杰理AC692X系列—关于模拟PWM、电机PWM和定时器映射PWM(1)
杰理690X系列的芯片目前只有4路定时器,分别是
Timer0,Timer1,Timer2,Timer3
其中Timer0被系统时钟占用,无法用于PWM输出。
前些日子做了一个项目,并且还需要支持红外遥控,RGB总共需要三路PWM,遥控器和系统时钟已经占用了两个定时器,只剩下Timer2和Timer3.
在做这个项目时用了好多种方式,请听我徐徐道来,哈哈哈
第一种
就是用两个定时器去映射2个,自己再模拟一个pwm,模拟的pwm推的灯有个弊端就是会看见肉眼可见的抖动,但是如果只做呼吸灯,那问题不大。
第二种
就是用两个定时器去映射2个,再用电机pwm输出一个,电机pwm唯一的弊端就是不能映射,只能使用固定的io口,那关于定时器映射的代码待会再讲,现在先讲电机pwm的注意事项
(1)、在mcpwm_api.h中有个void mcpwm_demo();
记住一定不要这样替换掉void mcpwm_demo();这样写
void mcpwm_demo(){
初始化代码
};
会初始化不了的,要自己重写个函数。代码如下
void mcpwm_demo();
void my_mcpwm_demo()
{
mcpwm_module_on(MCPWM_INCREASE_REDUCE_MODE, 24000000L, MCPWM_CLK_DIV4, 10000L, MCPWM_USE_DENOMINATOR);
// 占空比是占高电平还是低电平 对应io口
mcpwm2_init(MCPWMCH2_L_OPPOSITE, MCPWMCH2_H);
JL_PORTB->PU |= BIT(5);
JL_PORTB->PD &= ~BIT(5);
JL_PORTB->DIR &= ~BIT(5);
}
void my_mcpwm_close()
{
mcpwm_module_off(MCPWMCH2_H);
}
(2)、电机 PWM 对应的 IO 如下.(电机 PWM 支持 IO mapping,详细参考用户手册)
MCPMW0 H-PA0 L-PA3
MCPMW1 H-PC1 L-PC5
MCPMW2 H-PB5 L-PB0
(3)、在调节电机占空比时记得在占空比为0时关掉电机 PWM ,不然会出现灯不灭的情况
void mc_pwm_set(u8 duty)
{
if(duty>0)set_mcpwm2(duty);
else my_mcpwm_close();
}
第三种
就是用两个定时器去映射3个,这个就是要注意一下扫描频率。自己可以试试
#define PWM_FRQ 5000L
void timer3_pwm_set(u32 fre, u8 duty) ///RED
{
SFR(JL_IOMAP->CON1, 8, 4, 15);// CHANNEL0, 对应输出 IO 口的 OUT:0,DIE:0
JL_TIMER3->CON = 0x0000;
JL_TIMER3->PRD = OSC_Hz / (4 * fre);
JL_TIMER3->PWM = (JL_TIMER3->PRD * duty) / 100;
JL_TIMER3->CON = (1 << 4) | (1 << 8) | (1 << 0) | (2 << 2);
JL_PORTC->PU |= BIT(5);
JL_PORTC->PD |= BIT(5);
JL_PORTC->DIR &= ~BIT(5);
JL_PORTC->OUT &= ~BIT(5);
JL_PORTC->DIE &= ~BIT(5);
}
//调用
timer3_pwm_set(PWM_FRQ,100);
看图~
嘿嘿~
定时器pwm默认输出口
PWM0--TIMER0--PA1
PWM1--TIMER1--PA4
PWM2--TIMER2--PB3
PWM3--TIMER3--PB4
PWM 不通过 OUTPUTCHANNEL 设置的时候,PWM 从默认的 IO 口输出
接下来就是配置一个定时器去映射两个io口了
void timer3_pwm_set(u32 fre, u8 duty) ///RED
{
SFR(JL_IOMAP->CON1, 8, 4, 15);// CHANNEL0, 对应输出 IO 口的 OUT:0,DIE:0
JL_TIMER3->CON = 0x0000;
JL_TIMER3->PRD = OSC_Hz / (4 * fre);
JL_TIMER3->PWM = (JL_TIMER3->PRD * duty) / 100;
JL_TIMER3->CON = (1 << 4) | (1 << 8) | (1 << 0) | (2 << 2);
//不添加需要映射口代码
}
在循环里面添加代码以下
timer3_pwm_set(PWM_FRQ, 50);
JL_PORTC->PU |= BIT(5);
JL_PORTC->PD |= BIT(5);
JL_PORTC->DIR &= ~BIT(5);
JL_PORTC->OUT &= ~BIT(5);
JL_PORTC->DIE &= ~BIT(5);
JL_PORTC->PU |= BIT(4);
JL_PORTC->PD |= BIT(4);
JL_PORTC->DIR &= ~BIT(4);
JL_PORTC->OUT &= ~BIT(4);
JL_PORTC->DIE &= ~BIT(4);
这样就可以映射两个io口了,如果想用一个定时器映射两个io口为不同亮度,只需要把一个io口设为输入高阻,同时改变另一个映射的io口的占空比。这个逻辑就自己想吧。哈哈哈
就写到这了,欢迎大佬改正~~