Skip to content

16 LED Nhấp Nháy Bằng Timer

Quy trình cấu hình

Khi sử dụng chức năng Timer (bộ định thời), ta thường thực hiện các bước sau:

  • Bật clock cho Timer
  • Cấu hình thông số của Timer
  • Cấu hình mức ưu tiên ngắt
  • Kích hoạt sự kiện ngắt và Timer
  • Viết hàm xử lý ngắt (ISR)

STM32F407VET6 có tổng cộng 14 bộ Timer, mỗi loại có chức năng riêng. Trong bài này, ta sẽ dùng Timer để tạo LED nhấp nháy mỗi 1 giây. Bài thực hành dùng Timer3 để ví dụ.

Bật clock cho Timer

Theo sơ đồ trong datasheet trang 19:

img

Có thể thấy 14 Timer chia làm 2 nhóm:

  • Nhóm sử dụng bus APB1 (tốc độ tối đa 42MHz)
  • Nhóm sử dụng bus APB2 (tối đa 84MHz)

Timer3 thuộc APB1. Do đặc điểm nhân Cortex-M4, nếu APB1 được chia 4 (168 / 4 = 42MHz), thì Timer clock được nhân đôi → 84MHz:

img

Câu lệnh bật clock cho TIM3:

c
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

Cấu hình thông số Timer

Sau khi bật clock, ta cần thiết lập thời gian định kỳ và chế độ hoạt động.

img

Định nghĩa và cấu hình Timer:

c
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 10000;
TIM_TimeBaseStructure.TIM_Prescaler = 8400 - 1;  // Clock: 84MHz

Giải thích:

  • TIM_Prescaler: chia tần số xuống 10kHz
  • TIM_Period = 10000: 10kHz → đếm 10000 lần → mỗi 1 giây sẽ tràn

Cấu hình ngắt (Interrupt)

Định nghĩa cấu trúc ngắt:

c
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;

Ý nghĩa:

  • TIM3_IRQn: kênh ngắt của Timer3
  • PreemptionPriority: mức ưu tiên chính (0 = cao nhất)
  • SubPriority: thứ tự trong cùng nhóm

Kích hoạt Timer và ngắt

c
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);   // Khởi tạo timer
NVIC_Init(&NVIC_InitStructure);                   // Khởi tạo ngắt
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);        // Bật ngắt tràn
TIM_Cmd(TIM3, ENABLE);                            // Bật timer

Viết hàm xử lý ngắt

Tên hàm ISR được quy định trong startup_stm32f407_427.s:

c
void TIM3_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
    {
        printf("IRQHandler!!!\r\n");

        if (flag == 0)
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_2);
            flag = 1;
        }
        else
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_2);
            flag = 0;
        }
    }

    TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // Xóa cờ ngắt
}

Kết quả thực nghiệm

File mẫu:
立创·梁山派·天空星STM32F407VET6开发板资料/第03章软件资料/代码例程/008 定时器灯闪烁

Sau khi nạp chương trình:

  • LED sẽ nhấp nháy mỗi 1 giây
  • Terminal sẽ in: IRQHandler!!! mỗi lần tràn

img