stm32 PWM实验
STM32 TIM的PMW模式

STM32 TIM的PMW模式STM32开发板学习日记-[5]TIM的PMW模式脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。
在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。
必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位使能自动重装载的预装载寄存器(在向上计数或中心对称模式中)。
因为仅当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。
OCx的极性可以通过软件在TIMx_CCER寄存器中的CCxP 位设置,它可以设置为高电平有效活或低电平有效。
TIMx_CCER寄存器中的CCxE位控制OCx输出使能。
在PWM模式(模式1或模式2)下,TIMx_CNT和TIM1_CCRx 始终在进行比较,(依据计数器的计数方向)以确定是否符合TIM1_CCRx≤TIM1_CNT或者TIM1_CNT≤TIM1_CCRx。
然而为了与OCREF_CLR的功能(在下一个PWM周期之前,ETR信号上的一个外部事件能够清除OCxREF)一致,OCxREF信号只能在下述条件下产生:●当比较的结果改变●当输出比较模式(TIMx_CCMRx寄存器中的OCxM位)从“冻结”(无比较,OCxM=’000’)切换到某个PWM模式(OCxM=’110’或’111’)。
关于STM32在程序中间修改PWM值的总结(原创)

关于 STM32在程序中间修改 PWM值的总结(原创)
首先在STM32库函数里有这样一个函数 void TIM3_PWM_Init(u16 arr,u16 psc)
若TIM3_PWM_Init(7200,100)//设置频谱7200.分频100
若想要在程序进程中修改频率需要函数TIM_SetAutoreload(TIM3,arr); 这个函数就是手动更改 TIMx->ARR 的意思 使能预装载ARPE 可以保证ARR在 更新事件到来时(或者你说的周期结束) 被 送到影子寄存器 如果不使能ARPE, 写入的ARR值立即生效;
所以最终在程序进程中修改我们的pwm需要通过 TIM_SetCompare2(TIM3,pwmval); TIM_SetAutoreload(TIM3,arr); 两个函数实现。
我们初始化定时器得到得频率为PWM频率=72000000/7200=10000hz 10000/100=100hz; TIM_SetCompare2(TIM3,pwmval);函数调节占空比; 占空比为arr/pwmval;
占空比在3,pwmval);
STM32_PWM占空比和频率可调

#include "stm32f10x_lib.h"void RCC_cfg();void GPIO_cfg();void TIMER_cfg();void PWM_cfg();//占空比,取值范围为0-100int dutyfactor = 50;int main(){int Temp;RCC_cfg();GPIO_cfg();TIMER_cfg();PWM_cfg();//使能TIM3计时器,开始输出PWMTIM_Cmd(TIM3, ENABLE);while(1);}void RCC_cfg(){//定义错误状态变量ErrorStatus HSEStartUpStatus;//将RCC寄存器重新设置为默认值RCC_DeInit();//打开外部高速时钟晶振RCC_HSEConfig(RCC_HSE_ON);//等待外部高速时钟晶振工作HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){//设置AHB时钟(HCLK)为系统时钟RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置高速AHB时钟(APB2)为HCLK时钟RCC_PCLK2Config(RCC_HCLK_Div1);//设置低速AHB时钟(APB1)为HCLK的2分频RCC_PCLK1Config(RCC_HCLK_Div2);//设置FLASH代码延时FLASH_SetLatency(FLASH_Latency_2);//使能预取指缓存FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//设置PLL时钟,为HSE的9倍频8MHz * 9 = 72MHzRCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);//使能PLLRCC_PLLCmd(ENABLE);//等待PLL准备就绪while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//设置PLL为系统时钟源RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//判断PLL是否是系统时钟while(RCC_GetSYSCLKSource() != 0x08);}//开启TIM3的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启GPIOB的时钟和复用功能RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO,ENABLE);}void GPIO_cfg(){GPIO_InitTypeDef GPIO_InitStructure;//部分映射,将TIM3_CH2映射到PB5// GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//选择引脚5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//输出频率最大50MHzGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//复用推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB,&GPIO_InitStructure);}void TIMER_cfg(){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//重新将Timer设置为缺省值TIM_DeInit(TIM3);//采用内部时钟给TIM3提供时钟源TIM_InternalClockConfig(TIM3);//预分频系数为0,即不进行预分频,此时TIMER的频率为72MHzTIM_TimeBaseStructure.TIM_Prescaler = 0;//设置时钟分割TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置计数器模式为向上计数模式TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置计数溢出大小,每计7200个数就产生一个更新事件,即PWM的输出频率为10kHzTIM_TimeBaseStructure.TIM_Period = 7200 - 1;//将配置应用到TIM3中TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);}void PWM_cfg(){TIM_OCInitTypeDef TimOCInitStructure;//设置缺省值TIM_OCStructInit(&TimOCInitStructure);//PWM模式1输出TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100% TimOCInitStructure.TIM_Pulse = dutyfactor * 7200 / 100;//TIM输出比较极性高TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//使能输出状态TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//TIM3的CH2输出TIM_OC2Init(TIM3, &TimOCInitStructure);//设置TIM3的PWM输出为使能TIM_CtrlPWMOutputs(TIM3,ENABLE);}。
STM32产生PWM精讲

