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信號的代碼
使用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);
}
}