搜索
bottom↓
回复: 11

求教高人MSP430的PWM输出出现无规则跳变的原因

[复制链接]

出0入0汤圆

发表于 2014-5-17 10:49:40 | 显示全部楼层 |阅读模式


波形如上图所示,工程是用来调节光线的,通过一个传感器测量环境光,然后根据环境光强设定TA1CCR2的值,改变PWM输出,正常波形应该是个连续的占空比变化,但是现在出现了无规则的跳变(毫无规律,而且出现频率也很低,抓了1000秒的波形,只出现了两个异常波形),哪位高人以前遇到过类似的情况,能否共享一下解决方法。先谢谢了!

另外,通过条件断点,发现波形跳变时TA1CCR2的值根本不是零。

相关代码:
  1. void TimerA1Init(void)
  2. {
  3.         TA1CTL |= TASSEL_1;                                //设定时钟为ACLK,
  4.         TA1CTL |= ID_0;                                        //不分频

  5.         TA1CCR0 = 512;                                //波形周期,根据计时器时钟周期计算
  6.         TA1CCR2 = 64;                                        //default
  7.         TA1CCTL2 |= OUTMOD_3;                        //PWM输出模式3,P2.4

  8.         TA1CTL |= MC_1;                                        //增计数模式,MC_0可以停止
  9. }
复制代码

  1. void PortTwoInit(void)
  2. {
  3.         P2DIR |= 0xf3;                                       
  4.         P2OUT = 0x14;                                //P2.2 for KeyA input, enable pull up resistor
  5.         P2REN |= 0x04;
  6.         P2SEL |= BIT4;

  7. }
复制代码



以下代码就是条件断点的位置,如果TA1CCR2的值为0,那么P1.0就会反转,这样逻辑分析仪就能捕捉到波形,但实际没有捕捉到任何波形。
  1.         if((TA1CCR2 - 0) == 0)
  2.         {
  3.                 P1OUT ^= BIT0;
  4.         }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-5-20 16:21:00 | 显示全部楼层
本帖最后由 happyliu 于 2014-5-20 16:27 编辑

感觉应该是在修改占空比参数时带来的错误,在不合适的时候修改了寄存器值,如果不修改占空比的话应该不会有这个异常点,比如反转值是101时,在向上计数值是100时修改为反转值是99

出0入0汤圆

发表于 2014-5-23 07:58:39 | 显示全部楼层
PWM是自动的呀 不需要你干预他就能工作. 我还特地做了个例子,MSP也有些怪的地方  http://www.amobbs.com/thread-5581962-1-1.html

出0入0汤圆

 楼主| 发表于 2014-6-6 17:02:19 | 显示全部楼层
俺的问题貌似解决了,主要是将占空比调节的操作放到PWM产生的中断函数中。

出0入0汤圆

发表于 2014-6-19 16:31:21 | 显示全部楼层
皮爱了西 发表于 2014-6-6 17:02
俺的问题貌似解决了,主要是将占空比调节的操作放到PWM产生的中断函数中。
...

周期到了 才能更新 新的占空比 差的PWM都这样

可是...我这样 在占空比接近0时  突然出来一个 100%的占空比 这要命

出0入0汤圆

 楼主| 发表于 2014-6-19 17:22:20 | 显示全部楼层
wind2100 发表于 2014-6-19 16:31
周期到了 才能更新 新的占空比 差的PWM都这样

可是...我这样 在占空比接近0时  突然出来一个 100%的占空 ...

放到中断里更新占空比应该可以搞定,你的问题和我的应该一样。

出0入0汤圆

发表于 2014-6-20 08:08:23 | 显示全部楼层
皮爱了西 发表于 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;
}

出0入0汤圆

 楼主| 发表于 2014-6-20 08:42:17 | 显示全部楼层
wind2100 发表于 2014-6-20 08:08
调一个 死值的占空比 没事 ,我将占空比 100% 慢慢降到 0% 快到 0%时
出现一次 占空比100%的一个脉冲 LED ...

你这个是周期性的还是随机性的,我之前那个问题是完全随机的。
我看了你的处理方式和我的一样,另外我用的也是2553。

出0入0汤圆

发表于 2014-6-20 09:24:11 | 显示全部楼层
随机性 不是每次都出现  完全随机 那是你没用PWM 定时器那个 中断 更新PWM占空比
用了M3 M0都没这种问题 最多是不能到100%  我发现一个解决办法 就是占空比不到0% 设置最低10%,最高100% 的样子 就不会出现那个 脉冲了

出0入0汤圆

发表于 2014-6-20 09:34:54 | 显示全部楼层
皮爱了西 发表于 2014-6-20 08:42
你这个是周期性的还是随机性的,我之前那个问题是完全随机的。
我看了你的处理方式和我的一样,另外我用 ...

#include <msp430.h>

typedef unsigned char  u8;
typedef unsigned int   u16;
typedef unsigned long  u32;

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 output  2.1 2.2只能输出相同波形
    //P2SEL |= BIT2;                            // P2.1 Pin9

    //P2OUT &= ~BIT4;                           //LOW
    P2DIR |= BIT4;                            // P2.4 pwm output
    P2SEL |= BIT4;                            // P2.4 Pin12  Multiplexing
    //P2DIR |= BIT5;                            // P2.4 pwm output  2.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入0汤圆

 楼主| 发表于 2014-6-20 12:25:16 | 显示全部楼层
0%和100%是不可能都达到的,只能取其一,这个问题好像在TI论坛讨论过,就像24点和0点的关系一样,

我用的是模式3,可以到100%高电平,不要求100%低电平

出0入0汤圆

发表于 2014-6-23 11:31:37 | 显示全部楼层
皮爱了西 发表于 2014-6-20 12:25
0%和100%是不可能都达到的,只能取其一,这个问题好像在TI论坛讨论过,就像24点和0点的关系一样,

我用的 ...

这样 STM32有讲 又仔细看了一下 这手册上面并没有讲这个问题

现在只能设置 1% -100%  还不能在MCU上面反向 看来我要 在电路中反向,用低电平来驱动了.

80-8000  8MHZ  只能这样了 不会出现闪烁情况了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 14:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表