求教高人MSP430的PWM输出出现无规则跳变的原因
波形如上图所示,工程是用来调节光线的,通过一个传感器测量环境光,然后根据环境光强设定TA1CCR2的值,改变PWM输出,正常波形应该是个连续的占空比变化,但是现在出现了无规则的跳变(毫无规律,而且出现频率也很低,抓了1000秒的波形,只出现了两个异常波形),哪位高人以前遇到过类似的情况,能否共享一下解决方法。先谢谢了!
另外,通过条件断点,发现波形跳变时TA1CCR2的值根本不是零。
相关代码:
void TimerA1Init(void)
{
TA1CTL |= TASSEL_1; //设定时钟为ACLK,
TA1CTL |= ID_0; //不分频
TA1CCR0 = 512; //波形周期,根据计时器时钟周期计算
TA1CCR2 = 64; //default
TA1CCTL2 |= OUTMOD_3; //PWM输出模式3,P2.4
TA1CTL |= MC_1; //增计数模式,MC_0可以停止
}
void PortTwoInit(void)
{
P2DIR |= 0xf3;
P2OUT = 0x14; //P2.2 for KeyA input, enable pull up resistor
P2REN |= 0x04;
P2SEL |= BIT4;
}
以下代码就是条件断点的位置,如果TA1CCR2的值为0,那么P1.0就会反转,这样逻辑分析仪就能捕捉到波形,但实际没有捕捉到任何波形。
if((TA1CCR2 - 0) == 0)
{
P1OUT ^= BIT0;
} 本帖最后由 happyliu 于 2014-5-20 16:27 编辑
感觉应该是在修改占空比参数时带来的错误,在不合适的时候修改了寄存器值,如果不修改占空比的话应该不会有这个异常点,比如反转值是101时,在向上计数值是100时修改为反转值是99
PWM是自动的呀 不需要你干预他就能工作. 我还特地做了个例子,MSP也有些怪的地方http://www.amobbs.com/thread-5581962-1-1.html 俺的问题貌似解决了,主要是将占空比调节的操作放到PWM产生的中断函数中。
皮爱了西 发表于 2014-6-6 17:02
俺的问题貌似解决了,主要是将占空比调节的操作放到PWM产生的中断函数中。
...
周期到了 才能更新 新的占空比 差的PWM都这样
可是...我这样 在占空比接近0时突然出来一个 100%的占空比 这要命 wind2100 发表于 2014-6-19 16:31
周期到了 才能更新 新的占空比 差的PWM都这样
可是...我这样 在占空比接近0时突然出来一个 100%的占空 ...
放到中断里更新占空比应该可以搞定,你的问题和我的应该一样。 皮爱了西 发表于 2014-6-19 17:22
放到中断里更新占空比应该可以搞定,你的问题和我的应该一样。
调一个 死值的占空比 没事 ,我将占空比 100% 慢慢降到 0% 快到 0%时
出现一次 占空比100%的一个脉冲 LED灯闪一下,调光中间不闪. 现在还不知道是我程序的BUG还是这IC本来就有这鸟问题 不能用于调光.
这要命 ,,,
我已经在 PWM 那路中断 中 去更新占空比了,
前面我还试了 在MAIN中更新 和 另一组定时器中更新结果就是中间不断有闪烁感 有时无.
我用的是MSP430G2553
//===========================================================================
TA1CCR0 = Lum100-1; // PWM Period 1000us/(1/8MHZ) 这里不减1 高电平还不能到100%
TA1CCR1 = 0;//PWM1_duty_cycle_Val; // CCR1 PWM duty cycle 2.1
TA1CCR2 = 0;//PWM1_duty_cycle_Val; // CCR2 PWM duty cycle 2.4
TA1CCTL0 = CCIE; // CCR0 interrupt enabled就用这个中断
TA1CCTL1 = OUTMOD_7; // CCR1 reset/set
TA1CCTL2 = OUTMOD_7; // CCR2 reset/set
TA1CTL = TASSEL_2 + TACLR + MC_1; // SMCLK, up mode
然后 定时中断 更新
// Timer1 A0 interrupt service routine
#pragma vector=TIMER1_A0_VECTOR //TA1 CCR0
__interrupt void Timer1_A0 (void)//1khz
{
TA1CCR1 = PWM1_duty_cycle;
TA1CCR2 = PWM1_duty_cycle;
} wind2100 发表于 2014-6-20 08:08
调一个 死值的占空比 没事 ,我将占空比 100% 慢慢降到 0% 快到 0%时
出现一次 占空比100%的一个脉冲 LED ...
你这个是周期性的还是随机性的,我之前那个问题是完全随机的。
我看了你的处理方式和我的一样,另外我用的也是2553。 随机性 不是每次都出现完全随机 那是你没用PWM 定时器那个 中断 更新PWM占空比
用了M3 M0都没这种问题 最多是不能到100%我发现一个解决办法 就是占空比不到0% 设置最低10%,最高100% 的样子 就不会出现那个 脉冲了 皮爱了西 发表于 2014-6-20 08:42
你这个是周期性的还是随机性的,我之前那个问题是完全随机的。
我看了你的处理方式和我的一样,另外我用 ...
#include <msp430.h>
typedef unsigned charu8;
typedef unsigned int u16;
typedef unsigned longu32;
typedef signed char s8;
typedef signed int s16;
typedef signed long s32;
#define LED1() (P2OUT ^=BIT0)
#define PWM1_duty_cycle_Val 1000
u16 PWM1_duty_cycle = 0;
u16 PWM1_duty_cycle_CCR = 0;
//=============================================================================
void InitSystemClock(void)
{
BCSCTL1 = CALBC1_8MHZ;
DCOCTL= CALDCO_8MHZ; // DCO 8MHZ
FCTL2 = FWKEY + FSSEL0 + 0x18; // MCLK/3 for Flash Timing 8M / 25 320K//FLASH IN 257-476KHZ
}
//=============================================================================
void Init_IO(void)
{
P2DIR |=BIT0; //P2.0 Output LED
//P2OUT &= ~BIT1; //LOW
//P2OUT |= BIT1; //HIGH
P2DIR |= BIT1; // P2.1 pwm output详见硬件手册
P2SEL |= BIT1; // P2.1 Pin9 Multiplexing
//P2DIR |= BIT2; // P2.1 pwm output2.1 2.2只能输出相同波形
//P2SEL |= BIT2; // P2.1 Pin9
//P2OUT &= ~BIT4; //LOW
P2DIR |= BIT4; // P2.4 pwm output
P2SEL |= BIT4; // P2.4 Pin12Multiplexing
//P2DIR |= BIT5; // P2.4 pwm output2.4 2.5只能输出相同波形
//P2SEL |= BIT5; // P2.4 Pin12
}
//=============================================================================
void InitPWM(void)
{
/*
//===========================================================================
TA0CCR0 = 2550; // PWM Period
TA0CCR1 = 1000; // CCR1 PWM duty cycle
//TA0CCR2 = 800; // CCR2 PWM duty cycle 28Pins
TA0CCTL0 = CCIE; // CCR0 interrupt enabled
//TA0CCTL1 = OUTMOD_7; // CCR1 reset/set
//TA0CCTL2 = OUTMOD_7; // CCR2 reset/set 28Pins
TA0CTL = TASSEL_2 + TACLR + MC_1; // SMCLK, up mode定时器_A 控制寄存器
*/
//===========================================================================
TA1CCR0 = PWM1_duty_cycle_Val-1; // PWM Period 1000us/(1/8MHZ)
TA1CCR1 = 0;//PWM1_duty_cycle_Val; // CCR1 PWM duty cycle 2.1
TA1CCR2 = 0;//PWM1_duty_cycle_Val; // CCR2 PWM duty cycle 2.4
TA1CCTL0 = CCIE; // CCR0 interrupt enabled
TA1CCTL1 = OUTMOD_7; // CCR1 reset/set
TA1CCTL2 = OUTMOD_7; // CCR2 reset/set
TA1CTL = TASSEL_2 + TACLR + MC_1+ID_3; // SMCLK, up mode
}
// Timer1 A0 interrupt service routine
#pragma vector=TIMER1_A0_VECTOR //TA1 CCR0
__interrupt void Timer1_A0 (void)//1khz
{
if (PWM1_duty_cycle_CCR < PWM1_duty_cycle) //Smooth
{
PWM1_duty_cycle_CCR++;
}
else if (PWM1_duty_cycle_CCR > PWM1_duty_cycle)
{
if (PWM1_duty_cycle_CCR)
PWM1_duty_cycle_CCR--;
}
TA1CCR1 = PWM1_duty_cycle_CCR;
TA1CCR2 = PWM1_duty_cycle_CCR;
}
//=============================================================================
void DelaymS(unsigned int n)
{
volatile u16 i = 0;
volatile u16 j = 0;
for (i=n;i>0;i--)
{
for (j=680;j>0;j--)
{
_NOP();
}
}
}
/*
* main.c
*/
int main(void)
{
int i = 0;
_DINT(); // disable_interrupt
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
InitSystemClock();
InitPWM(); //TA1
Init_IO();
_EINT() ; // enable_interrupt
while(1)
{
LED1();
if (++i == 1)
{
PWM1_duty_cycle = 10; //注意将这里改成 0占空比到0%时 就会出现一个干扰脉冲
}
else if (i == 2)
{
i = 0;
PWM1_duty_cycle = PWM1_duty_cycle_Val;
}
DelaymS(3000);
}
//return 0;
}
//不到 0% 就可以了要么就用低电平来驱动 也可以解决 不能到0% 但可以到99%吧 0%和100%是不可能都达到的,只能取其一,这个问题好像在TI论坛讨论过,就像24点和0点的关系一样,
我用的是模式3,可以到100%高电平,不要求100%低电平 皮爱了西 发表于 2014-6-20 12:25
0%和100%是不可能都达到的,只能取其一,这个问题好像在TI论坛讨论过,就像24点和0点的关系一样,
我用的 ...
这样 STM32有讲 又仔细看了一下 这手册上面并没有讲这个问题
现在只能设置 1% -100%还不能在MCU上面反向 看来我要 在电路中反向,用低电平来驱动了.
80-80008MHZ只能这样了 不会出现闪烁情况了
页:
[1]