LCD1602做的乘法答题器显示乱码

2019-07-16 05:32发布

刚接触,不知道这是什么原因??貌似按钮和蜂鸣器都正常,就是显示不行。2行都只显示日文。
下面是程序。
#include < reg51.h >
#include < intrins.h >
bit  F_in=0,truer;
sbit LCD_RS = P2^0;            
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
sbit BEEP = P3^7;          //蜂鸣器驱动线
unsigned char  key_buf;            //显示缓存
unsigned char  temp;
unsigned char  key,key_num=0;                //键顺序
unsigned char code  cdis1[] = {" MULtiPLICATION "};
unsigned char code  cdis2[] = {" TABLE: 0*0=00  "};
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
unsigned char data testdata[] = {0x00,0x00,0x00,0x00};
unsigned char data in_data[] = {0x01,0x02};
unsigned char shift ;
/**********************************************************
延时子程序
**********************************************************/
void delay(unsigned int ms)
{
  unsigned char t;
   while(ms--)
   {
     for(t = 0; t < 120; t++);
   }
}
/*************************************************************/
/*                                                           */
/* 延时 x*0.14ms                                             */
/*                                                           */
/*************************************************************/
void delay0(unsigned char x)   
{
   unsigned char i;
   while(x--)
   {
     for (i = 0; i<13; i++) {}
   }
}
/*************************************************************/
/*                                                           */
/* 蜂鸣器响一声                                              */
/*                                                           */
/*************************************************************/
void beep()
{
  unsigned char i;
  for (i=0;i<180;i++)
   {
   delay0(6);
   BEEP=!BEEP;       //BEEP取反
   }
   BEEP=1;           //关闭蜂鸣器
   delay(250);       //延时     
}
/*************************************************************/
/*                                                           */
/*检查LCD忙状态                                              */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据  */
/*                                                           */
/*************************************************************/
bit lcd_busy()
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}
/*******************************************************************/
/*                                                                 */
/*写指令数据到LCD                                                  */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
/*                                                                 */
/*******************************************************************/
void lcd_wcmd(unsigned char cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}
/*******************************************************************/
/*                                                                 */
/*写显示数据到LCD                                                  */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
/*                                                                 */
/*******************************************************************/
void lcd_wdat(unsigned char dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
}
/*************************************************************/
/*                                                           */
/*  LCD初始化设定                                            */
/*                                                           */
/*************************************************************/
void lcd_init()
{
    delay(15);                  
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);
    lcd_wcmd(0x0c);      //显示开,关光标
    delay(5);
    lcd_wcmd(0x06);      //移动光标
    delay(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay(5);
}
/*************************************************************/
/*                                                           */
/*  设定显示位置                                             */
/*                                                           */
/*************************************************************/
void lcd_pos(unsigned char pos)
{                          
  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
}
/*************************************************************
                                                         
键扫描子程序                                             
                                                         
*************************************************************/
void  keyscan(void)
{
    P1=0x0F;                 //低四位输入  
    delay(1);
temp=P1;                 //读P1口
    temp=temp&0x0F;
    temp=~(temp|0xF0);
    if(temp==1)
        key=0;
    else if(temp==2)
        key=1;
    else if(temp==4)
        key=2;
    else if(temp==8)
        key=3;
    else
        key=16;
        
    P1=0xF0;                //高四位输入
    delay(1);
temp=P1;                //读P1口      
    temp=temp&0xF0;
    temp=~((temp>>4)|0xF0);
    if(temp==1)
        key=key+0;
    else if(temp==2)
        key=key+4;
    else if(temp==4)
        key=key+8;
    else if(temp==8)
        key=key+12;
    else
        key=16;
     
     key_buf = key;              //键值入显示缓存
     key_buf = key_buf & 0x0f;
}
/*************************************************************
                                                         
判断键是否按下                                             
                                                         
*************************************************************/
void  keydown(void)
{  
   P1=0xF0;
while(P1==0xf0);
{
   keyscan();
   beep();
    }
}
/**********************************************************
  随机出题函数
**********************************************************/
void  rubric()
{
   unsigned char  num1,num2,temp1;
   TR1=0;
   temp1=TL1;                   //取T1当前的计数值
   temp1=~temp1;                //取反得到对应的题号
   num2=temp1/9;                //就题目分成9组
   num2++;                      //将组号0~8转换为被乘数1~9
   testdata[3]=num2+0x30;       //保存被乘数
   num1=temp1%9;              
   num1++;                      //将组号0~8转换为乘数1~9。
   testdata[2]=num1+0x30;       //保存乘数
   temp1=num2*num1;             //计算乘积
   testdata[1]=temp1/10+0x30;   //乘积的高位
   testdata[0]=temp1%10+0x30;   //乘积的低位
   TR1=1;   
}
/**********************************************************
  键入正确答案函数
**********************************************************/
void  right()
{
   if(testdata[1]==0x30)
   {
   testdata[1]=0x20;
   }
   lcd_pos(0x4b);
   in_data[1]=testdata[1];
   in_data[0]=testdata[0];
   lcd_wdat(in_data[1]);
   lcd_wdat(in_data[0]);
}
/**********************************************************
  键入答案函数
**********************************************************/
void  key_input()
{
   if(testdata[1]==0x30)        //先判断十位数是否为0
   {      
     in_data[1]=0x30;           
  key_num=1;
   }
   else
   {
     keydown();
  if(key_buf==0x0c)          //C 键显示正确答案
  {
    right();
       key_num=0;
     }
     if(key_buf<10)
     {         
       key_buf=key_buf+0x30; //转换为ASCII码
       in_data[1]=key_buf;      //输入乘积高位
       lcd_pos(0x4b);
       lcd_wdat(in_data[1]);    //显示乘积高位
       lcd_wdat(0x20);
    key_num=1;
     }
   }
   if(key_num==1)
   {
     keydown();
     if(key_buf==0x0c)          //C 键显示正确答案
  {
       right();
    key_num=0;
  }
     if(key_buf<10)
     {            
       key_buf=key_buf+0x30;    //转换为ASCII码
       in_data[0]=key_buf;      //输入乘积低位
       lcd_pos(0x4c);
       lcd_wdat(in_data[0]);    //显示乘积低位
    key_num=0;
     }         
   }
}
/**********************************************************
  数据比较函数
**********************************************************/
void  datacomp()
{
   if(testdata[1]-in_data[1]==0)    //比较乘积高位
   {
      if(testdata[0]-in_data[0]==0) //比较乘积低位
   {
      beep();                //计算正确蜂鸣器响3声
   beep();
   beep();
   truer=1;               //比较正确
         F_in=0;                //可以重新出题
   }
      else  truer=0;            //比较错误
   }
   else  truer=0;               //比较错误
  
   if(truer==0)         
   {
     lcd_pos(0x4B);             //清除错误答案
     lcd_wdat(0x20);
  lcd_wdat(0x3f);
  F_in=1;                    //禁止重新出题
   }
}
/**********************************************************
  主函数
**********************************************************/
main()
{
   unsigned char  m;
   lcd_init();                  //初始化LCD            
        
   lcd_pos(0x00);               //设置显示位置为第一行
   for(m=0;m<16;m++)
   lcd_wdat(cdis1);
   lcd_pos(0x40);               //设置显示位置为第二行     
   for(m=0;m<16;m++)
   lcd_wdat(cdis2);
   TMOD=0x21;                 //将T1设置为8位自动重装工作方式。
   TH1=175;                     //对T1定时常数进行预置。
   TL1=175;
   TR1=1;                       //启动T1。
   while(1)               
   {
     keydown();
     if(key_buf==0x0f)          //F 键为模拟出题开关
  {
    rubric();
    lcd_pos(0x47);
       lcd_wdat(testdata[3]);   //显示被乘数
       lcd_pos(0x49);
       lcd_wdat(testdata[2]);   //显示乘数
       lcd_pos(0x4B);
       lcd_wdat(0x20);
       lcd_wdat(0x3f);          //显示 ?
    key_buf=0x00;
    F_in=1;                  //出题目完毕标志
  }
     
     while(F_in==1)
  {
    key_input();
       datacomp();
  }
   }
}

搜狗截图_2012-06-09_11-51-22.jpg
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。