pi反馈调速potues仿真
时间:10-02
整理:3721RD
点击:
#include<reg52.h>#include<math.h>#include<intrins.h>#include <string.h>#define uint unsigned int#define uchar unsigned char #define speed1 100sbit PWM=P2^5; //控制线sbit A1=P2^6;sbit A2=P2^7; //L298控制线uint high=30; //占空比uchar period=100; //脉冲周期uchar time=0; // pwm计数标志uchar c1=0; //速度计算标志;uint c2=0;//速度时间计算uint cnt ; //转速uchar code num[9]={"0000r/min"};//显示位uchar code PXA1[4]={"down"};//显示位uchar code PXA2[4]={" up"};//显示位uchar code zhuansu_buff[10]={'0','1','2','3','4','5','6','7','8','9'} ;uchar PO[4];//显示位uchar u_buff[3] ;//显示占空 uint x1; /*按键扫描 */sbit strat_key=P2^0;sbit left_key=P2^1;sbit right_key=P2^2;//按键接线/* LCD模块*/sbit en=P1^2;sbit rs=P1^0;sbit rw=P1^1;
void delay(uint x) //延时{ uint i,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } void write_com(uchar com) //写指令{ rs=0; rw=0; en=1; P0=com; delay(5); en=0;} void write_date(uchar date) //写数据{ rs=1; rw=0; en=1; P0=date; delay(5); en=0; }
void init_display()
{ delay(15);
write_com(0x38);
delay(5);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
void LCD_xy(uchar y,uchar x) //Y=0,1(起始行)X=0~15(起始列)Z=想写字符的ASCII码
{
if(y) //是否显示在第二行(若在第一行Y=0,不进入IF语句,若在第二行,进入IF语句
{
x+=0x40; //第二行起始地址加上列数为字符显示地址
}
x+=0x80; //设置数据指针位置
write_com(x);
} void display_lcd_1(uchar y,uchar x,uchar A){ LCD_xy(y,x); write_date(A);
}
void display_lcd_text(uchar y,uchar x,uchar a,uchar *s){ uchar date1,i; LCD_xy(y,x); for(i=0;i<=a;i++) { LCD_xy(y,x+i); date1=*s; write_date(date1); s++; }} /* 占空修改*/ int pi; motor_rihgt(){ high=pi; //? 占空计算 if(high>=period) high=90; if (high<=0) high=35;}
/*PI调节模块*/int remin=0,num1=0,num2=0;int PI1_math(){ num1=speed1-cnt; //if(fabs(num1)<2) //误差阈值 //num1=30; //else remin=6*num1/100+2*(num1-num2)/10+remin; num2=num1; return (remin); }int PI2_math(){ }
speed_cov(){ if(c2>=10) //5s { TR0=0; cnt=TL0*3; //获得真实转速 TH0=0; TL0=0; TR0=1; c2=0; PO[0]=(cnt%10000)/1000; PO[1]=(cnt%1000)/100; PO[2]=(cnt%100)/10; PO[3]=cnt%10; display_lcd_1(0,2,zhuansu_buff[(PO[0])]); display_lcd_1(0,3,zhuansu_buff[(PO[1])]); display_lcd_1(0,4,zhuansu_buff[(PO[2])]); display_lcd_1(0,5,zhuansu_buff[(PO[3])]); delay(5); u_buff[0]=(high%1000/100); u_buff[1]=(high%100/10); u_buff[2]=high%10; display_lcd_1(1,1,zhuansu_buff[(u_buff[0])]); display_lcd_1(1,2,zhuansu_buff[(u_buff[1])]); display_lcd_1(1,3,zhuansu_buff[(u_buff[2])]); pi=PI1_math(); motor_rihgt(); } }
/* 定时计数初始化 cnt */void init_timer(){ IE=0x89; IP=0x08; TMOD=0x15; //方式2,T1定时,T0计数 TH1=(65536-500)/256 ; TL1=(65536-500)%256; //500us RCAP2H=(65536-50000)/256;//自动重载模式下,定时器2溢出时,RC2H、RC2L RCAP2L=(65536-50000)%256;//中的16位初始值重新装入定时器的TH2,TL2 TL0=0; TH0=0; EA=1; ET1=1; ET0=0; ET2=1;}
/* 外部中断0初始化 cnt */Outside_Init(){ IT0=1;EX0=1;}
/* 主函数*/ void main(){ P1=0xFF; P2=0xff; init_timer(); init_display(); Outside_Init() ; display_lcd_text(0,2,8,num); while(1) { while(!strat_key) { while(! left_key) {A1=0;A2=1;TR1=1;TR0=1;TR2=1;display_lcd_text(1,6,3,PXA1);delay(200);}
while(! right_key) {A1=1;A2=0;TR1=1;TR0=1;TR2=1;display_lcd_text(1,6,3,PXA2);delay(200) ;}
A1=1;A2=1;TR1=0;TR0=0; display_lcd_text(0,2,8,num); delay(20) ; display_lcd_text(1,6,3,"wait"); } }}
void timer1()interrupt 3{ EA=0; TR1=0;
time++; if(time<=high) //pwm脉冲 {PWM=1;} if(time>high) {PWM=0; } if(time==period) { time=0; } speed_cov(); TH1=(65536-500)/256 ; //0.5ms TL1=(65536-500)%256;
TR1=1; EA=1; }
void Outside(void) interrupt 0{ EX0=0; high=high+2; if(high>100) high=0; EX0=1;
}
void timer2() interrupt 5{ TF2=0; //置位TF2位,表示计数溢出,向CPU发送中断请求信号,必须由程序清零 c2++;}
void delay(uint x) //延时{ uint i,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } void write_com(uchar com) //写指令{ rs=0; rw=0; en=1; P0=com; delay(5); en=0;} void write_date(uchar date) //写数据{ rs=1; rw=0; en=1; P0=date; delay(5); en=0; }
void init_display()
{ delay(15);
write_com(0x38);
delay(5);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
void LCD_xy(uchar y,uchar x) //Y=0,1(起始行)X=0~15(起始列)Z=想写字符的ASCII码
{
if(y) //是否显示在第二行(若在第一行Y=0,不进入IF语句,若在第二行,进入IF语句
{
x+=0x40; //第二行起始地址加上列数为字符显示地址
}
x+=0x80; //设置数据指针位置
write_com(x);
} void display_lcd_1(uchar y,uchar x,uchar A){ LCD_xy(y,x); write_date(A);
}
void display_lcd_text(uchar y,uchar x,uchar a,uchar *s){ uchar date1,i; LCD_xy(y,x); for(i=0;i<=a;i++) { LCD_xy(y,x+i); date1=*s; write_date(date1); s++; }} /* 占空修改*/ int pi; motor_rihgt(){ high=pi; //? 占空计算 if(high>=period) high=90; if (high<=0) high=35;}
/*PI调节模块*/int remin=0,num1=0,num2=0;int PI1_math(){ num1=speed1-cnt; //if(fabs(num1)<2) //误差阈值 //num1=30; //else remin=6*num1/100+2*(num1-num2)/10+remin; num2=num1; return (remin); }int PI2_math(){ }
speed_cov(){ if(c2>=10) //5s { TR0=0; cnt=TL0*3; //获得真实转速 TH0=0; TL0=0; TR0=1; c2=0; PO[0]=(cnt%10000)/1000; PO[1]=(cnt%1000)/100; PO[2]=(cnt%100)/10; PO[3]=cnt%10; display_lcd_1(0,2,zhuansu_buff[(PO[0])]); display_lcd_1(0,3,zhuansu_buff[(PO[1])]); display_lcd_1(0,4,zhuansu_buff[(PO[2])]); display_lcd_1(0,5,zhuansu_buff[(PO[3])]); delay(5); u_buff[0]=(high%1000/100); u_buff[1]=(high%100/10); u_buff[2]=high%10; display_lcd_1(1,1,zhuansu_buff[(u_buff[0])]); display_lcd_1(1,2,zhuansu_buff[(u_buff[1])]); display_lcd_1(1,3,zhuansu_buff[(u_buff[2])]); pi=PI1_math(); motor_rihgt(); } }
/* 定时计数初始化 cnt */void init_timer(){ IE=0x89; IP=0x08; TMOD=0x15; //方式2,T1定时,T0计数 TH1=(65536-500)/256 ; TL1=(65536-500)%256; //500us RCAP2H=(65536-50000)/256;//自动重载模式下,定时器2溢出时,RC2H、RC2L RCAP2L=(65536-50000)%256;//中的16位初始值重新装入定时器的TH2,TL2 TL0=0; TH0=0; EA=1; ET1=1; ET0=0; ET2=1;}
/* 外部中断0初始化 cnt */Outside_Init(){ IT0=1;EX0=1;}
/* 主函数*/ void main(){ P1=0xFF; P2=0xff; init_timer(); init_display(); Outside_Init() ; display_lcd_text(0,2,8,num); while(1) { while(!strat_key) { while(! left_key) {A1=0;A2=1;TR1=1;TR0=1;TR2=1;display_lcd_text(1,6,3,PXA1);delay(200);}
while(! right_key) {A1=1;A2=0;TR1=1;TR0=1;TR2=1;display_lcd_text(1,6,3,PXA2);delay(200) ;}
A1=1;A2=1;TR1=0;TR0=0; display_lcd_text(0,2,8,num); delay(20) ; display_lcd_text(1,6,3,"wait"); } }}
void timer1()interrupt 3{ EA=0; TR1=0;
time++; if(time<=high) //pwm脉冲 {PWM=1;} if(time>high) {PWM=0; } if(time==period) { time=0; } speed_cov(); TH1=(65536-500)/256 ; //0.5ms TL1=(65536-500)%256;
TR1=1; EA=1; }
void Outside(void) interrupt 0{ EX0=0; high=high+2; if(high>100) high=0; EX0=1;
}
void timer2() interrupt 5{ TF2=0; //置位TF2位,表示计数溢出,向CPU发送中断请求信号,必须由程序清零 c2++;}