- //用三个74hc595控制三个lcd1602,
- #include <reg51.h>
- #include <stdio.h>
- //引脚定义
- sbit LCD1602_SHCP=P3^4;
- sbit LCD1602_DS=P3^5;
- sbit LCD1602_STCP=P3^6;
- sbit LCD1602_STCP2=P3^7;
- sbit LCD1602_STCP3=P3^3;
- //两种数据类型
- typedef unsigned char uchar;
- typedef unsigned int uint;
- //定义数据槽
- uchar RS,RW,E,D4,D5,D6,D7;
- //二进制的形象表示方法,从左到右分别位第7 6 5 4 3 2 1 0位
- #define bin(_a,_b,_c,_d,_e,_f,_g,_h) ((_a)<<7|(_b)<<6|(_c)<<5|(_d)<<4|(_e)<<3|(_f)<<2|(_g)<<1|(_h)) //二进制的表示
- void Lcd1602_Delay1ms(uint c); //延时函数,延时1ms
- void LCD1602_DATAPINS(uchar value, uchar num); //更改74HC595连接LCD1602的数据
- void LcdCalc(uchar i); //确定4位总线
- void LcdWriteCom(uchar com, uchar num); //向LCD写入一个字节的命令
- void LcdWriteData(uchar dat, uchar num); //向LCD写入一个字节的数据
- void LcdInit(); //初始化LCD屏
- void LcdPrintf(uchar *s, uchar num); //向屏幕输出字符
- void LcdWriteCGRAM(uchar index,uchar *p, uchar num); //建立一个自定义字符
- void LCDPrintNum(uint number,uchar wei, uchar num); //显示数字
- /*******************************************************************************
- * 函 数 名 : Lcd1602_Delay1ms
- * 函数功能 : 延时函数,延时1ms
- * 输 入 : c
- * 输 出 : 无
- * 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。
- *******************************************************************************/
- void Lcd1602_Delay1ms(uint c) //误差 0us
- {
- uchar a,b;
- for(;c>0;c--){
- for(b=199;b>0;b--){
- for(a=1;a>0;a--);
- }
- }
- }
- /*******************************************************************************
- * 函 数 名 : LCD1602_DATAPINS
- * 函数功能 : 更改74HC595连接LCD1602的数据
- * 输 入 : value
- * 输 出 : 无
- *******************************************************************************/
- void LCD1602_DATAPINS(uchar value, uchar num)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- LCD1602_DS=value&0x80;//取数据高位
- if(LCD1602_DS==0x80){ //判断数据高位是否为1
- LCD1602_DS=1;//如果高位为1,DS置1
- }
- else{
- LCD1602_DS=0;//否则DS置0
- }
- LCD1602_SHCP=0;
- LCD1602_SHCP=1;//上升沿使这一位写入移位寄存器
- value<<=1;//数据左移1位,数据的第7位变为最高位,循环第8次时数据的最低位也变成最高位
- }
- if (num==2)
- {
- LCD1602_STCP3=0;
- LCD1602_STCP3=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
- }
- else if(num==1)
- {
- LCD1602_STCP2=0;
- LCD1602_STCP2=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
- }
- else
- {
- LCD1602_STCP=0;
- LCD1602_STCP=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
- }
- }
- /*******************************************************************************
- * 函 数 名 : LcdCalc
- * 函数功能 : 确定4位总线
- * 输 入 : i
- * 输 出 : 无
- *******************************************************************************/
- void LcdCalc(uchar i)
- {
- if(i==0x00){
- D4=0;
- D5=0;
- D6=0;
- D7=0;
- }
- if(i==0x01){
- D4=1;
- D5=0;
- D6=0;
- D7=0;
- }
- if(i==0x02){
- D4=0;
- D5=1;
- D6=0;
- D7=0;
- }
- if(i==0x03){
- D4=1;
- D5=1;
- D6=0;
- D7=0;
- }
- if(i==0x04){
- D4=0;
- D5=0;
- D6=1;
- D7=0;
- }
- if(i==0x05){
- D4=1;
- D5=0;
- D6=1;
- D7=0;
- }
- if(i==0x06){
- D4=0;
- D5=1;
- D6=1;
- D7=0;
- }
- if(i==0x07){
- D4=1;
- D5=1;
- D6=1;
- D7=0;
- }
- if(i==0x08){
- D4=0;
- D5=0;
- D6=0;
- D7=1;
- }
- if(i==0x09){
- D4=1;
- D5=0;
- D6=0;
- D7=1;
- }
- if(i==0x0a){
- D4=0;
- D5=1;
- D6=0;
- D7=1;
- }
- if(i==0x0b){
- D4=1;
- D5=1;
- D6=0;
- D7=1;
- }
- if(i==0x0c){
- D4=0;
- D5=0;
- D6=1;
- D7=1;
- }
- if(i==0x0d){
- D4=1;
- D5=0;
- D6=1;
- D7=1;
- }
- if(i==0x0e){
- D4=0;
- D5=1;
- D6=1;
- D7=1;
- }
- if(i==0x0f){
- D4=1;
- D5=1;
- D6=1;
- D7=1;
- }
- if(i==0x10){
- D4=1;
- D5=0;
- D6=0;
- D7=0;
- }
- if(i==0x20){
- D4=0;
- D5=1;
- D6=0;
- D7=0;
- }
- if(i==0x30){
- D4=1;
- D5=1;
- D6=0;
- D7=0;
- }
- if(i==0x40){
- D4=0;
- D5=0;
- D6=1;
- D7=0;
- }
- if(i==0x50){
- D4=1;
- D5=0;
- D6=1;
- D7=0;
- }
- if(i==0x60){
- D4=0;
- D5=1;
- D6=1;
- D7=0;
- }
- if(i==0x70){
- D4=1;
- D5=1;
- D6=1;
- D7=0;
- }
- if(i==0x80){
- D4=0;
- D5=0;
- D6=0;
- D7=1;
- }
- if(i==0x90){
- D4=1;
- D5=0;
- D6=0;
- D7=1;
- }
- if(i==0xa0){
- D4=0;
- D5=1;
- D6=0;
- D7=1;
- }
- if(i==0xb0){
- D4=1;
- D5=1;
- D6=0;
- D7=1;
- }
- if(i==0xc0){
- D4=0;
- D5=0;
- D6=1;
- D7=1;
- }
- if(i==0xd0){
- D4=1;
- D5=0;
- D6=1;
- D7=1;
- }
- if(i==0xe0){
- D4=0;
- D5=1;
- D6=1;
- D7=1;
- }
- if(i==0xf0){
- D4=1;
- D5=1;
- D6=1;
- D7=1;
- }
- }
- /*******************************************************************************
- * 函 数 名 : LcdWriteCom
- * 函数功能 : 向LCD写入一个字节的命令
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
- void LcdWriteCom(uchar com, uchar num) //写入命令
- {
- E = 0; //使能清零
- RS = 0; //选择写入命令
- RW = 0; //选择写入
- LcdCalc(com>>4); //发送高四位
- Lcd1602_Delay1ms(1);
- E = 1; //写入时序
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- Lcd1602_Delay1ms(5);
- E = 0;
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- LcdCalc(com<<4); //发送低四位
- Lcd1602_Delay1ms(1);
- E = 1; //写入时序
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- Lcd1602_Delay1ms(5);
- E = 0;
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- }
- /****************************************************************************
- * 函 数 名 : LcdWriteData
- * 函数功能 : 向LCD写入一个字节的数据
- * 输 入 : dat
- * 输 出 : 无
- *******************************************************************************/
- void LcdWriteData(uchar dat, uchar num) //写入数据
- {
- E = 0; //使能清零
- RS = 1; //选择写入数据
- RW = 0; //选择写入
- LcdCalc(dat>>4); //发送高四位
- Lcd1602_Delay1ms(1);
- E = 1; //写入时序
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- Lcd1602_Delay1ms(5);
- E = 0;
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- LcdCalc(dat<<4); //发送低四位
- Lcd1602_Delay1ms(1);
- E = 1; //写入时序
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- Lcd1602_Delay1ms(5);
- E = 0;
- LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
- }
- /*******************************************************************************
- * 函 数 名 : LcdInit
- * 函数功能 : 初始化LCD屏
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void LcdInit() //LCD初始化子程序
- {
- LcdWriteCom(0x32,0); //将8位总线转为4位总线
- LcdWriteCom(0x28,0); //在四位线下的初始化
- LcdWriteCom(0x0c,0); //开显示不显示光标
- LcdWriteCom(0x06,0); //写一个指针加1
- LcdWriteCom(0x01,0); //清屏
- LcdWriteCom(0x80,0); //设置数据指针起点
- LcdWriteCom(0x32,1); //将8位总线转为4位总线
- LcdWriteCom(0x28,1); //在四位线下的初始化
- LcdWriteCom(0x0c,1); //开显示不显示光标
- LcdWriteCom(0x06,1); //写一个指针加1
- LcdWriteCom(0x01,1); //清屏
- LcdWriteCom(0x80,1); //设置数据指针起点
- LcdWriteCom(0x32,2); //将8位总线转为4位总线
- LcdWriteCom(0x28,2); //在四位线下的初始化
- LcdWriteCom(0x0c,2); //开显示不显示光标
- LcdWriteCom(0x06,2); //写一个指针加1
- LcdWriteCom(0x01,2); //清屏
- LcdWriteCom(0x80,2); //设置数据指针起点
- }
- /*******************************************************************************
- * 函 数 名 : LcdPrintf
- * 函数功能 : 向屏幕输出字符
- * 输 入 : *s
- * 输 出 : 无
- *******************************************************************************/
- void LcdPrintf(uchar *s, uchar num)
- {
- while(*s>0)LcdWriteData(*s++, num);
- }
- /*******************************************************************************
- * 函 数 名 : LcdWriteCGRAM
- * 函数功能 : 建立一个自定义字符
- * 输 入 : index、*p
- * 输 出 : 无
- *******************************************************************************/
- void LcdWriteCGRAM(uchar index,uchar *p, uchar num)
- {
- uchar i;
- index <<=3; //index *= 8
- for(i=0;i<8;++i){
- LcdWriteCom(0x40 | index+i, num);//写CGRAM地址
- LcdWriteData(*p++, num);
- }
- LcdWriteCom(0x80, num);
- }
- /*******************************************************************************
- * 函 数 名 : LcdPrintNum
- * 函数功能 : 显示数字
- * 输 入 : num、wei
- * 输 出 : 无
- *******************************************************************************/
- void LCDPrintNum(uint number,uchar wei, uchar num)//wei 数字占的位数
- {
- uchar tempstring[6];
- uchar n[5];
- uchar i,j=0;
- n[0]=number/10000;
- n[1]=number%10000/1000;
- n[2]=number%1000/100;
- n[3]=number%100/10;
- n[4]=number%10;
- i=5-wei;
- for(i;i<5;i++){
- tempstring[j++]=n[i]+'0';
- }
- tempstring[j]='\0';
- LcdPrintf(tempstring, num);
- }
- const uchar type_t[]={
- 0x1f,0x02,0x02,0x02,
- 0x02,0x02,0x02,0x00
- }; //显示一种用于以前的logo的“T”字符
- const uchar line1[]="Have a nice day!";
- const uchar line2[]="HE Wcommands";
- void main()
- {
- uchar i;
- LcdInit();
- LcdWriteCGRAM(0x00,type_t,0);
- LcdWriteData(0x00,0);
- LcdWriteCom(0x81,0);
- LcdPrintf("HE With",0);
- LcdWriteCom(0xc0,0);
- LcdPrintf("Commands",0);
- Lcd1602_Delay1ms(1000);
- LcdWriteCGRAM(0x00,type_t,1);
- LcdWriteData(0x00,1);
- LcdWriteCom(0x81,1);
- LcdPrintf("HE With",1);
- LcdWriteCom(0xc0,1);
- LcdPrintf("2nd Display",1);
- Lcd1602_Delay1ms(500);
- LcdWriteCGRAM(0x00,type_t,2);
- LcdWriteData(0x00,2);
- LcdWriteCom(0x81,2);
- LcdPrintf("HE With",2);
- LcdWriteCom(0xc0,2);
- LcdPrintf("3rd Display",2);
- Lcd1602_Delay1ms(500);
- LcdWriteCom(0x01,0);
- while(1){
- for(i=0;i<16;i++){
- LcdWriteCom(0x80+i,0);
- LcdWriteData(line1[i],0);
- Lcd1602_Delay1ms(100);
- }
- Lcd1602_Delay1ms(500);
- LcdWriteCom(0xc1,0);
- LcdWriteData(0x00,0);
- Lcd1602_Delay1ms(100);
- for(i=0;i<12;i++){
- LcdWriteCom(0xc2+i,0);
- LcdWriteData(line2[i],0);
- Lcd1602_Delay1ms(100);
- }
- LcdWriteCom(0x01,0);
- Lcd1602_Delay1ms(100);
- }
- }
复制代码 |