关于1602液晶显示问题 求助下~在线等谢谢了

2019-03-24 18:00发布

做一个基于单片机的汽车超速报警系统,在做液晶显示的时候总是显示不了 无奈之下请教下大家帮帮忙 ,液晶屏有亮度但是没有显示,proteus仿真有结果,一开始以为是辉度问题开始调了好久还是不行。帮忙看看吧 谢谢各位大侠了




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

*********STC89C51**********

**********12MHz晶振********/



#include "reg51.h"



#define uint8 unsigned char

#define uint16 unsigned int

#define uchar unsigned char

#define uint unsigned int



#define TIMER0_HIGHT 0xEC        //设置定时器0工作方式1自动装载初值,定时5ms,Fosc=12MHZ

#define TIMER0_LOW   0x78



uint8 keyin = 1;        //按键输入






uint16 cnt10ms;        //10ms计数器





uint16 Pulsecnt;         



uint16 Pulsenum;         



uint16 PulseTime;        //10ms计数器

uint16 Pulse;        //10ms计数器



//--------------------------PWM

#define V_TH1 0xFF

#define V_TL1 0xF6

#define V_TMOD 0x01

unsigned char SETSPEED=150;

unsigned char ZKB1;

unsigned char click=0;

void Init_Extint(void);

void TimerInitProc();



void Init_System(void);

void Display(uint8 chose_dat, uint8 dat);

void ShowDisp(uint8 tPulsenum, uint8 tPulsecnt, uint8 tcnt1s);

void DelayMs(uint8 Ms);

uint8 Pulse_FLAG=0;



#define LCD_Data P0           //LCD的数据口

sbit    LCD_BF=LCD_Data^7;    //LCD忙信号位

sbit    LCD_RS=P2^5;

sbit    LCD_RW=P2^6;

sbit    LCD_EN=P2^7;

sbit    MOTOR_EN=P2^3;//电机

sbit    BP_EN=P3^5;//喇叭

sbit    red_EN=P1^3;//喇叭



sbit   SPEEDADD=P1^0;

sbit   SPEEDDEC=P1^1;

sbit   K1=P2^0;

sbit   K2=P2^1;

sbit   K3=P2^2;



#define LCD_GO_HOME               0x02         //AC=0,光标、画面回HOME位



//输入方式设置

#define LCD_AC_AUTO_INCREMENT     0x06         //数据读、写操作后,AC自动增一

#define LCD_AC_AUTO_DECREASE      0x04         //数据读、写操作后,AC自动减一

#define LCD_MOVE_ENABLE           0x05         //数据读、写操作,画面平移

#define LCD_MOVE_DISENABLE        0x04         //数据读、写操作,画面不动



//设置显示、光标及闪烁开、关

#define LCD_DISPLAY_ON            0x0C         //显示开

#define LCD_DISPLAY_OFF           0x08         //显示关

#define LCD_CURSOR_ON             0x0A         //光标显示

#define LCD_CURSOR_OFF            0x08         //光标不显示

#define LCD_CURSOR_BLINK_ON       0x09         //光标闪烁

#define LCD_CURSOR_BLINK_OFF      0x08         //光标不闪烁



//光标、画面移动,不影响DDRAM

#define LCD_LEFT_MOVE             0x18         //LCD显示左移一位

#define LCD_RIGHT_MOVE            0x1C         //LCD显示右移一位

#define LCD_CURSOR_LEFT_MOVE      0x10         //光标左移一位

#define LCD_CURSOR_RIGHT_MOVE     0x14         //光标右移一位



//工作方式设置

#define LCD_DISPLAY_DOUBLE_LINE   0x38         //两行显示

#define LCD_DISPLAY_SINGLE_LINE   0x30         //单行显示

/*定义子程序*/

void LCD_ClrAll(void);              //清屏

void Judge_LCD_busy(void);           //检测是否忙碌

void LCD_Write(uchar WriteData);     //写控制字

void LCD_write_data(uchar LCD_data); //写数据显示

void LCD_cursor(uchar x);    //光标起始地址

void LCD_printc(unsigned char lcd_data) ;  //输出一个字符

void LCD_prints(unsigned char *lcd_string);//输出字符串





/*LCD1602忙碌判断子程序*/

void Judge_LCD_busy(void)   //判断LCD1602是否忙状态

