微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 基于LPC2124的直流电机调速系统Proteus仿真 出错了

基于LPC2124的直流电机调速系统Proteus仿真 出错了

时间:10-02 整理:3721RD 点击:

基于LPC2124的直流电机调速系统Proteus仿真
电路图在最下面,预想功能是按下1、2、3、4按钮(从上到下)分别实现电机的加速、减速、制动、反转功能,结果一个功能都实现不了,代码复制出来了,求大神指点

/******************************************************************************

*File: Main.c

*功能: 使用PWM6输出PWM信号,通过KEY1,KEY2,KEY3控制电机转速,KEY1按一次加速10r/min,KEY2按一下减速10r/min,KEY3按一下制动,KEY4按一下反转

******************************************************************************/

#include "LPC21xx.h"

typedef  unsigned int uint32;

typedef int int32;

#define pwmdata 240000         /*PWM周期*/

#define f0 1000000             /*计数器频率*/

#define Z 60                   /*电机每转一圈产生Z个脉冲*/

#define kp 0.1                 /*PI调节器比例系数*/

#define ki 0                   /*PI调节器积分系数*/

#define KEY  0x0b800000       /*P0.23,P0.24,P0.25,P0.27引脚连有按键*/

#define KEY1 0x00800000       /*P0.23引脚连接KEY1*/

#define KEY2 0x01000000       /*P0.24引脚连接KEY2*/

#define KEY3 0x02000000       /*P0.25引脚连接KEY3*/

#define KEY4 0x08000000       /*P0.27引脚连接KEY4*/

uint32 t1=0,t2=0,i=0;

uint32 flag=0;                /*制动标志,flag=1转速接近0*/

uint32 fv=0;                   /*正反转标志,fv=0正转,fv=1反转*/

int32 nu=0,n=0;                /*nu给定转速,n检测转速*/

__irq void IRQ_T0(void)

{   

   t2=T0CR2;                   //读取捕获寄存器

   T0CR2=0;                    //捕获寄存器清零

  if(t1<t2) n=1.236*60*f0/(Z*(t2-t1));         //T法测速

   elseif(t1>t2) n=1.236*60*f0/(Z*(t2-t1+f0)); //1.236为修正系数

   t1=t2;

   T0IR=0x40;         //清除捕捉0中断标志(向6位写1)                   

  VICVectAddr=0x00;   //中断结束

}

__irq void IRQ_EINT0(void)  

{

  uint32 i;

IOCLR0=0x00000001;

for(i=0;i<50;i++);                     //延时去抖

if((IOPIN0&KEY)!=KEY)

   if((IOPIN0&KEY1)==0)                  //KEY1按键按下,加速

       {

         flag=0;

         if(nu>=0) nu+=10;

         else nu-=10;

        }

    elseif((IOPIN0&KEY2)==0)             //KEY2按键按下,减速

           {

              if(nu>10) nu-=10;

              else if(nu<-10) nu+=10;

                   else nu=0;

            }

        else if((IOPIN0&KEY3)==0) {nu=0;}      //KEY3按键按下,制动

              else if((IOPIN0&KEY4)==0)         //KEY4按键按下,反转

                   {

                     if(fv==0) fv=1;

                     else fv=0;

                     nu=-nu;

                   }

while((IOPIN0&KEY)!=KEY);            //等待按键放开  

  {EXTINT=0x01; }     //清楚EINT0中断标志

VICVectAddr=0x00;   //中断结束

}

void TargetInit(void)

