微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32 定时器产生PWM彻底应用

STM32 定时器产生PWM彻底应用

时间:12-02 来源:互联网 点击:

TIM_Cmd(TIM2,ENABLE);

}

void TIM2_IRQHandler(void)

{

TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);

if(n==1)

{

n=0;

TIM_SetCompare1(TIM2,CCR1_Val2);

}

else

{

n=1;

TIM_SetCompare1(TIM2,CCR1_Val1);

}

}

通过改变比较寄存器(CCR1)中的值,改变PWM的占空比,在每次匹配中断中改变CCR1的值。上面程序实现的是产生一路频率为10K占空比为40%的PWM波。

有了上面的思想我就想产生四路不同频率不同占空比的PWM波,经过反复思考光配函数似乎不能实现,在网上去查了的,很多网友也说不能实现,有一个网友给了一个提示:软件模拟。刚开始没明白什么意思,于是还是自己继续配置库函数,在这个过程中一直有两个疑问:

每次中断中,CCR寄存器的值都在循环的增加,CCR的寄存器不可能是无限大吧?就算是无限大,计数器也不是无限大呀,他只能记到65535。初步确定使用匹配中断不行,我有想过同时使用溢出中断和匹配中断,但这样四路PWM波只能是固定的,频率和占空比不能调。大概说一下怎样用溢出中断和匹配中断实现四路固定的PWM波,把计数器寄存器(CNT)的值装最大周期的那个PWM波,当一次计数完成算一下三路小点周期数,在匹配中断中对应的设个变量,CCR就改变几次,溢出中断来了就再次给计数器装初值,同时四个比较寄存器从装初值,这样很麻烦,理论上可以实现,但我考虑到最终不能实现我的要求,就没有去验证。所以产生四路频率可调占空比可调,用一个定时器似乎不能实现,就一直卡到这里,我又在想飞哥说能实现,就肯定能实现,我又在网上找资料,还是没找到,只是有人题四路,软模拟,于是我就思考用软模拟实现,最后在一个师兄的指点下,确实用软件模拟一个中间比较寄存器能实现,思路大概是这样子的,首先让比较寄存器装满,也就是最大值(65535),然后通过改变模拟比较寄存器的值,每次匹配中断只需把模拟比较寄存器的值去比较就行,具体方案看程序。

unsigned charCnt[4]; //一个数组,这个数组的每个元素对应一个通道,用来判断装PWM得高电平还是低电平数

unsigned intT[4];//周期数组

unsigned intR[4];//模拟的比较寄存器数组,一样的每个通道对应一个数组元素

unsigned intRh[4];//模拟的PWM高电平比较寄存器

unsigned intRl[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++)

{

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)

F[0] = 40;

F[1] = 30;

F[2] = 20;

F[3] = 10;

for(i = 0; i < 4; i++)

{

Rh[i] = (T[i] * F[i]) / 100;

Rl[i] = T[i] - Rh[i];

}

R[0] = Rl[0];

R[1] = Rl[1];

R[2] = Rl[2];

R[3] = Rl[3];

CCR1 = R[0];

CCR2 = R[1];

CCR3 = R[2];

CCR4 = R[3];

}

对应的数组初始化

void RCC_Configuration(void)

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);

}

时钟配置

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

//Key1 PA0 Key3 PA8

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_8;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//Key2 PC13

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOC,&GPIO_InitStructure);

//Key PD3

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOD,&GPIO_InitStructure);

//TIM3 CH1 CH2

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//TIM3 CH3 CH4

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top