• STM32F103C8T6 có 2 bộ Watchdog Timer, 1 bộ SysTick Timer, 4 bộ Timer (Timer 1,Timer 2, Timer 3, Timer 4 ) mỗi 1 bộ là 1 bộ đếmtimer 16 bit. 1 bộ Timer 1 – Advancedcontrol timer thuộc khối clock APB2. 3 bộ Timer 2,3,4 – Generalpurpose timers thuộc khối clock APB1.
Trang 1Bài 3 Lập trình cơ bản trên ARM
3.3 Lập trình với Timer
3.4 Lập trình với bộ điều chế độ rộng xung PWM
#1
Trang 2 1 bộ Timer 1 – Advanced-control timer thuộc khối clock APB2.
3 bộ Timer 2,3,4 – General-purpose timers thuộc khối clock APB1.
Trang 4• Tạo xung, tạo xung PWM
• Tạo yêu cầu DMA
• Timer 2,3,4 - General-purpose timers (TIMx)
• 16-bit auto-reload up/down counter
• 16-bit prescaler
• 4 kênh độc lập: input capture/output compare
• Tạo xung, tạo xung PWM
• Tạo yêu cầu DMA
• Đọc ENCODER, đọc tín hiệu từ cảm biếnHALL
Trang 5Sơ đồ khối Timer 1 Hình 52 trang 294 Datasheet
3.3 Lập trình với Timer 3.3.2 Sơ đồ khối của Timer - TIM1
- Khối nguồn xung
- Khối đầu vào
- Khối PSC
- Khối bộ đếm
- Khối Capture/Compare
- Khối đầu ra
Trang 6Sơ đồ khối Timer 2,3,4 Hình 100 trang 367 Datasheet
3.3 Lập trình với Timer 3.3.2 Sơ đồ khối của Timer – TIM2, TIM3, TIM4
- Khối nguồn xung
- Khối đầu vào
- Khối PSC
- Khối bộ đếm
- Khối Capture/Compare
- Khối đầu ra
Trang 7Sơ đồ khối Timer 1,2,3,4 chế độ tạo xung
3.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
- Khối nguồn xung
- Khối PSC
- Khối bộ đếm
Nguồn xung
- Nguồn xung từ bên
ngoài : ETR hoặc TI1FP1,
TI2FP2.
- Nguồn xung từ bộ tạo
dao động của hệ thống
RCC - CK_INT
Trang 8Sơ đồ tạo xung từ bộ tạo dao động RCC
3.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(1) Tạo xung sử dụng nguồn xung từ bộ tạo dao động – CK_INT
Cần tác động 3 thanh ghi
- Counter register (TIMx_CNT).
- Prescaler register (TIMx_PSC)
- Auto-reload register (TIMx_ARR)
Trang 93.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(1) Tạo xung sử dụng nguồn xung từ bộ tạo dao động – CK_INT
Công thức tạo xung :
(Prescaler + 1)(Period + 1)
- Fout: tần số đầu ra (Hz)
- Fclk: tần số đầu vào của Timer (Hz)
- Prescaler: giá trị nạp vào bộ chia tần của Timer (0 ÷ 65535)
- Period: giá trị nạp vào bộ đếm của Timer (0 ÷ 65535)
Trang 103.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(1) Tạo xung sử dụng nguồn xung từ bộ tạo dao động – CK_INT
Ví dụ :Tạo xung Fout có tần số 1KHz, với Fclk=8MHz, Prescaler =0;
Trang 113.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(2) Các hàm sử dụng trong thư viện HAL
Trang 123.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer
Bước 3 Thiết lập các thông số cho Timer
- Lựa chọn tần số cho Timer
- Lựa chọn hệ số chia tần: Prescaler
- Nạp giá trị cho thanh ghi đếm: Period
- Khởi tạo Timer : HAL_TIM_Base_Start_IT( &htim1 );
Bước 4 Viết chương trình con phục vụ ngắt Timer
Trang 133.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer
Bước 4 Viết chương trình con phục vụ ngắt Timer
Trong file "stm32f1xx_it.c“ hoặc trong “main.c”
void TIM1_IRQHandler (void) // Ví dụ ngắt Timer 1
Trang 143.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
B1 Cấu hình nguồn xung của Timer
- Timer 1 – APB2
- Timer 2,3,4 – APB1
Trang 153.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
Trang 163.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
Trang 173.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
B2 Cấu hình Timer
- Lựa chọn nguồn xung từ bộ tạo dao động : Clock Source –> Internal Clock
Trang 183.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
B2 Cấu hình Timer
- Thiết lập Prescaler, Counter Mode, Period
Trang 193.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
B3 Thiết lập ngắt Timer
- Thiết lập TIM1 update interrupts ( với Timer 1)
- Thiết lập TIM x global interrupt( với Timer 2,3,4)
Trang 203.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
Lựa chọn chân chiều vào, chiều ra, mode Thiết lập các thông số trên STM32CubeMX như trong hướng dẫn lập trình với GPIO
Sau đó chọn GENERATE CODE để tạo file Code
Trang 213.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
(3) Các bước lập trình tạo xung với Timer trên STM CUBE
– Khung chương trình Timer 2
#include "main.h"
TIM_HandleTypeDef htim2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_11);
HAL_TIM_IRQHandler(&htim2);
}
Trang 22(4) Ví dụ
Ví dụ 1: Sử dụng Timer 1 tạo xung có tần số
Fout = 1KHz trên chân PA15
Bộ tạo dao động chế độ HSI với Fosc = 8MHz
3.3 Lập trình với Timer 3.3.3 Chế độ tạo xung thông thường
Trang 23Code ví dụ 1
#include "main.h"
TIM_HandleTypeDef htim1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
if (HAL_TIM_Base_Init(&htim1) != HAL_OK){Error_Handler();} sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig)
!= HAL_OK){ Error_Handler();}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
Trang 243.3 Lập trình với Timer
Bài tập:
Bài tập 1 Sử dụng ngắt Timer1, lập trình điều khiển LED sáng nhấp nháy với tần số 5Hz; sau
5 giây led nhấp nháy với tần số 1Hz
Bài tập 2 Sử dụng ngắt Timer2, lập trình điều khiển LED sáng nhấp nháy với tần số 4Hz, sau
4 giây led sáng với tần số 2Hz
Bài tập 3 Sử dụng ngắt Timer3, lập trình điều khiển LED sáng nhấp nháy với tần số 1Hz
(0,5s sáng; 0,5s tắt) khi nhấn DOWN led sáng nhấp nháy 5Hz; nhấn UP led sáng nhấp nháy 1Hz
Trang 25Sơ đồ khối Timer 1,2,3,4 chế độ tạo xung
3.3 Lập trình với Timer 3.3.4 Chế độ đếm
(1) Nguồn xung từ bên ngoài
ETR
TI1FP1, TI2FP2
Trang 26Timer External clock source mode 1
3.3 Lập trình với Timer 3.3.4 Chế độ đếm
(1)Nguồn xung từ bên ngoài
- External clock source mode 1
Khối lọc - lấy mẫu
Khối lựa chọn sườn xung
Khối lựa chọn đầu vào
Khối lựa chọn chế độ hoạt động
Trang 273.3 Lập trình với Timer 3.3.4 Chế độ đếm
(2) Các hàm sử dụng trong thư viện HAL
Hàm cho phép bộ timer hoạt động
Trang 283.3 Lập trình với Timer 3.3.4 Chế độ đếm
(3) Các bước lập trình trong chế độ đếm của Timer
Trang 293.3 Lập trình với Timer 3.3.4 Chế độ đếm
(3) Các bước lập trình trong chế độ đếm của Timer
Bước 3 Thiết lập các thông số cho Timer
- Lựa chọn tần số cho Timer
- Lựa chọn chế độ hoạt động : External clock source mode 1
- Lựa nguồn xung đầu vào : ETR; TI1FP1; TI2FP2.
- Lựa chọn sườn xung: Rising; Falling.
- Lựa chọn lọc – lấy mẫu: 0 ÷ 15
- Lựa chọn hệ số chia tần: Prescaler = 0;
- Lựa chọn chế độ đếm: Counter Mode = Up;
- Nạp giá trị đếm tràn thanh ghi đếm: Period
- Khởi tạo Timer : HAL_TIM_Base_Start( &htim1 );
- Đọc giá trị trong bộ đếm của Timer : dem = HAL_TIM_GetCounter(&htim1);
Trang 303.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
B1 Cấu hình nguồn xung của Timer
- Timer 1 – APB2
- Timer 2,3,4 – APB1
Trang 313.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
B2 Thiết lập các thông số cho Timer
- Lựa chọn Timer
- Thiết lập chế độ hoạt động
- Lựa chọn nguồn xung
Trang 323.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
Trang 333.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
B3 Cấu hình Timer
- Lựa chọn nguồn
xung đầu vào : ETR1
hoặc TI1FP1; TI2FP2
Trang 343.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
B3 Cấu hình Timer
- Cấu hình các thông số : Prescaler,
Counter mode, Counter Period,
Trigger Polarity, Trigger Filter.
Trang 353.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
B3 Cấu hình Timer
- Cấu hình các thông số : Prescaler,
Counter mode, Counter Period,
Trigger Polarity, Trigger Filter.
Trang 363.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
Lựa chọn chân chiều vào, chiều ra, mode Thiết lập các thông số trên STM32CubeMX như trong hướng dẫn lập trình với GPIO
Sau đó chọn GENERATE CODE để tạo file Code
Trang 373.3 Lập trình với Timer 3.3.4 Chế độ đếm
(4) Các bước lập trình đếm xung với Timer trên STM CUBE
– Khung chương trình Timer 1
Trang 38(5) Ví dụ
Ví dụ 1: Sử dụng Timer 1 chế độ đếm – TI1FP1 – PA8,
đọc số lần nhấn nút PB1 hiển thị trên 01 Led 7 thanh kết
nối như hình bên
3.3 Lập trình với Timer 3.3.4 Chế độ đếm
Trang 39Code ví dụ 1
#include "main.h"
TIM_HandleTypeDef htim1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
dem = HAL_TIM_GetCounter(&htim1); hienthi_7seg(ma_led[dem]);
} }
3.3 Lập trình với Timer
Trang 413.4 Lập trình với Bộ điều chế độ rộng xung
3.4.1 Giới thiệu
#41
• STM32F103C8T6 có 4 bộ Timer (Timer 1,Timer 2, Timer 3, Timer 4 ) mỗi
1 Timer có thể tạo ra 4 kênh PWM 16 bit.
1 bộ Timer 1 – Advanced-control timer thuộc khối clock APB2.
3 bộ Timer 2,3,4 – General-purpose timers thuộc khối clock APB1.
Trang 42Sơ đồ khối Timer 1 Hình 52 trang 294 Datasheet
3.4 Lập trình với Bộ điều chế độ rộng xung
3.4.2 Sơ đồ khối của Timer - TIM1
- Khối nguồn xung
- Khối đầu vào
Trang 43Sơ đồ khối Timer 2,3,4 Hình 100 trang 367 Datasheet
3.4 Lập trình với Bộ điều chế độ rộng xung 3.4.2 Sơ đồ khối của Timer – TIM2, TIM3, TIM4
- Khối nguồn xung
- Khối đầu vào
Trang 443.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
(1) PWM trong STM32 được tạo ra trong chế độ
Edge-aligned mode hoặc Center-aligned mode
trong đó :
- Thanh ghi TIMx_ARR :
thiết lập chu kì Tpwm ( Period ).
- Thanh ghi (TIMx_CCRx):
thiết lập độ rộng xung Ton ( Duty cycle - Pulse )
PWM mode 1
Up-counting, trên kênh TIMx_CHx được thiết lập TIMx_CNT<TIMx_CCR1.
Down-counting, T trên kênh TIMx_CHx được thiết lập TIMx_CNT>TIMx_CCR1; OC1REF = ’1’.
PWM mode 2
Up-counting, trên kênh TIMx_CHx không được thiết lập TIMx_CNT<TIMx_CCR1.
Down-counting, T trên kênh TIMx_CHx được thiết lập TIMx_CNT>TIMx_CCR1.
Trang 453.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
(2) Tạo xung PWM sử dụng nguồn xung từ bộ tạo dao động – CK_INT
Công thức tạo xung PWM :
(Prescaler + 1)(Period + 1)
- Fpwm: tần số PWM đầu ra (Hz)
- Fclk: tần số đầu vào của Timer (Hz)
- Prescaler: giá trị nạp bộ chia tần của Timer (0 ÷ 65535)
- Period: giá trị nạp bộ đếm của Timer (0 ÷ 65535)
Trang 463.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
(2) Tạo xung PWM sử dụng nguồn xung từ bộ tạo dao động – CK_INT
Công thức tạo độ rộng phần dương Ton :
D Period+1 *100%
- D: tỉ lệ xung dương so với chu kì
- Ton: Chu kì xung phần dương của xung PWM (Pulse)
- Period: giá trị nạp bộ đếm của Timer (0 ÷ 65535)
Trang 48- Thiết lập xung nhịp hệ thống : SystemClock_Config()
Bước 2 Thiết lập cho các GPIO
- Cho phép GPIO – AFIO tương ứng hoạt động bằng hàm:
HAL_RCC_GPIO x _CLK_ENABLE();
Bước 3 Thiết lập các thông số tạo xung PWM
- Lựa chọn tần số cho Timer
- Lựa chọn hệ số chia tần: Prescaler ;
- Lựa chọn chế độ đếm: Counter Mode = Up;
- Nạp giá trị cho thanh ghi đếm: Counter Period
- Nạp giá trị thiết lập độ rộng xung Ton: Pulse
- Khởi tạo kênh PWM: HAL_TIM_PWM_Start( &htim1,TIM_CHANNEL_1 );
- Thiết lập lại độ rộng xung Ton: HAL_TIM_SetCompare( &htim1,TIM_CHANNEL_1,DutyCycle );
Trang 493.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
(5) Các bước lập trình tạo xung PWM trên STM CUBE
B1 Cấu hình nguồn xung của Timer
- Timer 1 – APB2
- Timer 2,3,4 – APB1
Trang 51- Lựa chọn kênh đầu ra PWM
- Thiết lập Prescaler, Counter
Mode, Period, Pulse
Trang 553.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
(5) Các bước lập trình tạo xung PWM trên STM CUBE
Lựa chọn chân chiều vào, chiều ra, mode Thiết lập các thông số trên STM32CubeMX như trong hướng dẫn lập trình với GPIO
Sau đó chọn GENERATE CODE để tạo file Code
Trang 563.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
(5) Các bước lập trình tạo xung PWM trên STM CUBE
– Khung chương trình Timer 1 – PWM CH1
#include "main.h"
TIM_HandleTypeDef htim1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
htim1.Init.Period = 99;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
//**************************************// sConfigOC.Pulse = 0;
Trang 57(6) Ví dụ
Ví dụ 1: Sử dụng Timer 1 tạo xung PWM có tần số
Fpwm = 1KHz trên kênh 1 – PA8
với Ton= 20%Tpwm
Bộ tạo dao động chế độ HSI với Fosc = 8MHz
3.4 Lập trình với Bộ điều chế độ rộng xung
3.4.3 Tạo xung PWM
Trang 58#58(6) Ví dụ
Trang 59static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
htim1.Init.Period = 999;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
//**************************************// sConfigOC.Pulse = 200;
Trang 603.4 Lập trình với Bộ điều chế độ rộng xung
Sử dụng Timer 1, lập trình tạo đồng thời 4 xung PWM có tần số 1KHz, với độ rộng
Ton 10%, 30%, 70%, 90% lần lượt trên các kênh CH1, CH2, CH3, CH4