目錄
一、Cube配置基本定時器
1.定時器CubeMX配置介紹
2.定時器中斷控制LED
3.定時器常用函數
4.定時器從模式(Reset Mode)
5.定時器的從模式(Gated Mode)
6.定時器的編碼器接口
一、Cube配置基本定時器
1.定時器CubeMX配置介紹
定時器屬性配置:
2.定時器中斷控制LED
1、CubeMX配置(配置定時器頻率為1Hz)
開啟中斷:
繼續選擇PA9為LED工作引腳(推挽輸出):
代碼實現:
HAL_TIM_Base_Start_IT(&htim2);//開始定時器中斷//中斷回調函數
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9);}
3.定時器常用函數
HAL_TIM_Base_Stop_IT(&htim2);//關閉定時器中斷
HAL_TIM_Base_Start_IT(&htim2);//開始定時器中斷//中斷回調函數
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{}
4.定時器從模式(Reset Mode)
作用:
它的作用是TIF接收到信號時(上升沿或下降沿),會清空計數器。并且觸發一次 觸發器中斷(由觸發器中斷標 志位控制) 。(重裝載是的中斷是 更新中斷 )
CubeMX設置定時器相關參數:
1. 設置從模式為Reset模式
2. 使用的觸發源是TI1FP1,但選擇這個后右邊芯片圖中的PA6引腳會自動創建標簽
3. 使用內部時鐘
4. 設置PSC為36000-1,自動重裝寄存器為2000-1.計數器從0增加到2000,溢出周期為1秒。
5. 設置從模式的Reset模式用上升沿
6. 濾波值設置15
7、打開中斷
下面我們用這個配置實現一個功能:
假如不按下按鍵,CNT從0自增到2000,后count只加1,并且從0計數。
但按鍵按下,CNT清零然后從零重新開始計數
main.c文件中重寫中斷函數:
uint32_t hhRetCount=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==&htim3){if(__HAL_TIM_GET_FLAG(htim,TIM_FLAG_TRIGGER)==SET){//從模式Reset的中斷__HAL_TIM_CLEAR_FLAG(htim,TIM_FLAG_TRIGGER);//需手動清空標志位}else{//自動重裝的中斷hhRetCount+=1;}}
}
main函數:
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C2_Init();MX_TIM3_Init();/* USER CODE BEGIN 2 */OLED_Init();//OLED初始化OLED_CLS();HAL_TIM_Base_Start_IT(&htim3);OLED_ShowStr(0,0,"CNT:",2); //顯示字符串OLED_ShowStr(0,5,"Conut:",2); //顯示字符串/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */uint32_t man = __HAL_TIM_GET_COUNTER(&htim3);//OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2);//size2(16|12)OLED_ShowNum(40, 0, hhRetCount,5,16);OLED_ShowNum(50, 5, man,4,16);}}
效果:
5.定時器的從模式(Gated Mode)
作用:
它的作用是TIF接收到信號時(高電平或低電平),會暫停計數器計數。會設置觸發器中斷標志位,但是不會觸發觸發器中斷。
CubeMX設置定時器相關參數:
其他的和上面一樣,代碼實現也一樣!
現象:按下按鍵時,TIF會輸入高電平。Gated模式檢查到后會開始計數器計數。不按下時則會停止計數。(定時器在高電平模式下會正常計數,低電平觸發后就會停止計數)
6.定時器的編碼器接口
簡單原理闡述:
Encoder Interface 編碼器接口 編碼器接口可接收增量(正交)編碼器的信號,根據編碼器旋轉產生的正交信號脈沖,自動控制CNT自增或自減,從而指示編碼器的位置、旋轉方向和旋轉速度
編碼器工作模式:
簡單可以分為三個模式:
要理解這些,我們先要知道怎么分辨編碼器是正轉和反轉:
分辨完反向后,我們就可以根據A和B相來進行算數計次了,TI1模式就為遇到A相上下沿CNT自增,同理TI2模式就為遇到B相上下沿CNT自增,TI1和TI2模式就為遇到A相和B相上下沿CNT自增,無非就是精度問題而已,根據自己需求設定工作模式!
下面我們做兩個小實驗:①編碼器當做時鐘源 ②計數編碼器速度
編碼器硬件接線:
CubeMX配置:
1. 打開編碼器模式
2. 設置定時器的相關參數由于是檢測速度,所以這里就不分頻,盡可能讓定時器快點。計數器設置 最大,防止輸入信號頻率太高溢出。
3. 設置計數模式,TI1計數和TI2計數
4. 設置信號不反轉
代碼實現:
main函數(這里我使用的OLED驅動,沒有顯示負數的函數,所以翻反轉沒辦法顯示負數出來):
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init */int16_t time = 100;int man =100;/* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C2_Init();MX_TIM3_Init();/* USER CODE BEGIN 2 */OLED_Init();//OLED初始化OLED_CLS();HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);//打開定時器編碼器模式OLED_ShowStr(0,0,"CNT:",2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */time = __HAL_TIM_GET_COUNTER(&htim3);//獲取當前CNTOLED_ShowNum(70, 0, time, 5, 16);HAL_Delay(100);OLED_ShowNum(70, 5, man, 5, 16);}/* USER CODE END 3 */
}
計數編碼器速度并顯示:
原理就是1秒鐘讀取一次定時器的計數值(編碼器的脈沖)并清空。得到的數字就是當前的速度,單 位是Plus/S
代碼實現:
int16_t hhGetEncoderSpeedCountAndReset(){int16_t Tmp;Tmp=__HAL_TIM_GET_COUNTER(&htim3);//獲取當前CNT__HAL_TIM_SET_COUNTER(&htim3,0);//清空CNTreturn Tmp;
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM3_Init();HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);//打開定時器編碼器模式OLED_Init();OLED_Clear();OLED_ShowString(2, 1, "CNT:");while (1){OLED_ShowSignedNum(2,5,hhGetEncoderSpeedCountAndReset(),5);HAL_Delay(1000);}
}