TIM_OCInitStructure.TIM_Pulse=CCR1_Val;//设置了待装入捕获比较器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置输出极性
{
Cnt[i]= 0;
T[i] = 0;
R[i] = 0;
Rh[i] = 0;
Rl[i] = 0;
F[i] = 0;
}
//t的范围为(0~65536)
T[0] = 450;//F=40K
T[1] = 600;//F=30K
T[2] = 900;//F=20K
T[3] = 1800; //F=10K
//F(占空比)的范围为(0~100)
unsigned int Rl[4];//模拟的PWM低电平比较寄存器
unsigned char F[4];//占空比数组
unsigned int CCR1,CCR2,CCR3,CCR4;
void Init(void)
{
unsigned char i = 0;
for(i = 0; i < 4; i++)
TIM_BaseInitStructure.TIM_Prescaler=3; //设置TIM时钟频率除数的预分频值(18M)
TIM_BaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数器模式
TIM_BaseInitStructure.TIM_Period=1800;//设置下一个更新事件装入活动的自动重装载寄存器周期的值
stm32pwm输出三角波原理

stm32pwm输出三角波原理
在STM32微控制器中,PWM 输出可以实现多种波形,包括方波、正弦波、三角波等。
其中,三角波是一种非常常见的波形,在很多应用场景中都有广泛的应用。
三角波是一种连续的、平滑的波形,其特点是从低电平逐渐升高到高电平,然后再逐渐降低到低电平,如同一个长长的三角形。
在STM32 中,输出三角波需要使用 PWM 模块和定时器,并对定时器的计数器进行配置。
具体来说,输出三角波的原理如下:
1. 配置定时器为向上计数模式,并设置一个合适的计数频率,例如 10 kHz。
2. 配置 PWM 输出通道为定时器输出比较功能,并选择合适的输出极性和时钟分频系数。
3. 在每次定时器计数器达到设定值时,PWM 输出通道会自动翻转输出电平,这将导致三角波的上升和下降。
4. 在每次计数器溢出时,需要重新设置计数器的初始值,以保证连续输出三角波。
5. 如果需要改变三角波的频率或幅值,可以通过改变定时器的计数频率或 PWM 输出通道的占空比来实现。
通过上述方法,可以在 STM32 微控制器中实现三角波的输出。
这种波形非常适合一些需要连续、平滑的变化的应用场景,例如音频信号发生器、电机驱动等。
stm32 中pwm频率计算公式

一、概述在嵌入式系统开发中,PWM(脉冲宽度调制)是一种重要的控制技术,常用于电机驱动、灯光控制、无线通讯和其他类似应用领域。
对于STM32系列的微控制器来说,如何准确地计算PWM的频率是一个关键问题。
本文将介绍STM32中PWM频率的计算公式,希望对开发者们有所帮助。
二、PWM频率计算公式在STM32系列微控制器中,PWM的频率计算可以使用以下公式:\[PWM频率 = \frac{定时器时钟频率}{预分频系数 * 定时器自动重载值}\]其中,各参数的含义如下:1. 定时器时钟频率:定时器的时钟频率取决于系统时钟的频率以及定时器的分频系数。
一般情况下,定时器的时钟频率可以表示为:\[定时器时钟频率 = 系统时钟频率 / 分频系数\]如果系统时钟频率为72MHz,定时器的分频系数为72,那么定时器时钟频率为1MHz。
2. 预分频系数:预分频系数决定了定时器时钟频率的除数。
通过修改预分频系数,可以改变PWM信号的频率。
在STM32系列微控制器中,通常有多个预分频系数可以选择,开发者可以根据具体应用需求进行选择。
3. 定时器自动重载值:定时器的自动重载值决定了PWM周期的长度。
一般情况下,定时器的计数范围为0到定时器自动重载值,当定时器计数达到自动重载值时,定时器会自动清零并产生中断。
通过以上公式,开发者可以根据具体的系统时钟频率、预分频系数和定时器自动重载值来计算出所需的PWM频率。
三、实例分析为了更直观地理解PWM频率的计算方法,接下来将通过一个实例来演示具体的计算过程。
假设我们需要设计一个PWM信号,其频率为1kHz,系统的时钟频率为72MHz。
我们可以根据需要的PWM频率来确定定时器的自动重载值。
由于所需的PWM频率为1kHz,因此PWM周期为1ms。
根据PWM的工作原理,我们知道PWM信号的周期T与频率f的关系为:\[T = \frac{1}{f}\]PWM周期T为1ms。
我们需要根据系统时钟频率来确定定时器的分频系数。
STM3日记2之高级定时器TIM1和TIM8

STM32 高级定时器-PWM简单使用高级定时器与通用定时器比较类似,下面是一个TIM1 的PWM 程序,TIM1是STM32唯一的高级定时器。
共有4个通道有死区有互补。
先是配置IO脚:GPIO_InitTypeDef GPIO_InitStructure;/* PA8设置为功能脚(PWM) */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/*PB13 设置为PWM的反极性输出*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);/*开时钟PWM的与GPIO的*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);/*配置TIM1*/TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;void Tim1_Configuration(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM_DeInit(TIM1); //重设为缺省值/*TIM1时钟配置*/TIM_TimeBaseStructure.TIM_Prescaler = 4000; //预分频(时钟分频)72M/4000=18KTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数TIM_TimeBaseStructure.TIM_Period = 144; //装载值18k/144=125hz 就是说向上加的144便满了TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置了时钟分割不懂得不管TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //周期计数器值不懂得不管TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); //初始化TIMx的时间基数单位/* Channel 1 Configuration in PWM mode 通道一的PWM */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效PA8TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //反向通道也有效PB13 TIM_OCInitStructure.TIM_Pulse = 40; //占空时间144 中有40的时间为高,互补的输出正好相反TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //互补端的极性TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //空闲状态下的非工作状态不管TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //先不管TIM_OC1Init(TIM1,&TIM_OCInitStructure); //数初始化外设TIMx通道1这里2.0库为TIM_OCInit/* TIM1 counter enable开定时器*/TIM_Cmd(TIM1,ENABLE);/* TIM1 Main Output Enable 使能TIM1外设的主输出*/TIM_CtrlPWMOutputs(TIM1,ENABLE);}//设置捕获寄存器1void SetT1Pwm1(u16 pulse){TIM1->CCR1=pulse;}/*操作寄存器改变占空时间*//*************************************************************************** **************************************TIM1的定时器通道时间1到4 分别为PB8 PA9 PA10 PA11 而互补输出分别为PB13 PB14 PB15中止PB12 。
stm32 pwm 输出一定数量脉冲

利用定时器PWM模式输出一定数量脉冲方式:定时器的同步,以一个定时器作为另一个定时器的与分频器方式。
具体代码实现:void Tim4_Slave_Init(void){TIM_DeInit(TIM4);器,使之进入初始状态//主要用于复位TIM4定时//自动重装TIM_TimeBaseStructure.TIM_Period=pulnum;载寄存器的值//}void Tim1_PWM_Init(void){CCR1_Val = (timer1_period+1)/2;TIM_SelectInputTrigger(TIM4,TIM_TS_ITR0);TIM_InternalClockConfig(TIM4);TIM4->SMCR = 0X07;//设定从模式控制寄存器//TIM_UpdateDisableConfig(TIM4,ENABLE);TIM_ARRPreloadConfig(TIM4, ENABLE);TIM_ClearFlag(TIM4,TIM_FLAG_Update);TIM_TimeBaseStructure.TIM_Prescaler=0;//时钟预分频数//采样分频TIM_TimeBaseStructure.TIM_ClockDivision=0;TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上溢出TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//清除溢出中断标志TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);TIM_Cmd(TIM4,ENABLE);//是否开启时钟(开启后每发送一个脉冲,定时器加一)CCR2_Val = (timer1_period+1)/2;/* -----------------------------------------------------------------------TIM1 Configuration:generate 4 PWM signals with 4 different duty cycles:TIM1CLK = 36 MHz, Prescaler = 0x0, TIM1 counter clock = 36 MHzTIM1 ARR Register = 999 => TIM1 Frequency = TIM1 counter clock/(ARR +1)TIM1 Frequency = 36 KHz.TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 50%TIM1 Channel2 duty cycle = (TIM1_CCR2/ TIM1_ARR)* 100 = 50%TIM1 Channel3 duty cycle = (TIM1_CCR3/ TIM1_ARR)* 100 = 50%TIM1 Channel4 duty cycle = (TIM1_CCR4/ TIM1_ARR)* 100 = 50%----------------------------------------------------------------------- *//* Time base configuration */TIM_TimeBaseStructure.TIM_Period = timer1_period;TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);TIM1->CR1 &= ((u16)0x03FD);// UDIS enable/* PWM1 Mode configuration:Channel1 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR1_Val;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;CCR3_Val = (timer1_period+1)/2;CCR4_Val = (timer1_period+1)/2;GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);TIM_OC1Init(TIM1, &TIM_OCInitStructure);TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);/* PWM1 Mode configuration:Channel2 */TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR2_Val;TIM_OC2Init(TIM1, &TIM_OCInitStructure);TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);/* PWM1 Mode configuration:Channel3 */TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR3_Val;TIM_OC3Init(TIM1, &TIM_OCInitStructure);TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);/* PWM1 Mode configuration:Channel4 */TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR4_Val;TIM_OC4Init(TIM1, &TIM_OCInitStructure);TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_ARRPreloadConfig(TIM1, ENABLE);//apreTIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);/* TIM1 enable counter */TIM_Cmd(TIM1, ENABLE);/* Main Output Enable */TIM_CtrlPWMOutputs(TIM1, ENABLE);}voidTIM4_IRQHandler(void){GPIO_InitTypeDef GPIO_InitStructure;if (TIM_GetITStatus(TIM4,TIM_IT_Update) !=RESET){TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//进入中断后把通道GPIO关闭,达到控制脉冲目的GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11 |GPIO_Pin_13 | GPIO_Pin_14;}}GPIO_Init(GPIOE, &GPIO_InitStructure);TIM_Cmd(TIM4,DISABLE);//关闭定时器4GPIO_SetBits(GPIOE, GPIO_Pin_9);GPIO_SetBits(GPIOE, GPIO_Pin_11);GPIO_SetBits(GPIOE, GPIO_Pin_13);GPIO_SetBits(GPIOE, GPIO_Pin_14);GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;当想发送一定脉冲时,配置TIM4ARR寄存器,使能TIM4,即可发送一定数量脉冲。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
今天对AFIO有了正确的认识。
在使用引脚的重映射功能和外部中断时需要使用AIFO时钟。
贴一段官方手册对AFIO的解释:
为了优化64脚或100脚封装的外设数目,可以把一些复用功能重新映射到其他引脚上。
设置复用
重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。
这时,复用功能不再映射到它们的原始分配上。
这次PWM实验要实验的功能就是呼吸灯。
配置步骤如下:
1:使能GPIO和TIM1时钟;
2:配置GPIO,MODE查中文参考手册确定为为AF_PP;
3:配置定时器;
4:配置TIM1_CH1输出比较函数;
5:因为TIM1为高级定时器,普通定时器在完成以上设置了之后,就可以输出 PWM 了,但是高级定时器,我们还需要使能刹车和死区寄存器( TIM1_BDTR)的 MOE 位,以使能整个 OCx(即 PWM)输出。
库函数的设置函数为:
TIM_CtrlPWMOutputs(TIM1,ENABLE);// MOE 主输出使能
6:使能预装载;
7:使能自动重装载;(区别仅在于是否是本次还是下一个周期进行改变,可写,可不写)8:使能定时器。
贴出timer.c
void PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period=arr;
TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_Pulse=0;(初值)
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM1,&TIM_OCInitStructure);
TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1,ENABLE);
TIM_Cmd(TIM1,ENABLE);
}
然后在主函数中只需调用TIM_SetCompare1(TIM1,led0val);就可以完成占空比的变化。
贴出主函数:
#include "timer.h"
#include "delay.h"
int main(void)
{
u16 led0val=0;
u8 dir;
PWM_Init(899,0); 频率为1/(900/72000000)=80KHz
delay_init();
while(1)
{
delay_ms(10); (延时函数万万不能漏!)
if(led0val>300) dir=0;
else if(led0val==0) dir=1;
if(dir) led0val++;
else led0val--;
TIM_SetCompare1(TIM1,led0val);
}
}
这里,我们从死循环函数可以看出,我们控制LED0_PWM_VAL 的值从0 变到300,然后
又从300 变到0,如此循环,因此DS0 的亮度也会跟着从暗变到亮,然后又从亮变到暗。
至于
这里的值,我们为什么取300,是因为PWM 的输出占空比达到这个值的时候,我们的LED 亮度变化就不大了(虽然最大值可以设置到899),因此设计过大的值在这里是没必要的。
至此,我们的软件设计就完成了。
最后我还做了另外一个小实验,同时使用两个定时器控制两个呼吸灯,一开始新配置的那盏怎么都不行,后来发现原来是RCC时钟没给它配置好,真是兜了个机灵!洗澡,休息!
************************************************************
更新:
做了输入捕获实验后,发现主函数中还可以这样写:
TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);
if(TIM_GetCapture1(TIM1)>300) TIM_SetCompare1(TIM1,0); 严重声明的是这里的TIM_GetCapture1();得到的是寄存器CCR1的值;这里来说一下CCR1寄存器,它有点特别。
它在输入捕获模式和输出比较模式下的用法是不一样的。
在输入捕获时,它是CNT计数值;
在输出比较时,它是预装载值;
详见手册P293。