1. 程式人生 > >嵌入式課程設計 —— STM32 定時器程式設計

嵌入式課程設計 —— STM32 定時器程式設計

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);
  }
}