{

while(1)

  {

   LCD_EN=0;

   LCD_RS=0;

   LCD_RW=1;

   LCD_Data=0xff;

   LCD_EN=1;   //EN 是 1—0 使能

   if(!LCD_BF)break; //LCD_BF=1表示忙碌,需要等待。

  }

   LCD_EN=0;

}

/******LCD清屏***************/

void LCD_ClrAll(void)

{



Judge_LCD_busy();   //判断是否忙碌

LCD_RS=0;

LCD_RW=0;

LCD_Data=0x01;

LCD_EN=1;

LCD_EN=0;



}

/*******LCD写数据定义各种模式*********/

void LCD_Write(uchar WriteData)   //写指令到LCD

{

Judge_LCD_busy();

LCD_RS=0;

LCD_RW=0;



LCD_Data=WriteData; //把WriteData的数据送到数据口

LCD_EN=1;

LCD_EN=0;

}

/********LCD显示数据***********/

void LCD_write_data(uchar LCD_data)      //输出一个字节数据到LCD

{

Judge_LCD_busy();

LCD_RS=1;

LCD_RW=0;



LCD_Data=LCD_data;

LCD_EN=1;

LCD_EN=0;

}

/****光标位置的确定***/

void LCD_cursor(uchar x)            //LCD光标定位到x处

{

LCD_Write(0x80+x);                       //第一行地址是0x80



}

/*输出一个字符*/

void LCD_printc(unsigned char lcd_data)

{

LCD_write_data(lcd_data);

}



/*输出字符串*/

void LCD_prints(unsigned char *lcd_string)

{

unsigned char i=0;

while(lcd_string!=0x00)

  {

   LCD_write_data(lcd_string);

   i++;

  }

}



/*初始化程序*/

void LCD_initial(void)                        //初始化LCD

{

LCD_Write(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);

LCD_Write(LCD_DISPLAY_ON|LCD_CURSOR_OFF);

LCD_Write(LCD_DISPLAY_DOUBLE_LINE);

LCD_ClrAll();

}





void  Value_to_ASCII2(unsigned int value,uchar add)

{

    unsigned char temp[] = "00";





    temp[0] = value/10 + 0x30;

    value = value%10;

    temp[1] = value + 0x30;  



    LCD_cursor(add);   //光标起始地址 ,第一行地址是0x00~0x0F,第二行地址是0x40~0x4f

    LCD_prints(temp);

}





void  Value_to_ASCII(unsigned int value,uchar add)

{

    unsigned char temp[] = "000KM/H";





    temp[0] = value/100 + 0x30;

    value = value%100;

    temp[1] = value/10 + 0x30;

    value = value%10;

    temp[2] = value + 0x30;  



    LCD_cursor(add);   //光标起始地址 ,第一行地址是0x00~0x0F,第二行地址是0x40~0x4f

    LCD_prints(temp);

}

void  Value_to_ASCII3(unsigned int value,uchar add)

{

    unsigned char temp[] = "SET:000KM/H";





    temp[4] = value/100 + 0x30;

    value = value%100;

    temp[5] = value/10 + 0x30;

    value = value%10;

    temp[6] = value + 0x30;  



    LCD_cursor(add);   //光标起始地址 ,第一行地址是0x00~0x0F,第二行地址是0x40~0x4f

    LCD_prints(temp);

}

//--------------------主程序--------------------------------

void main()

{

    MOTOR_EN=0;

    BP_EN=1;ZKB1=0;

    Init_System();        //初始化

    LCD_initial();

       





    LCD_cursor(0x00);//写地址





    LCD_prints("CAR:");//写内容



    Value_to_ASCII(Pulsenum,0X04);

     Value_to_ASCII2(ZKB1,0X4c);

    Value_to_ASCII3(SETSPEED,0X40);

        while(1)

        {



//按键处理

if(SPEEDADD==0){//加速

  DelayMs(1);

   if(SPEEDADD==0){





          if(SETSPEED<250)SETSPEED=SETSPEED+10;

              Value_to_ASCII3(SETSPEED,0X40);

       while(SPEEDADD==0){}

}



}

if(SPEEDDEC==0){//减速

  DelayMs(1);

   if(SPEEDDEC==0){



         if(SETSPEED>10)SETSPEED=SETSPEED-10;

              Value_to_ASCII3(SETSPEED,0X40);  



       while(SPEEDDEC==0){}

}



}   

if(K1==0){//设定超速报警速度

  DelayMs(1);

   if(K1==0){



           if(ZKB1)ZKB1--;

              Value_to_ASCII2(ZKB1,0X4c);



       while(K1==0){}

}



}   

if(K2==0){//设定超速报警速度

  DelayMs(1);

   if(K2==0){

   if(ZKB1<50)ZKB1++;

            Value_to_ASCII2(ZKB1,0X4c);





       while(K2==0){}

}



}   

if(K3==0){//设定超速报警速度

  DelayMs(1);

   if(K3==0){



           ZKB1=0;

           Value_to_ASCII2(ZKB1,0X4c);

       while(K3==0){}

}



}  









       if(Pulse_FLAG==1){



           Pulse_FLAG=0;



           Value_to_ASCII(Pulsenum,0X04);

   if(Pulsenum>SETSPEED){BP_EN=0;red_EN=0;







  }else{BP_EN=1;red_EN=1;}



          }



       

        }

}

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

