微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 仿真成功了,但是作实物不显示

仿真成功了,但是作实物不显示

时间:10-02 整理:3721RD 点击:
#include<reg52.h>
#include<math.h>
#define LCD P0
#define out_max 10000
#define out_min -10000
sbit EN=P2^2;
sbit RW=P2^1;
sbit RS=P2^0;
sbit PSB=P2^3;
sbit RST=P2^4;
sbit CS1=P2^5;
sbit CS2=P2^6;
sbit BUSY=P0^0;
sbit PWM=P3^0;
sbit DIR=P3^1;
sbit LED0=P3^4;
sbit LED1=P3^5;
sbit LED2=P3^6;
sbit 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<a;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<out_min) out=out_min;  //输出值限幅
        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);
        }
}

电路图


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

网站地图

Top