求一stm32产生spwm波的程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求一stm32产生spwm波的程序相关的知识,希望对你有一定的参考价值。
mail 511432335 qq
参考技术A void PWM_Init()unsigned short CCR1_Val = 5000;
unsigned short CCR2_Val = 5000;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = BSP_GPIOC_PWM1|BSP_GPIOC_PWM2; // PC6,PC7输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* -----------------------------------------------------------------------
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
TIM3 Frequency = 36 KHz.
TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
----------------------------------------------------------------------- */
/* Time base configuration */
TIM_DeInit(TIM3);
TIM_TimeBaseStructure.TIM_Period = 10000; // 200Hz
TIM_TimeBaseStructure.TIM_Prescaler = 35; //36M/(35+1)=1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //50%占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
stm32高级定时器的应用——spwm
用过stm32定时器的朋友都知道,定时器的CCR寄存器,可以用来配置PWM的输出,但同样也可以用来配置spwm。废话不多说,直接上代码。
首先,你得考虑一下几个因素:
1.同步调制还是异步调制。
2.载波比N设置为多少
3.spwm计算法
4.prescaler和period的值
5.改变CCR还是改变ARR
下面是程序的大致情况:
1.使用同步
2.载波比设置为N = 360
3.采用对称规则采样法
4.通过中断时实改变CCR的值
5.使用stm32f429,它的高级定时器时钟频率为180M(不分频的情况下)
6.计数器采用递增递减的方式技术
——————————————————————————————————————————
1.GPIO的复用
使用了TIM8_CH1和TIM8_CH1N,两个引脚。
这两个脚是复用功能,所以在配置GPIO口的时候,要调用
这段代码在GPIO配置之前,还是GPIO_Init()之后都没有太大的影响。
2.ARR值与CCR
定义计数频率,TIM_CLk,和滤波后正弦波的频率,Sin_F那么
prescaler = 定时器计数频率 / TIM_CLK - 1;
period = TIM_CLK / (2*Sin_F *N) - 1;
3.定时器计数方式的设定
不要死记什么TIM_CountMode_CenterAligned1,等,每款板子可能不一样。
在这块stm32f4的板子上面,CMS = 01 ,对应定时器递减计数的时候,当计数的值等于CCR的值时,就触发中断,查看对应的寄存器
4.中断函数的处理
首先进行中断向量表的配置,这大家都会吧
根据对称规则采样的公式 D = 载波的周期 / 4 *(1 - 调制比 * sin(x)).
这里将sin(x)离散化处理,因为sin函数的值是小于1的,所以Sin_Tab[]应该是float或者double型
如果正弦波的周期定了,那么载波的定时器的周期也定了,参考下面的函数,
float n1_RET(float Sin_F)
{
static float temp;
temp = TIM_CLK;
temp = temp/Sin_F;
temp = temp/N;
temp = temp/4;
return temp;
}
这个函数就是计算载波周期的四分之一,当它的返回值乘以占空比就得到公式的第二个参数,
float n2_RET(float M,float AN_RET)
{
static float temp;
temp = AN_RET;
temp *= M;
return temp;
}
最后在中断处理函数里面更新CCR的值,记住一次只更新一个值,并不是让你更新N个,
所以在中断处理函数中不需要对 i 进行 1 ~ 360 的遍历 , 只需要 每次递增就行了。
当 i 超过 N 时,进行复位就可以了。
TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);
NewChannelValue = (int)(n1_Temp - n2_Temp*Sin_Tab[i++]);
if ( i == 360)
{
i = 0;
}
TIM_SetCompare1(ADVANCE_TIM,NewChannelValue);
以上是关于求一stm32产生spwm波的程序的主要内容,如果未能解决你的问题,请参考以下文章