嵌入式課程設計 —— STM32 定時器程式設計
阿新 • • 發佈:2019-01-25
1.定時器基本功能:定時和計數
2.基本原理:對脈衝訊號進行計數
3.定時器的程式設計思路:
1)配置定時器計數脈衝訊號的頻率;
2)設定定時器的工作方式:向上/向下計數,是否允許中斷
3)設定定時器的定時時間
4)如果用到中斷,需要編寫定時器中斷服務處理程式
5)啟動定時器
4.以Timer3為例來實現一個 10ms 的定時中斷
檢視定時器3的中斷時鐘:定時器3掛在 APB1 總線上(APB1 匯流排時鐘頻率-42MHz)
定時器的工作時鐘 42 * 2 = 84 MHz
計數時鐘頻率 = 定時器3 的工作時鐘 /(PSC+1)
計數時鐘頻率 1MHz => PSC = 83
主要程式碼
/*定時器3驅動*/ #include"sys.h" #include<stdio.h> /* 初始化定時器3 計數脈衝頻率 1MHz, 定時時間設為 10ms 允許定時器中斷,採用向上計數方式 */ void InitTimer3(void) { //開啟定時器3的工作時鐘 RCC->APB1ENR |= (0x1<<1); //設定計數脈衝訊號頻率是 1MHz 1µs TIM3->PSC = 83; //定時時間設 10ms 10000-1 TIM3->ARR = 10000-1; //允許定時器更新 TIM3->DIER |= (0x1<<0); //允許定時器3向量中斷 MY_NVIC_Init(1,3,TIM3_IRQn,2); //啟動定時器 TIM3->CR1 |= (0x1<<0); } //編寫定時器3中斷服務處理程式 int timer3_count = 0; void TIM3_IRQHandler(void) { if(TIM3->SR & 0x1) { //產生定時器更新中斷 timer3_count ++; if((timer3_count % 100 ) == 0 ){ printf("Timer3 interrupt\r\n"); } TIM3->SR &= (~0x1);//清除中斷標誌位 } }
/*main.c*/ #include"sys.h" #include"usart.h" #include"delay.h" #include<stdio.h> //宣告中斷相關函式 void InitTimer3(void); void TIM3_IRQHandler(void); int main(void) { Stm32_Clock_Init(336,8,2,7);//初始化時鐘 uart_init(84,115200);//初始化除錯串列埠 delay_init(168);//初始化系統定時器 InitTimer3(); while(1) { TIM3_IRQHandler(); } return 0; }
====================================================================================================
使用定時器產生PWM訊號的程式設計思路:
目標:通過程式設計在一個引腳上輸出pwm訊號,從而去控制相應的執行機構
定時器產生PWM訊號的原理:
0)開啟定時器14、GPIOF的時鐘訊號
1)設定PWM訊號的週期(設定定時時間)
2)設定PWM訊號的脈衝寬度,通過CCR比較暫存器來進行設定(CCR比較暫存器)
3)設定PWM訊號的輸出引腳
4)設定定時器計數時鐘頻率
5)設定PWM模式,計數方式
6)啟動計數器
編寫(定時器14)
使用PWM訊號來控制LED燈
PF9 ——> TIM14_CH1(PF9作為定時器14的第一個輸出通道)
主要程式碼:
/*
初始化定時器14產生PWM訊號
PWM訊號的週期 1ms
*/
void InitPwmTimer14(void)
{
//開啟定時器14的時鐘訊號
RCC->APB1ENR |= (0x1<<8);
//開啟PF埠的時鐘訊號
RCC->AHB1ENR |= (0x1<<5);
//配置PF9為TIM14的輸出引腳
GPIO_Set(GPIOF,PIN9,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);
GPIO_AF_Set(GPIOF,9,9);//配置GPIO第9個引腳為可選功能模式9
//設定定時器計數時鐘頻率 1MHz
TIM14->PSC = 83;
//設定PWM訊號的週期 1ms = 1000μs
TIM14->ARR = 1000 - 1;
//設定比較模式為 PWM模式1
TIM14->CCMR1 &= (~(0x7<<4));//456位清零
TIM14->CCMR1 |= (0x6<<4);
//設定PWM訊號 低電平有效,同時開啟PWM訊號輸出
TIM14->CCER |= 0x3<<0;//第一位置1
TIM14->CCR1 = 0;
//啟動定時器14
TIM14->CR1 |= 0x1;
}
//設定PWM訊號的脈衝寬度
void SetPwmWidth(int w)
{
TIM14->CCR1 = w;
}
/*main.c*/
#include"sys.h"
#include"usart.h"
#include"delay.h"
#include<stdio.h>
//宣告
void InitPwmTimer14(void);
void SetPwmWidth(int w);
int dir = 1 ;
int pwmwidth = 0;
main()
{
Stm32_Clock_Init(336,8,2,7);
uart_init(84,115200);
delay_init(168);
InitPwmTimer14();
while(1){
delay_ms(10);
if(dir){
pwmwidth += 10;
if(pwmwidth >= 990)
dir = 0;
}else{
pwmwidth -= 10;
if(pwmwidth <=0 )
dir = 1;
}
SetPwmWidth(pwmwidth);
}
}