基于LPC2124的直流电机调速系统Proteus仿真 出错了
基于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循环里面最好加一段延时