* 函 数 名: Exti0_interrupt

* 函数功能: /INT0引脚下降沿进入中断

* 入口参数: 无

* 返    回: 无

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

void Ext0_interrupt(void) interrupt 0

{





    Pulsecnt++;        //来一次中断计数器加1



       

}

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

函数功能:定时器/计数器0中断处理

入口参数:null

返    回:null

备    注:null

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

void Timer0IntProc() interrupt 1

{

        TH0 = TIMER0_HIGHT;        //设置定时器0高字节初值

        TL0 = TIMER0_LOW;        //设置定时器0低字节初值





        if(++cnt10ms == 200)        //1s计时到

        {

                cnt10ms = 0;

                Pulsenum = Pulsecnt;        //保存测得脉冲值

        Pulsecnt=0;

        Pulsenum=(Pulsenum*2)/3;  //2个脉冲为1圈



            Pulse_FLAG=1;

               

               

        }



}

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

函数功能:定时器/计数器1中断处理

入口参数:null

返    回:null

备    注:null

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

void Timer1IntProc() interrupt 3

{

        TH1 = V_TH1;        //设置定时器1高字节初值

        TL1 = V_TL1;        //设置定时器1低字节初值

    ++click;

    if(click>=50)click=0;

        if(click<=ZKB1){

         MOTOR_EN=1;



     }else{

        MOTOR_EN=0;



      }



}

/////////////////////////End of Timer0IntProc////////////////////////

void Init_Extint(void)

{

    IT0 = 1;    //外部中断1设置为下降沿触发

    IE0 = 0;    //标志位清0

    EX0 = 1;    //允许外部中断1

}

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

函数功能:定时器/计数器初始化

入口参数:null

返    回:null

备    注:null

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

void TimerInitProc()

{

        TMOD &= 0xF0;

        TMOD |= 0x11;                //设置定时器0,1,方式1:16位定时器

        TH0 = TIMER0_HIGHT;        //设置定时器0高字节初值

        TL0 = TIMER0_LOW;        //设置定时器0低字节初值

        TR0 = 1;                        //启动定时器0

    ET0 = 1;                        //开定时器0中断



        TH1 = V_TH1;        //设置定时器1高字节初值

        TL1 = V_TL1;        //设置定时器1低字节初值

        TR1 = 1;                        //启动定时器1

    ET1 = 1;                        //开定时器1中断

        EA = 1;                 //开总中断

}

/////////////////////////End of TimerInitProc////////////////////////

void initvar()

{



        cnt10ms = 0;



        Pulsecnt = 0;

        Pulsenum = 0;

}

void Init_System(void)

{

    Init_Extint();

    TimerInitProc();

        initvar();

}



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

函数功能:延时ms

入口参数:MS

返    回:null

备    注:null

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

void DelayMs(uint8 Ms)

{

    unsigned char i,j;

    do

    {

        for(i=5;i>0;i--)

        for(j=98;j>0;j--);

    }while(--Ms);

        //Test for 12M

}

///////////////////////////End of DelayMs////////////////////////////




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
huaiqiao
1楼-- · 2019-03-26 02:10
哎,这个帖子够长的,建议你下次发帖的时候把代码粘贴到txt文档中,1602其实最主要的还是在写命令,写数据,还有初始化上的。只要看基本按照时序走,应该是没有问题的。要不要我丢个成熟的文档给你呢。
song430
2楼-- · 2019-03-26 02:37
应该是你的上拉电阻接的不对
song430
3楼-- · 2019-03-26 05:25
 精彩回答 2  元偷偷看……

一周热门 更多>