嵌入式课程设计 —— STM32 定时器编程
程序员文章站
2024-02-25 14:48:15
...
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);
}
}