#include
#include
#define LCD P0
#define out_max 10000
#define out_min -10000
***it EN=P2^2;
***it RW=P2^1;
***it RS=P2^0;
***it PSB=P2^3;
***it RST=P2^4;
***it CS1=P2^5;
***it CS2=P2^6;
***it BUSY=P0^0;
***it PWM=P3^0;
***it DIR=P3^1;
***it LED0=P3^4;
***it LED1=P3^5;
***it LED2=P3^6;
***it LED3=P3^7;
int KeyH=0;
int KeyL=0;
int Key=0;
int PWML=0;
int KP=120;
int KI=50;
int KD=30;
int count=0;
int Key_flag=0;
int flag=0;
int last_out=0;
int setspeed=50;
int speed=0;
int Now_speed[3]={0};
int num,speed,j;
unsigned char highh,highl,lowh,lowl;
int high=10000;
void delay(unsigned int a);
unsigned char code table[16]= //定义16个按键,S3-S18的键值
{0xd7,0xeb,0xdb,0xbb,0xed,0xdd,0xbd,0xee,0xde,0xbe,0x7e,0x7d,0x7b,0xe7,0xb7,0x77};
unsigned char code number[][6]=
{
{ 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
{ 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
{ 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
{ 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3
{ 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4
{ 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
{ 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
{ 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
{ 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
{ 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
{ 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
};
//设
unsigned char code she[]={0x10,0x11,0xF2,0x20,0x10,0x6F,0xA1,0x21,0xAF,0x68,0x08,0x00,0x00,0x00,0x03,0x05,0x04,0x04,0x02,0x01,0x02,0x04,0x04,0x00};
//当
unsigned char code dang[]={0x10,0x92,0x94,0x90,0x90,0x9F,0x90,0x98,0x94,0xF2,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x07,0x00,0x00};
//前
unsigned char code qian[]={0x04,0xF4,0x54,0x55,0xF6,0x04,0x06,0xF5,0x04,0xF6,0x04,0x00,0x00,0x07,0x01,0x05,0x07,0x00,0x00,0x05,0x04,0x07,0x00,0x00};
//定
unsigned char code ding[]={0x04,0x16,0xD2,0x12,0x12,0xF3,0x92,0x92,0x92,0x92,0x06,0x00,0x04,0x02,0x01,0x01,0x02,0x03,0x04,0x04,0x04,0x04,0x04,0x00};
//速
unsigned char code su[]={0x11,0xF6,0x00,0x02,0x3A,0xAA,0xFF,0x6A,0xAA,0x3A,0x02,0x00,0x06,0x01,0x02,0x05,0x05,0x04,0x07,0x04,0x04,0x05,0x04,0x00};
//度
unsigned char code du[]={0x00,0xFE,0x0A,0x8A,0xBE,0xAA,0xAB,0xAA,0xBE,0x0A,0x0A,0x00,0x06,0x01,0x04,0x04,0x04,0x03,0x02,0x03,0x04,0x04,0x04,0x00};
//各
unsigned char code ge[]={0x90,0x88,0x44,0xC7,0xAA,0x92,0xAA,0xA6,0xC2,0x40,0x40,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x00,0x00,0x00};
//参
unsigned char code can[]={0x90,0x54,0xB4,0x96,0x5D,0x34,0x94,0x35,0x56,0x94,0x90,0x00,0x00,0x04,0x04,0x04,0x05,0x05,0x02,0x02,0x01,0x00,0x00,0x00};
//数
unsigned char code shu[]={0xA5,0x96,0xCC,0xBF,0x96,0xA5,0x18,0x67,0x84,0x7C,0x04,0x00,0x04,0x05,0x02,0x02,0x03,0x04,0x04,0x02,0x01,0x02,0x04,0x00};
//显
unsigned char code xian[]={0x00,0x40,0x9F,0x15,0xD5,0x15,0xD5,0x15,0x1F,0xC0,0x00,0x00,0x04,0x04,0x05,0x04,0x07,0x04,0x07,0x06,0x05,0x04,0x04,0x00};
//示
unsigned char code shi[]={0x10,0x12,0x92,0x52,0x12,0xF2,0x12,0x12,0x53,0x92,0x10,0x00,0x02,0x01,0x00,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x03,0x00};
//如
unsigned char code ru[]={0x04,0xE4,0x9F,0x04,0xFC,0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x04,0x04,0x02,0x01,0x02,0x00,0x03,0x02,0x02,0x02,0x03,0x00};
//下
unsigned char code xia[]={0x02,0x02,0x02,0x02,0x02,0xFE,0x12,0x12,0x22,0x43,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
//许
unsigned char code xu[]={0x20,0x24,0x28,0xE0,0x40,0x60,0x5E,0x48,0xF8,0x48,0x48,0x40,0x00,0x00,0x00,0x1F,0x08,0x00,0x00,0x00,0x7F,0x00,0x00,0x00};
//明
unsigned char code ming[]={0xF8,0x88,0x88,0x88,0xF8,0x00,0xFE,0x12,0x12,0x12,0x12,0xFE,0x0F,0x08,0x08,0x08,0x4F,0x20,0x1F,0x01,0x01,0x01,0x21,0x7F};
//康
unsigned char code kang[]={0x00,0x00,0xFC,0x44,0x55,0x56,0xFC,0x54,0x54,0xF4,0x44,0x40,0x20,0x10,0x0F,0x20,0x15,0x29,0x7F,0x09,0x15,0x21,0x20,0x00};
//P
unsigned char code Kkp[]={0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00};
//I
unsigned char code Kki[]={0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00};
//D
unsigned char code Kkd[]={0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00};
void checkbusy() //检查忙,若忙则必须等待
{
EN=1;
RW=1;
RS=0;
LCD=0XFF;
if(BUSY);
}
void writecode(unsigned char dat) //写命令
{
checkbusy();
EN=1;
RW=0;
RS=0;
LCD=dat;
EN=1;
EN=0;
}
void writedata(unsigned char dat) //写数据
{
checkbusy();
EN=1;
RW=0;
RS=1;
LCD=dat;
EN=1;
EN=0;
}
void LCD_set(unsigned char page,unsigned char column) //设定起始行 页 列
{
column=column&0x3f; //12864最大为64列
writecode(page+0xb8); //+184
writecode(column+0x40); //+64
}
void LCD_clear() //清屏
{
unsigned char i,j;
CS2=0;
CS1=0;
for(i=0;i<8;i++)
{
for(j=0;j<64;j++)
{
LCD_set(i,j);
writedata(0);
}
}
}
void LCD_write_char(unsigned char screen,unsigned char page,unsigned char line,unsigned char *hz)
{
unsigned char i,j;
if(screen==0)
{
CS1=1;
CS2=0; //left
LCD_set(page,line);
for(i=0;i<8;i++)
writedata(hz[i]);
LCD_set(page+1,line);
for(j=0;j<8;j++)
writedata(hz[j+8]);
}
if(screen==1)
{
CS1=0; //right
CS2=1;
LCD_set(page,line);
for(i=0;i<8;i++)
writedata(hz[i]);
LCD_set(page+1,line);
for(j=0;j<8;j++)
writedata(hz[j+8]);
}
}
void LCD_write_var(unsigned char screen,unsigned char page,unsigned char line,int num) // 显示单个数字
{
unsigned char i;
if(screen==0)
{
CS1=1;
CS2=0; //left
LCD_set(page,line);
for(i=0;i<6;i++)
writedata(number[num][i]);
}
if(screen==1)
{
CS1=0; //right
CS2=1;
LCD_set(page,line);
for(i=0;i<6;i++)
writedata(number[num][i]);
}
}
void LCD_write_num(unsigned char screen,unsigned char page,unsigned char line,int dat) //显示三位数
{
unsigned char i,tab[3]={0};
tab[0]=dat/100;
tab[1]=dat%100/10;
tab[2]=dat%100%10;
for(i=0;i<3;i++)
LCD_write_var(screen,page,line+i*6,tab[i]);
}
void LCD_write_chinese(unsigned char screen,unsigned char page,unsigned char line,unsigned char *hz) //显示汉字 屏区 页 列 字库
{
unsigned char i,j;
if(screen==0)
{
CS1=1;
CS2=0; //left
LCD_set(page,line);
for(i=0;i<12;i++)
writedata(hz[i]);
LCD_set(page+1,line);
for(j=0;j<12;j++)
writedata(hz[j+12]);
}
if(screen==1)
{
CS1=0; //right
CS2=1;
LCD_set(page,line);
for(i=0;i<12;i++)
writedata(hz[i]);
LCD_set(page+1,line);
for(j=0;j<12;j++)
writedata(hz[j+12]);
}
}
void Display1(void)
{
int i;
for(i=0;i<10;i++)
delay(50);
}
void Display2(void) //汉子、字符的显示位置
{
LCD_write_chinese(0,0,0,ge);delay(10);
LCD_write_chinese(0,0,16,can);delay(10);
LCD_write_chinese(0,0,32,shu);delay(10);
LCD_write_chinese(0,0,48,xian);delay(10);
LCD_write_chinese(1,0,0,shi);delay(10);
LCD_write_chinese(1,0,16,ru);delay(10);
LCD_write_chinese(1,0,32,xia);delay(10);
LCD_write_chinese(0,2,0,she);delay(10);
LCD_write_chinese(0,2,14,ding);delay(10);
LCD_write_var(0,2,26,10);delay(10);
LCD_write_chinese(0,4,0,dang);delay(10);
LCD_write_chinese(0,4,14,qian);delay(10);
LCD_write_var(0,4,26,10);delay(10);
LCD_write_char(0,6,14,Kkp);delay(10);
LCD_write_var(0,6,26,10);delay(10);
LCD_write_char(1,2,20,Kki);delay(10);
LCD_write_var(1,2,30,10);delay(10);
LCD_write_char(1,4,20,Kkd);delay(10);
LCD_write_var(1,4,30,10);delay(10);
LCD_write_chinese(1,6,16,xu);delay(10);
LCD_write_chinese(1,6,32,ming);delay(10);
LCD_write_chinese(1,6,48,kang);delay(10);
}
void LCD_init()
{
writecode(0X3f);//显示开关关
writecode(0XC0);//修改显示起始行
writecode(0XB8);//修改页地址,x地址
writecode(0X40);//修改列地址,y地址
}
void delay(unsigned int a)
{
unsigned int i,j;
for(i=0;i
for(j=0;j<200;j++);
}
void Scankey(void) //控制器P1口对键盘扫描
{
int i,t;
P1=P1&0xf0; // 行扫描
t=P1&0xf0; //
if(t!=0xf0) //
{
KeyH=t&0xf0; //
P1=0xff; //
delay(1); //
P1&=0x0f; // 列扫描
t=P1&0x0f; //
if(t!=0x0f) //
{
KeyL=t;
Key=KeyH|KeyL;
for(i=0;i<16;i++)
{
if(table[i]==Key)
Key=i;
}
}
}
P1=0xff;
}
void delay1s(void)
{
unsigned char a,b,c;
for(c=100;c>0;c--)
for(b=150;b>0;b--)
for(a=16;a>0;a--);
}
void Keychuli(void) //按键处理
{
unsigned int t=30000;
int n1=1000;
int n2=1000;
LED0=0;
LED1=0;
LED2=0;
LED3=0; //
Key_flag=1;
Scankey();
if(Key==10) // 单击10(/)按键 设定速度
{
LED0=1; // D1灯亮,进入设置
while(!(n1==0))
{
Scankey();
if(Key==15) // 单击15(+)按键,增大设定值
{
delay1s();
while(!(n2==0))
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;} // 单击14(=)按键, 确定参数
else if(Key==13) {setspeed=0;Key=0;} // 单击13(ON)按键, 参数清零
else if(Key>9) Key=0; // 加大的系数范围0-9
setspeed=setspeed+Key; //设定的速度+增加的系数
Key=0;
if(setspeed<0) setspeed=0;
if(setspeed>999) setspeed=999;
LCD_write_num(0,2,34,setspeed); //设定速度的显示位置
}
}
else if(Key==12&&setspeed!=0) // 单击12(-)按键,减小设定值
{
delay1s();
while(n2--)
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;} // 单击14(=)按键, 确定参数
else if(Key==13) {setspeed=0;Key=0;} // 单击13(ON)按键, 参数清零
else if(Key>9) Key=0; // 减小的系数范围0-9
setspeed=setspeed-Key; //设定的速度-增加的系数
Key=0;
if(setspeed<0) setspeed=0;
if(setspeed>999) setspeed=999;
LCD_write_num(0,2,34,setspeed); //设定速度的显示位置
}
}
LCD_write_num(0,2,34,setspeed); //设定速度的显示位置
}
}
else if(Key==11) //单击11(*)按键,设置PID
{
delay(200); //延时
LED1=1;
while(t--) { Scankey();}
LED1=0;
delay(200);
if(Key!=11) //单击11(*)按键,设置P
{
LED1=1; //D2灯亮,进入P设置
while(!(n1==0))
{
Scankey();
if(Key==15) // 单击15(+)按键,增大设定值
{
delay1s();
while(!(n2==0))
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;} // 单击14(=)按键, 确定参数
else if(Key==13) {KP=0;Key=0;} // 单击13(ON)按键, 参数清零
else if(Key>9) Key=0;
KP=KP+Key;
Key=0;
if(KP<0) KP=0;
if(KP>999) KP=999;
LCD_write_num(0,6,34,KP);
}
}
else if(Key==12&&KP!=0) // -
{
delay1s();
while(n2--)
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;}
else if(Key==13) {KP=0;Key=0;} //参数清零
else if(Key>9) Key=0;
KP=KP-Key;
Key=0;
if(KP<0) KP=0;
if(KP>999) KP=999;
LCD_write_num(0,6,34,KP);
}
}
LCD_write_num(0,6,34,KP);
}
}
else if(Key==11)
{
delay(200);
LED2=1;
while(t--) { Scankey();}
LED2=0;
Scankey();
delay(200);
if(Key!=11) //单击11(*)按键,设置I
{
LED2=1; //D3灯亮时,进入I设置
while(!(n1==0))
{
Scankey();
if(Key==15) // +
{
delay1s();
while(!(n2==0))
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;}
else if(Key==13) {KI=0;Key=0;} //参数清零
else if(Key>9) Key=0;
KI=KI+Key;
Key=0;
if(KI<0) KI=0;
if(KI>999) KI=999;
LCD_write_num(1,2,38,KI);
}
}
else if(Key==12&&KI!=0) // -
{
delay1s();
while(n2--)
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;}
else if(Key==13) {KI=0;Key=0;} //参数清零
else if(Key>9) Key=0;
KI=KI-Key;
Key=0;
if(KI<0) KI=0;
if(KI>999) KI=999;
LCD_write_num(1,2,38,KI);
}
}
LCD_write_num(1,2,38,KI);
}
}
else if(Key==11) //单击11(*)按键,设置D
{
LED3=1; //D4灯亮时,进入D设置
while(!(n1==0))
{
Scankey();
if(Key==15) // +
{
delay1s();
while(!(n2==0))
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;}
else if(Key==13) {KD=0;Key=0;} //参数清零
else if(Key>9) Key=0;
KD=KD+Key;
Key=0;
if(KD<0) KD=0;
if(KD>999) KD=999;
LCD_write_num(1,4,38,KD);
}
}
else if(Key==12&&KD!=0) // -
{
delay1s();
while(n2--)
{
Scankey();
delay(150);
if(Key==14) {n2=0;n1=0;Key=0;}
else if(Key==13) {KD=0;Key=0;} //参数清零
else if(Key>9) Key=0;
KD=KD-Key;
Key=0;
if(KD<0) KD=0;
if(KD>999) KD=999;
LCD_write_num(1,4,38,KD);
}
}
LCD_write_num(1,4,38,KD); //D的显示位置
}
}
}
}
}
void PWMset(int pwm) //PWM设置
{
if(pwm>=0){DIR=0;PWML=pwm;}
if(pwm<0){DIR=1;PWML=10000+pwm;}
}
/********电机PID控制**********/
void Motor_control(void)
{
int PID=0;
int P=0;
int I=0;
int D=0;
int out=0;
Now_speed[2] = Now_speed[1];
Now_speed[1] = Now_speed[0];
Now_speed[0] = setspeed-speed;
P = KP*(Now_speed[0]-Now_speed[1]); //PID计算
I = KI* Now_speed[0];
D = KD*(Now_speed[0]-2*Now_speed[1]+Now_speed[2]);
PID = P+I+D;
out=last_out+PID;
if(out>out_max) out=out_max; //输出值限幅
if(out
PWMset(out);
last_out=out; //输出给寄存器,改变PWM占空比
}
/**********计数器0初始化**********/
void timer0_init(void)
{
highh=(unsigned char)((16384-high)/256+192);
highl=(unsigned char)((16384-high)%256);
lowh=(unsigned char)(high/256+200);
lowl=(unsigned char)(high%256);
TMOD=0x01;
TH0=highh;
TL0=highl;
IT0=1;
EX0=1;
TR0=1;
ET0=1;
EA=1;
}
void Getspeed(void) interrupt 0 //外部中断脉冲计数
{
num++;
IE0=0;
}
void Timer(void) interrupt 1
{
if(flag==0)
{
TH0=(unsigned char)((16384-PWML)/256+192);;
TL0=(unsigned char)((16384-PWML)%256);;
PWM=1;
flag=1; //
}
else
{
TH0=(unsigned char)(PWML/256+200);
TL0=(unsigned char)(PWML%256);;
PWM=0;
flag=0; //
}
if(j==20)
{
speed=num;
if(Key_flag==0)
Motor_control();
num=0;
j=0;
}
j++;
TF0=0;
}
void main(void)
{
int t=1;
LCD_init();
timer0_init();
LCD_clear();
Display1();
delay(200);
PWM=1;
DIR=0;
LCD_clear();
while(1)
{
if(t==1)
{
Display2();
t=0;
}
Keychuli();
Key_flag=0;
/*****及时更新数据显示***/
LCD_write_num(0,2,34,setspeed);
LCD_write_num(0,4,34,speed);
LCD_write_num(0,6,34,KP);
LCD_write_num(1,2,38,KI);
LCD_write_num(1,4,38,KD);
}
}
|