為了使程式在使用上更有效率,大部分類似的功能都是使用Timer來實現。
以下是Timer的設定步驟
選擇完晶片後,首先是設定外部震盪,如果要使用內部震盪可直接略過
選擇外部震盪 |
再來是選擇Clock source
選擇internal clock |
再來跳到Clock configuration,設定頻率,這邊我是使用外部震盪,石英晶體的頻率為8M,最後APB1與APB2的頻率為24M。
Clock configuration |
接下來是要設定Timer的中斷間隔,我使用的是Timer1來做示範,可以查看資料手冊中,Timer的Clock source 是APB2
接下來要計算Timer的中斷時間,以0.5s為範例,我時脈是24M,Prescaler應該要設定
24M/(2-1),但是Prescaler數值範圍只有16bit也就是0~65535所以我們要用一些變通的方法來做,Prescaler設定23999,也就是24K-1,然後把Period設定成500,也就是說計數器每秒可以計數1000次,在計數到第500次的時候發生中斷,執行中斷的內容。
Prescaler與Period的設定值 |
HAL_TIM_Base_Start_IT(&htim1);
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_TIM1_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
在TIM1_UP_TIM16_IRQHandler中加入IO狀態切換的副程式
void TIM1_UP_TIM16_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);
/* USER CODE END TIM1_UP_TIM16_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */
/* USER CODE END TIM1_UP_TIM16_IRQn 1 */
}