欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

嵌入式课程设计 —— STM32 定时器编程

程序员文章站 2024-02-25 14:48:15
...

1.定时器基本功能:定时和计数

2.基本原理:对脉冲信号进行计数

嵌入式课程设计 —— STM32 定时器编程

3.定时器的编程思路:

1)配置定时器计数脉冲信号的频率;

2)设置定时器的工作方式:向上/向下计数,是否允许中断

3)设置定时器的定时时间

4)如果用到中断,需要编写定时器中断服务处理程序

5)启动定时器

4.以Timer3为例来实现一个 10ms 的定时中断

查看定时器3的中断时钟:定时器3挂在 APB1 总线上(APB1 总线时钟频率-42MHz)

定时器的工作时钟 42 * 2  = 84 MHz

计数时钟频率 = 定时器3 的工作时钟 /(PSC+1)

计数时钟频率 1MHz  => PSC = 83

 嵌入式课程设计 —— STM32 定时器编程

主要代码

/*定时器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;
}


嵌入式课程设计 —— STM32 定时器编程

====================================================================================================

嵌入式课程设计 —— STM32 定时器编程

使用定时器产生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);
  }
}


相关标签: 嵌入式