{

  /*管脚配置初始化*/

PINSEL0=0x00080000;                     //设置PWM6连接到P0.9引脚

PINSEL1=0x02000000;                    //P0.28捕捉

IODIR0=0x000002c0;                      //P0.6,P0.7,P0.9输出

  /*PWM初始化*/

PWMPR=0x00;                     //不分频,计数频率为Fpclk

PWMMCR=0x02;                    //设置PWMMR0匹配时复位PWMTC

PWMMR0=pwmdata;                 //设置PWM周期

PWMMR6=120000;                  //设置PWM占空比

PWMLER=0x40;                     //PWMMR6锁存

PWMPCR=0x4000;                  //允许PWM6输出,单边PWM

PWMTCR=0x09;                    //启动定时器,PWM使能

  /*EINT0中断初始化*/

PINSEL1=(PINSEL1&0xfffffffc)|0x01;  //选择P0.16为EINT0

EXTMODE=EXTMODE&0x0e;                //电平触发

EXTPOLAR=EXTPOLAR&0x0e;             //低电平中断

  /*定时器0初始化*/

  T0TC=0;                       //清除 T0计数值

  T0PR=23;                      //24分频(24MHZ分频后变成1MHZ)

T0MR0=1000000;                //计数匹配值

T0CCR=0x0140;                 //第七位写1进入捕捉模式 (上升沿捕捉,进入中断)

T0MCR=0x00000002;             //匹配后复位T0(不停止)

T0TCR=0x00000002;             //复位计数器

  T0TCR=0x00000001;            //计数器使能

  

  /*中断向量初始化*/

VICIntSelect=0x00000000;            //中断向量寄存器选择0,IRQ中断

VICVectCntl0=0x20|4;                //定时器0中断分配为向量IRQ通道0

VICVectAddr0=(uint32)IRQ_T0;       //向量IRQ通道0的中断服务程序地址为IRQ_T0

VICVectCntl1=0x20|14;               //EINT0中断分配为向量IRQ通道1

  VICVectAddr1=(uint32)IRQ_EINT0;//向量IRQ通道1的中断服务程序地址为IRQ_EINT0

VICIntEnable=(1<<4)|(1<<14);        //定时器0和EINT0中断使能

EXTINT=0x07;                        //清楚外部中断标志

}      

/******************************************************************************

*名称: main()

*功能: 使用PWM6输出占空比可调的PWM波形,控制直流电机

******************************************************************************/

int main(void)

{  

  floatPI=0,sum=0;

  int32 es=0;

TargetInit();

  while(1)

  {  

    if(nu==0)                          //制动

      if(fv==0)                        //如果正转

        if(n>50) PI=-0.8;

         else if(n>20) PI=-0.5;

              else if(n>10) PI=-0.3;

                   else if(n>3) PI=-0.1;

                         else {PI=0;flag=1;}

      else                             //如果反转

        if(n>50) PI=0.8;

         else if(n>20) PI=0.5;

              else if(n>10) PI=0.3;

                   else if(n>3) PI=0.1;

                         else {PI=0;flag=1;}

     else

        {

         if(nu>0) es=nu-n;

         else    es=nu+n;

         sum=sum+es;

         PI=kp*es+ki*sum;

        if(PI>0.8)PI=0.8;               //过饱和保护

        if(PI<-0.8) PI=-0.8;

        }

     if(flag==1)

       {IOSET0=0x000000c0;}

     else

       if(PI>0)

       {

      IOSET0=0x00000040;                   //设置P0.6高电平,P0.7低电平

      IOCLR0=0x00000080;                   //正转

      PWMMR0=pwmdata;

      PWMMR6=pwmdata*PI;                  //设置PWM占空比

      PWMLER=0x40;                        //PWMMR6锁存,更新PWM占空比

       }

       else if(PI<0)

       {

      IOCLR0=0x00000040;                   //设置P0.6低电平,P0.7高电平

      IOSET0=0x00000080;                   //反转

      PWMMR0=pwmdata;

      PWMMR6=pwmdata*(-PI);                //设置PWM占空比

      PWMLER=0x40;                          //PWMMR6锁存,更新PWM占空比

       }      

  }

//return(0);

}

基于LPC2124的直流电机调速系统Proteus仿真


可以先把硬件隔离开测试
比如制动if(nu==0)                    
全局变量直接定义nu=1;
while循环里面最好加一段延时

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

网站地图

Top