Lập trình và Ứng dụng Timer trên STM32

Bộ định thời TIM (Phần một)

  • Bộ định thời (Timer) có thể đếm xung clock và tạo ngắt khi đạt giá trị đặt trước
  • Đơn vị cơ bản gồm bộ đếm 16-bit, bộ chia tần số và thanh ghi tự động nạp lại, cho phép định thời tối đa 59.65s với clock 72MHz
  • Cung cấp đa dạng chức năng: chọn nguồn clock, bắt giữ vào/ra, giao diện encoder, chế độ master-slave
  • Phân loại: Bộ định thời cao cấp, phổ thông và cơ bản

Loại bộ định thời trên STM32F103C8T6

Bao gồm TIM1, TIM2, TIM3, TIM4 với đặc tính khác nhau

Cấu trúc hệ thống

Bộ định thời cơ bản

Sử dụng clock nội 72MHz, bộ chia tần số có thể chia tối đa 65536. Khi bộ đếm đạt giá trị trong thanh ghi tự động nạp, tín hiệu ngắt được phát và bộ đếm được đặt lại.

Bộ định thời phổ thông

Cấu hình TIM3 ở chế độ master để kích hoạt TIM2 thông qua ngõ ra TRGO. TIM2 được thiết lập ở chế độ clock ngoài để tạo hệ thống định thời nối tiếp.

Bộ định thời cao cấp

Thêm thanh ghi đếm lặp để mở rộng thời gian định thời lên gấp 65536 lần. Hỗ trợ 2 ngõ ra PWM bổ trợ với mạch tạo khoảng chết (dead time) để điều khiển động cơ không chổi than.

Nguyên lý ngắt định thời

Công thức tính tần số bộ đếm: CK_CNT = CK_PSC / (PSC + 1)
Tần số tràn bộ đếm: CK_CNT_OV = CK_CNT / (ARR + 1)

Cây tín hiệu clock (RCC)

Hệ thống phân phối tín hiệu clock đến các ngoại vi, là nền tảng cho mọi hoạt động phần cứng

Bộ so sánh đầu ra (Phần hai)

  • Chức năng điều chế độ rộng xung (PWM) thông qua so sánh giá trị CNT và CCR
  • Thông số PWM: Tần số = 1 / TS, Độ rộng = TON/TS, Độ phân giải = bước thay đổi độ rộng
  • Mỗi kênh có khả năng tạo tín hiệu bổ trợ với mạch tạo khoảng chết (DTG) trên bộ định thời cao cấp

Ứng dụng thực tế

  • Servo motor: Tín hiệu 20ms với xung cao 0.5-2.5ms điều khiển góc quay
  • Động cơ DC: Cần mạch cầu H (TB6612) để điều khiển chiều quay và tốc độ

Bộ bắt giữ đầu vào (Phần ba)

  • Ghi nhận giá trị bộ đếm khi phát hiện cạnh chuyển đổi trên ngõ vào
  • Hỗ trợ đo tần số/độ rộng xung thông qua chế độ PWMI
  • Chế độ master-slave cho phép tự động kích hoạt phần cứng

Nguyên lý đo tần số

Phương pháp đo tần số phù hợp tín hiệu cao, đo chu kỳ phù hợp tín hiệu thấp

Giao diện encoder (Phần tư)

  • Xử lý tín hiệu encoder vuông pha để xác định vị trí, hướng và tốc độ
  • Chế độ đếm tăng/giảm tự động dựa trên trạng thái tín hiệu A/B
  • Kháng nhiễu thông qua phát hiện tín hiệu bất thường trên kênh đối nghịch

Ví dụ ứng dụng

Khi encoder quay phải: CNT tăng dần theo số xung, quay trái: CNT giảm tương ứng

Mã nguồn minh họa

Cấu hình ngắt định thời


void Timer_Init(void) {
    // Kích hoạt clock TIM2 và GPIO
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    // Cấu hình clock nội
    TIM_InternalClockConfig(TIM2);
    
    // Thiết lập tham số định thời
    TIM_TimeBaseInitTypeDef timConfig;
    timConfig.TIM_Prescaler = 7199;
    timConfig.TIM_Period = 9999;
    timConfig.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &timConfig);
    
    // Xóa cờ ngắt và kích hoạt ngắt
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    
    // Cấu hình NVIC
    NVIC_InitTypeDef nvicConfig;
    nvicConfig.NVIC_IRQChannel = TIM2_IRQn;
    nvicConfig.NVIC_IRQChannelPreemptionPriority = 2;
    nvicConfig.NVIC_IRQChannelSubPriority = 1;
    nvicConfig.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicConfig);
    
    // Kích hoạt bộ định thời
    TIM_Cmd(TIM2, ENABLE);
}

// Hàm xử lý ngắt
void TIM2_IRQHandler(void) {
    if (TIM_GetITStatus(TIM2, TIM_IT_Update)) {
        counter++;
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

Cấu hình PWM


void PWM_Init(void) {
    // Kích hoạt clock
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // Cấu hình chân PWM
    GPIO_InitTypeDef gpioConfig;
    gpioConfig.GPIO_Pin = GPIO_Pin_0;
    gpioConfig.GPIO_Mode = GPIO_Mode_AF_PP;
    gpioConfig.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpioConfig);
    
    // Thiết lập tham số PWM
    TIM_TimeBaseInitTypeDef timConfig;
    timConfig.TIM_Prescaler = 719;
    timConfig.TIM_Period = 99;
    timConfig.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &timConfig);
    
    // Cấu hình kênh so sánh
    TIM_OCInitTypeDef ocConfig;
    ocConfig.TIM_OCMode = TIM_OCMode_PWM1;
    ocConfig.TIM_OutputState = TIM_OutputState_Enable;
    ocConfig.TIM_Pulse = 90;
    ocConfig.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM2, &ocConfig);
    
    // Kích hoạt PWM
    TIM_Cmd(TIM2, ENABLE);
}

void PWM_SetDuty(uint16_t value) {
    TIM_SetCompare1(TIM2, value);
}

Thẻ: STM32 Bộ định thời PWM Bắt giữ đầu vào Giao diện mã hóa

Đăng vào ngày 2 tháng 6 lúc 21:44