专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

STM32单片机简易定时器PWM输出

作者:佚名   来源:本站原创   点击数:  更新时间:2013年10月22日   【字体:
由于RCC->CFGR时钟配置寄存器中  APB1设置为2分频,所以TIM3就是其倍频==72M

上次我发表的STM32单片机自带PWM输出实验大家可以参考学习: http://www.51hei.com/mcu/2123.html ,这次是用定时器产生的pwm.
 
//----------------------------------定时器-----------time.c-----------
#include "time.h"

 
void time_init(u16 arr,u16 psc)
{
 RCC->APB1ENR|=1<<1; //TIM2定时器时钟使能
 TIM3->ARR=arr;        //设置重装载值
 TIM3->PSC=psc;       //设置分配系数
 TIM3->DIER|=1<<0; //允许更新
 TIM3->DIER|=1<<6;      //触发中断使能
 TIM3->CR1|=1<<0;       //使能定时器2
 MY_NVIC_Init(2,2,TIM3_IRQChannel,2);  //设置定时器2中断类别
 
}

//----------------time.h--------------
#ifndef _time_h
#define _time_h
#include "sys.h"
 
void time_init(u16 arr,u16 psc);
#endif
//----------------------按键-----key.c------------
#include "key.h"

 
void key_init(void)
{
 RCC->APB2ENR|=1<<2;    //PORTA时钟使能
 GPIOA->CRH&=0x0f0fffff;
 GPIOA->CRH|=0x80800000;  //设置为输入
 GPIOA->ODR|=1<<15;
 GPIOA->ODR|=1<<13;

 
}

 
//-------------------key.h----------------
#ifndef _key_h
#define _key_h
#include "sys.h"
#define key1 PAin(13)
#define key2 PAin(15)
void key_init(void);

 
#endif
//-------------------LED---------led.c-------------
#include "led.h"
void led_init(void)
{
 RCC->APB2ENR|=1<<2;
 RCC->APB2ENR|=1<<5;   //使能PORTD时钟
 GPIOA->CRH&=0xfffffff0;
 GPIOA->CRH|=0x00000003;  //PA8推挽输出
 GPIOD->CRL&=0xfffff0ff;
 GPIOD->CRL|=0x00000300;  //PD2推挽输出
 GPIOA->ODR|=1<<8;
 GPIOD->ODR|=1<<2;

 
}
//------------------led.h---------------------
 #ifndef _led_h
 
#define _led_h
#include "sys.h"

 
#define LED0 PAout(8)
#define LED1 PDout(2)

 
void led_init(void);

 
#endif

//------------------------主函数-----------test.c-----------
#include <stm32f10x_lib.h>
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "time.h"            

 
char pwm;       //pwm增减量
char cnt;         //pwm时间变量

 
//-----------------------pwm增量按键----------------
void key1_scan()
{
  static u8 i,j;
 if(key1==0)
 {
if(i==0)
{
j++;
if(j>3)
{
i=1;j=0;
pwm+=5;
if(pwm>100)pwm=0;
}
   }
 }
 else
  {
i=j=0;
  }
}

 
//--------------------pwm减量按键--------------------
void key2_scan()
{
  static u8 i,j;
 if(key2==0)
 {
if(i==0)
{
j++;
if(j>3)
{
i=1;j=0;
pwm-=5;
if(pwm<10)pwm=0;
}
   }
 }
 else
  {
i=j=0;
  }
}

 
void TIM3_IRQHandler(void) //定时器2中断函数
{
   if(TIM3->SR&0x0001)
   {
cnt++;
if(cnt>100)cnt=0;
if(cnt>pwm)                   //LED0作为pwm 输出指示
{
 LED0=0;
}
else
{
 LED0=1;
}
   }
   TIM3->SR&=~(1<<0);         //清除中断标志位
}

 

 
int main(void)
{
 u16 i,t;
 Stm32_Clock_Init(9);
 delay_init(72);
 uart_init(72,9600);
 led_init();
 key_init();
 time_init(3600,1);                        //产生10K频率      pwm只是~~100HZ  由于100分频
 while(1)
 {
  key1_scan();
  key2_scan();
  t++;
  if(t>60000)
  {
    i++;
if(i>11)
{
LED1=!LED1;       //系统运行指示约1秒闪烁一次
i=0;
    }
t=0;
  }

 
  }
 }

//--------------------------------关于定时器溢出时间计算--------------------------
1)TIM3时钟使能。
这里我们通过APB1ENR的第1位来设置TIM3的时钟,因为Stm32_Clock_Init函数里面把APB1的分频设置为2了,所以我们的TIM3时钟就是APB1时钟的2被,等于系统时钟。(72M)

Tout= (arr*(psc+1))/Tclk;
其中:
Tclk:TIM3的输入时钟频率(单位为Khz)。
Tout:TIM3溢出时间(单位为ms)。

Tout=(3600*(1+1))/72M=0.1ms

//------------------------------系统时钟初始化函数对于定时器TIM3 时钟简易分析-----------------
void Stm32_Clock_Init(u8 PLL)
{
unsigned char temp=0;   
MYRCC_DeInit();  //复位并配置向量表
RCC->CR|=0x00010000;  //外部高速时钟使能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪
RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
PLL-=2;//抵消2个单位
RCC->CFGR|=PLL<<18;   //设置PLL值 2~16
RCC->CFGR|=1<<16;  //PLLSRC ON 
FLASH->ACR|=0x32;  //FLASH 2个延时周期

 
RCC->CR|=0x01000000;  //PLLON
while(!(RCC->CR>>25));//等待PLL锁定
RCC->CFGR|=0x00000002;//PLL作为系统时钟  
while(temp!=0x02)     //等待PLL作为系统时钟设置成功
{   
temp=RCC->CFGR>>2;
temp&=0x03;
}    
}    


 
关闭窗口

相关文章