LCD1602 显示乘法口诀的设计

img

以 51 单片机为主控芯片,LCD1602 为显示屏设计 99 乘法口诀的显示
要求实现以下
功能:
(1)硬件部分:由单片机外围电路、液晶显示电路、键盘电路等构成。
(2)软件部分:通过按键控制乘法口诀的顺序显示和随机显示。当按下顺序按键时,液
晶显示屏上自动实现从 1×1=1 到 9×9=81 的轮流显示;若再按下顺序按键,则暂停轮流
显示,若再按下顺序按键,则继续轮流显示,如此反复。若按下随机按键,则每按键一次
就显示一条乘法口诀,同时扬声器发声

#include<reg51.h>
#include <stdlib.h>
#include"lcd1602.h"
unsigned char op1=1;
unsigned char op2=1;
unsigned char a=1;
unsigned char b=1;
bit m=0,n=0;
unsigned char result;
unsigned char table[7]="";
sbit key=P3^0;
sbit key1=P3^3;
//sbit key=P1^0;
//sbit key1=P1^4;
void keyscan()
{
        key=1;
        if(key == 0)
        {
            delayms(10);
            if(key == 0){m=!m;}
      while (key==0);                    
        }
        
         key1=1;
        if(key1== 0)
        {
            delayms(10);
            if(key1 == 0){n=!n;}
      while (key1==0);                    
        }
}    
void main()
{
    unsigned char a,b;
    a=op2;
    b=op1;
LCD_initial();

srand(16);
while(1)
{
    keyscan();
    if(m)
    {
        op2++;
        if(op2>9){
            op1++;
            op2=1;}
        if(op1>9)
        {
            op1=1;
        }
        result=op1*op2;
    table[0]=op1+'0';
    table[1]='*';
    table[2]=op2+'0';
    table[3]='=';
    table[4]=result/10%10+48;
    table[5]=result/1%10+48;
    write_string(0x40,table);
    delayms(1000);
        }    
        if(n)
        {
            
            
            b = rand()%9+1; 
      a= rand()%9+1;
            n=0;
            result=b*a;
      table[0]=b+'0';
      table[1]='*';
      table[2]=a+'0';
      table[3]='=';
      table[4]=result/10%10+48;
      table[5]=result/1%10+48;
            write_string(0x40,table);
            delayms(1000); 
            
        }
        

}}

lcd1602.h

#define uchar unsigned char
#define uint unsigned int 


void LCD_initial(void);        //LCD初始化函数
void check_busy(void);     //检查忙标志函数
void write_command(uchar com);     //写命令函数
void write_data(uchar dat);        //写数据函数
void string(uchar ad ,uchar *s);
void delayms(uint);                //延时函数
void write_string(uchar addr,uchar str[]);//在某个地址上显示字符串

lcd1602.c


#include <stc15f2k60s2.h>
#include <intrins.h>
#include <string.h>

#define uchar unsigned char
#define uint unsigned int 

sbit RS=P2^0;                 //位变量
sbit RW=P2^1;                //位变量
sbit E=P2^2;                 //位变量
void delayms(uint n)            //n ms延时子程序
{
    uchar i;
    while(n--)
      for(i=0;i<113;i++);
}

void check_busy(void)     //检查忙标志函数
{
    uchar dt;
    do
    {
        dt=0xff;
        E=0;
        RS=0;    
        RW=1;
        E=1;
        dt=P0;
        //E=0;//有也可以
    }while(dt&0x80);
    E=0;
}

void write_command(uchar com)      //写命令函数
{
    check_busy();
    E=0;
    RS=0;
    RW=0;
    P0=com;
    E=1;
    _nop_( );
    E=0;
    delayms(1);
}

void write_data(uchar dat)         //写数据函数
{
    check_busy();
    E=0;
    RS=1;
    RW=0;
    P0=dat;
    E=1;
    _nop_();
    E=0;
    delayms(1);    
}
void LCD_initial(void)     //液晶显示器初始化函数
{
    write_command(0x38);    //写入命令0x38:8位两行                    显示,5×7点阵字符
    _nop_( );  
    write_command(0x0C);    //写入命令0x0C:开整体                    显示,光标关,无黑块
    _nop_( );
    write_command(0x06);    //写入命令0x06:光标右移
    _nop_( );
    write_command(0x01);     //写入命令0x01:清屏
    delayms(2);
}

void write_string(uchar addr,uchar str[])
{
   uchar i;
   write_command(0x80+addr);
   for(i=0;i<strlen(str);i++)
   {
     write_data(str[i]);
     delayms(60);
   }
    
}

有点bug但应该能用(大概)