锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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

时间:2024-05-19 01:07:11

由于RCC->CFGR时钟配置寄存器中 APB1设置为2分频,所以 M3就是其倍频==72M

上次我发表的 M32单片机自带PWM输出实验大家可以参考学习: http://www.ruidan.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_N _Init(2,2,TIM3_ QChannel,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 #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; //外部高速时钟使能HSE while(!(RCC->CR>>17));//等待外部时钟就绪 RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;A=DIV1; PLL-=2;//抵消2个单位 RCC->CFGR|=PLL<<18; //设置PLL值 2~16 RCC->CFGR|=1<<16; //PLLSRC ON FL->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; } }


-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章