资讯详情

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

由于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 <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; //外部高速时钟使能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百科大全!

锐单商城 - 一站式电子元器件采购平台