打印

请教LPC2138的6路PWM波如何分开设定频率

[复制链接]
3090|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2011-1-6 23:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用LPC2138驱动电机,直流电机用的是100KHz的波调占空比,伺服电机用的是100Hz,俺看资料的理解是这芯片,6个PWM模块只有一个PWM0寄存器来确定波形的周期。因而6个波的频率必段相同。
相关代码段如下:

#define MotorPWM1 1  //P0.0 PWM1
#define MotorPWM2 1<<7  //P0.7  PWM2
#define MotorPWM3 1<<1  //P0.1 PWM3
#define MotorPWM4 1<<8  //P0.8  PWM4
#define MotorPWM5 1<<21  //P0.21 PWM5
#define MotorPWM6 1<<9  //P0.9  PWM6
uchar ucMotorLatch_Data_Image;   //锁存到直流马达的数据的内存映象值
//初始化马达控制硬件
//PWMMR0控制脉冲周期,PWMMRX控制脉冲占空比
//1ms 脉冲周期。 延时长度2S
void InitDCMotorHardware(void)
{
PINSEL0 |= 2;   //P0.0设置为PWM1输出
PINSEL0 |= 2<<2;  //P0.3 设置为PWM3输出
PINSEL0 |= 2<<14;  //P0.7 设置为PWM2 输出
PINSEL0 |= 2<<16;  //P0.8 设置为PWM4 输出
PINSEL0 |= 2<<18;    //P0.9 设置为PWM6输出
PINSEL1 |= 1<<10;  //P0.21 设置为PWM5输出
ucMotorLatch_Data_Image=0;
// IO0DIR |= (MotorPWM1 | MotorPWM2 | MotorPWM4 |);
// IO0SET = (MotorPWM1 | MotorPWM2 | MotorPWM4 |);
PWMPR = 0x00;   //预分频寄存器
PWMMCR = 0x02;  //pwmmr0与PWMTC匹配时使PWMTC复位
PWMPCR = 0x7E00; //允许PWM1-PW6输出
// PWMMR0 = 18432000*3/100000;
PWMMR0 = 18432000*3/100;
PWMMR1 = PWMMR0/50;  //设置占空比
PWMMR2 = PWMMR0/50;  //设置占空比
PWMMR3 = PWMMR0/50;  //设置占空比
PWMMR4 = PWMMR0/50;  //设置占空比
PWMMR5 = PWMMR0/50;  //设置占空比
PWMMR6 = PWMMR0/50;  //设置占空比
PWMLER = 0x7F;    //PWM0-PWM6匹配锁存
PWMTCR = 0x02;
PWMTCR = 0x09;
}  


// PWMMR0 = 18432000*3/100000;
PWMMR0 = 18432000*3/100;

两者存在不可调和的矛盾,这可如何时是好?请教大家,实在不行,伺服电机控制口线改成GPIO口,用定时器模拟PWM波算了。

相关帖子

沙发
古道热肠|  楼主 | 2011-1-7 23:59 | 只看该作者
没找到好办法,自己整了个软件PWM波,还蛮好用的,共享一下。


void Init_Timer1(void)
{
          /* 定时器0初始化 */
        T1CTCR = 0;                   //定时器模式
        T1TC   = 0;                        /* 定时器设置为0                                                                                */
        T1PR   = 0;                        /* 时钟不分频                                                                                        */
        T1MCR  = 0x03;                /* 设置T0MR0匹配后复位计数器,并产生中断标志                                */
//        T1MR0  = (18432000 / 100000)*3;        /* 0.01mS秒钟定时计数值                                                                                        */
        T1MR0  = (18432000 / 120000)*3;        /* 0.01mS秒钟定时计数值                                                                                        */
        T1TCR  = 0x01;                /* 启动定时器                                                                                        */
        /* 设置定时器0中断IRQ */

}


#define SIM_PWM5 1<<21                 //P0.21
#define SIM_PWM6 1<<9                //P0.9


uint uiPWM5_RatioSetValue;
uint uiPWM6_RatioSetValue;

uint uiPWMPlusLength;
#define SIM_PWM_Plus_MaxLength 1200  //控制波形的周期
uint uiSIM_PWM5_Temp;
uint uiSIM_PWM6_Temp;
void SIM_PWM_PLUS_CTRL(void)
{
        if(uiPWMPlusLength)
        {
                 uiPWMPlusLength--;
        }
        else
        {
                uiPWMPlusLength = SIM_PWM_Plus_MaxLength;
//                ucSIM_PWM_Temp = 98;                 //占空比控制值
//                ucSIM_PWM_Temp = 70;                 //占空比控制值
                uiSIM_PWM5_Temp = uiPWM5_RatioSetValue;
                uiSIM_PWM6_Temp = uiPWM6_RatioSetValue;

                 LightContol(2,1);

                IO0SET = SIM_PWM5;
                IO0SET = SIM_PWM6;

        }

        if(uiSIM_PWM5_Temp)
        {
                uiSIM_PWM5_Temp--;
        }
        else
        {
//                LightContol(2,0);
                IO0CLR = SIM_PWM5;
//                IO0CLR = SIM_PWM6;

        }

        if(uiSIM_PWM6_Temp)
        {
                uiSIM_PWM6_Temp--;
        }
        else
        {
//                LightContol(2,0);
                IO0CLR = SIM_PWM6;
        }
}

uchar  ucFlag;
void  IRQ_Timer1(void) __irq
{
         if(ucFlag)
         {
                 ucFlag =0;
         }
         else
         {
                 ucFlag =1;
         }

         if(ucFlag)
         {
                LightContol(1,1);
         }
         else
         {
                 LightContol(1,0);
         }
         SIM_PWM_PLUS_CTRL();

         T1IR = 0x01;
         VICVectAddr = 0x00;
}

  //初始化系统中断
void Init_SystemInterrupt(void)
{
        /* 设置定时器0中断IRQ */
        VICIntSelect = 0x00;                                /* 所有中断通道设置为IRQ中断                        */
        VICVectCntl0 = 0x20 | 0x05;                        /* 设置定时器1中断通道分配最高优先级        */
        VICVectAddr0 = (unsigned int)IRQ_Timer1;        /* 设置中断服务程序地址                                        */
        VICIntEnable = 1 << 0x05;                        /* 使能定时器1中断                                                */

}

有了上述支撑函数
主调函数很简单,如下:
//ID:伺服电机号 1 2
//vecter:角度参数  0-180
void ServerMotor(char ID,char vecter)
{
        switch(ID)
        {
                case 1:
                        uiPWM5_RatioSetValue = 94+ vecter;
                        break;
                case 2:
                        uiPWM6_RatioSetValue = 94+ vecter;
                        break;
        }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:以VS1003B和山景SOC芯片为背景,倾心研制数字化语音录放产品. 排忧邮箱:xg_2004_sy@126.com 得意之作是做了个AVR高压编程器,用起来爽歪歪, 串口MP3录放音模块,全面进入数字录放音时代

284

主题

6411

帖子

16

粉丝