本文主要是介绍51综合程序05-LCD12864相关应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 一、LCD12864显示图形
- 1. 仿真电路图
- 2. 源代码
- 3. 实验结果
- 二、LCD12864显示指针式时钟
- 1. 仿真电路图
- 2. 源代码
- 3. 实验结果
- 三、LCD12864温度型时钟
- 1. 源代码
- 2. 实验结果
一、LCD12864显示图形
1. 仿真电路图
2. 源代码
LCD12864.h
#ifndef LCD12864
#define LCD12864#include <intrins.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <absacc.h>
#include <string.h>#define STX 0x02
#define ETX 0x03
#define EOT 0x04
#define ENQ 0x05
#define BS 0x08
#define CR 0x0d
#define LF 0x0a
#define DLE 0x10
#define ETB 0x17
#define SPACE 0x20
#define COMMA 0x2c#define TRUE 1
#define FALSE 0
#define HIGH 1
#define LOW 0#define LCMDW XBYTE[0x8000]
#define LCMCW XBYTE[0x8100]//显示内存分配
#define DISRAM_SIZE 0X7FFF //设置显示ram的大小
#define TXTSTART 0x0000 //设置文本区的起始地址
#define GRSTART 0x6800 //设置图形区的起始地址
#define CGRAMSTART 0x7800 //设置CGRAM的起始地址//T6963C 命令定义
#define LC_CUR_POS 0x21 //光标位置设置
#define LC_CGR_POS 0x22 //CGRAM偏置地址设置
#define LC_ADD_POS 0x24 //地址指针位置
#define LC_TXT_STP 0x40 //文本区首址
#define LC_TXT_WID 0x41 //文本区宽度
#define LC_GRH_STP 0x42 //图形区首址
#define LC_GRH_WID 0x43 //图形区宽度
#define LC_MOD_OR 0x80 //显示方式:逻辑或
#define LC_MOD_XOR 0x81 //显示方式:逻辑异或
#define LC_MOD_AND 0x82 //显示方式:逻辑与
#define LC_MOD_TCH 0x83 //显示方式:文本特征
#define LC_DIS_SW 0x90 //显示开关://D0=1/0:光标闪烁启用/禁用;//D1=1/0:光标显示启用/禁用;//D2=1/0:文本显示启用/禁用;//D3=1/0:图形显示启用/禁用;
#define LC_CUR_SHP 0xA0 //光标形状选择:0xA0-0xA7表示光标占的行数
#define LC_AUT_WR 0xB0 //自动写设置
#define LC_AUT_RD 0xB1 //自动读设置
#define LC_AUT_OVR 0xB2 //自动读/写结束
#define LC_INC_WR 0xC0 //数据写,地址加1
#define LC_INC_RD 0xC1 //数据读,地址加1
#define LC_DEC_WR 0xC2 //数据写,地址减1
#define LC_DEC_RD 0xC3 //数据读,地址减1
#define LC_NOC_WR 0xC4 //数据写,地址不变
#define LC_NOC_RD 0xC5 //数据读,地址不变
#define LC_SCN_RD 0xE0 //屏读
#define LC_SCN_CP 0xE8 //屏拷贝
#define LC_BIT_OP 0xF0 //位操作:D0-D2:定义D0-D7位;D3:1置位,0:清除unsigned char fnST01(void);
unsigned char LCD12864_Write_Cmd_2(unsigned char uCmd,unsigned char uPar1,unsigned char uPar2);
unsigned char LCD12864_Write_Cmd_1(unsigned char uCmd,unsigned char uPar1);
unsigned char LCD12864_Write_Cmd_0(unsigned char uCmd);
void fnSetPos(unsigned char urow, unsigned char ucol);
void LCD12864_cls(void);
char LCD12864_Init(void);
unsigned char fnST3(void);
unsigned char LCD12864_Write_Date(unsigned char uData);
#endif
LCD12864.c
#include <reg52.h>
#include "LCD12864.h"
#include "DS1302.h"unsigned char gCurRow,gCurCol; //图形当前行、列存储,行高16点,列宽8点
unsigned int txthome,grhome;unsigned char fnST01(void) // 状态位STA1,STA0判断(读写指令和读写数据)
{unsigned char i;for(i=10;i>0;i--){if((LCMCW & 0x03) == 0x03)break;}return i; // 若返回零,说明错误
}unsigned char fnST3(void) // 状态位ST3判断(数据自动写状态)
{unsigned char i;for(i=10;i>0;i--){if((LCMCW & 0x08) == 0x08)break;}return i; // 若返回零,说明错误
}unsigned char LCD12864_Write_Cmd_2(unsigned char uCmd,unsigned char uPar1,unsigned char uPar2) // 写双参数的指令
{if(fnST01() == 0)return 1;LCMDW = uPar1;if(fnST01() == 0)return 2;LCMDW = uPar2;if(fnST01() == 0)return 3;LCMCW = uCmd;return 0; // 返回0成功
}unsigned char LCD12864_Write_Cmd_1(unsigned char uCmd,unsigned char uPar1) // 写单参数的指令
{if(fnST01() == 0)return 1;LCMDW = uPar1;if(fnST01() == 0)return 2;LCMCW = uCmd;return 0; // 返回0成功
}unsigned char LCD12864_Write_Cmd_0(unsigned char uCmd) // 写无参数的指令
{if(fnST01() == 0)return 1;LCMCW = uCmd;return 0; // 返回0成功
}unsigned char LCD12864_Write_Date(unsigned char uData) // 写数据
{if(fnST3() == 0)return 1;LCMDW = uData;return 0; // 返回0成功
}void fnSetPos(unsigned char urow, unsigned char ucol) //设置当前地址
{unsigned int iPos;iPos = urow * 20 + ucol;LCD12864_Write_Cmd_2(LC_ADD_POS,iPos & 0xFF,iPos / 256);gCurRow = urow;gCurCol = ucol;
}// 清屏/**/
void LCD12864_cls(void)
{unsigned int i;LCD12864_Write_Cmd_2(LC_ADD_POS,0x00,0x00); // 置地址指针LCD12864_Write_Cmd_0(LC_AUT_WR); // 自动写for(i=0;i<0x2000;i++){fnST3();LCD12864_Write_Date(0x00); // 写数据}LCD12864_Write_Cmd_0(LC_AUT_OVR); // 自动写结束LCD12864_Write_Cmd_2(LC_ADD_POS,0x00,0x00); // 重置地址指针gCurRow = 0; // 置地址指针存储变量gCurCol = 0;
}char LCD12864_Init(void) /*LCD初始化*/
{LCD12864_Write_Cmd_2(LC_TXT_STP,0x00,0x00); // 文本显示区首地址LCD12864_Write_Cmd_2(LC_TXT_WID,0x14,0x00); // 文本显示区宽度LCD12864_Write_Cmd_2(LC_GRH_STP,0x00,0x00); // 图形显示区首地址LCD12864_Write_Cmd_2(LC_GRH_WID,0x14,0x00); // 图形显示区宽度LCD12864_Write_Cmd_1(LC_CGR_POS,CGRAMSTART >> 11);LCD12864_Write_Cmd_0(LC_CUR_SHP | 0x01); // 光标形状LCD12864_Write_Cmd_0(LC_MOD_OR); // 显示方式设置LCD12864_Write_Cmd_0(LC_DIS_SW |0x08);grhome = GRSTART;txthome = TXTSTART;return 0;
}
wave.h
#ifndef WAVE
#define WAVEvoid Pixel(unsigned char PointX,unsigned char PointY, bit Mode);void Line( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2, bit Mode);void Line_2( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2, bit Mode);void Line_1( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2, bit Mode);#endif
wave.c
#include "wave.h"
#include "LCD12864.h"void Pixel(unsigned char PointX,unsigned char PointY, bit Mode)/*在指定坐标位置显示一个点*/
{ //Mode 1:显示 0:清除该点unsigned char StartAddr;unsigned char dat;StartAddr=7-(PointX%8);dat=LC_BIT_OP|StartAddr; //生产位操作命令画点的数据if(Mode) dat=dat|0x08;fnSetPos(PointY,PointX/8);LCD12864_Write_Cmd_0(LC_BIT_OP|dat); // 写数据
}/*划线函数, 参数: 坐标1,坐标2,显示点或清除点*///绘制正弦波
void Line( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2, bit Mode)
{float x,y;double k,b;for (x=(float)x1;x<=(float)x2;x+=0.1){y=30+15*sin(x*3.14/30);Pixel(x, y, Mode);}
}//绘制菱形
void Line_1( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2, bit Mode)
{float x,y;double k,b;k=((double)y2-y1) / ((double)x2-x1) ;b=y1-k*x1;if( x1 <= x2 ) {for(x=(float)x1;x<=(float)x2;x+=0.1){y=(unsigned char)(k*x+b);Pixel(x, y, Mode);}}else{for(x=(float)x1;x>=(float)x2;x-=0.1){y=(unsigned char)(k*x+b);Pixel(x, y, Mode);}}
}//绘制矩形
void Line_2( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2, bit Mode)
{float x,y;for(x=(float)x1;x<=(float)x2;x+=0.1){Pixel(x,0,Mode);Pixel(0,x,Mode);Pixel(50-x,50,Mode);Pixel(50,50-x,Mode);}
}
main.c
#include <reg52.h>
#include "LCD12864.h"
#include "wave.h"#define PI 3.1415926//绘制圆形
void Clock_yuanxing()
{float sta,x,y;for (sta=0;sta<=2*PI;sta+=0.01){ x = sin(sta); y = cos(sta);Pixel(30+30*x,30+30*y,1);}
}//绘制矩形
void Clock_juxing()
{float x=50,y=50;Line_2(0,0,x,y,1);
}//绘制菱形
void Clock_lingxing()
{Line_1(20,30,60,0,1);Line_1(60,0,100,30,1);Line_1(100,30,60,60,1);Line_1(60,60,20,30,1);
}//绘制正弦波
void Clock_zhengxuanbo()
{unsigned char x=108,y=50;Line(16,0,x,y,1);
}void main() /*主程序*/
{LCD12864_Init(); //液晶初始化fnSetPos(0,0); //从LCD左上角开始清屏LCD12864_cls();while(1){//Clock_zhengxuanbo();Clock_lingxing();//Clock_yuanxing(); //Clock_juxing();}
}
3. 实验结果
二、LCD12864显示指针式时钟
1. 仿真电路图
2. 源代码
LCD12864.h
与上述代码相同,不在赘述
LCD12864.c
与上述代码相同,不在赘述
DS1302.h
#ifndef DS1302_H
#define DS1302_H#include <reg52.h>sbit SDA=P1^0; // DS1302数据线
sbit CLK=P1^1; // DS1302时钟线
sbit RST=P1^2; // DS1302复位线
sbit K1=P3^0; //选择
sbit K2=P3^1; //调整
sbit K3=P3^3; //确定void DS1302_Write(unsigned char x);
unsigned char DS1302_Read();
unsigned char DS1302_Read_Data(unsigned char addr);
void DS1302_Write_Data(unsigned char addr,unsigned char dat);#endif
DS1302.c
#include "DS1302.h"
#include "LCD12864.h"/*向DS1302写入一字节*/
void DS1302_Write(unsigned char x)
{unsigned char i;for(i=0;i<8;i++){SDA = x&1; CLK = 1; CLK = 0; x >>= 1;}
}/*从DS1302读取一字节*/
unsigned char DS1302_Read()
{unsigned char i, b, t;for(i = 0; i < 8; i++){b >>= 1; t = SDA; b |= t << 7; CLK = 1; CLK = 0;}
// BCD码转换return b /16 * 10 + b % 16;
}/*从DS1302指定位置读取数据*/
unsigned char DS1302_Read_Data(unsigned char addr)
{unsigned char dat;RST = 0; CLK = 0; RST = 1;DS1302_Write(addr);dat = DS1302_Read();CLK = 1; RST = 0;return dat;
}/*向DS1302某地址写入数据*/
void DS1302_Write_Data(unsigned char addr,unsigned char dat)
{CLK = 0; RST = 1;DS1302_Write(addr);DS1302_Write(dat);CLK = 0;RST = 0;
}
main.c
#include <reg52.h>
#include "LCD12864.h"
#include "DS1302.h"#define PI 3.1415926unsigned char count=0,d_Flag=0; //定时器累加次数,标志位
unsigned char Current_Time[3]; //所获取的日期时间
char Adjust_Index=-1; //当前调节的时间对象:秒,分,时(0,1,2)
char Time_Back[]= {-1,-1,-1}; //秒,分,时变化以后的备份,用于避免时针与分针在每秒时均被重画 ,形成抖动
unsigned char HMS_Hand_Length[]={24,20,15}; /*绘制电子钟圆形面板函数*/
void Clock_plate()
{float sta,x,y;//绘制外围圆圈,如果希望绘制较连续的圆圈线条,可减少步长,将0.1改为0.02for (sta=0;sta<=2*PI;sta+=0.01){ x = sin(sta); y = cos(sta);Pixel(30+30*x,30+30*y,1);}//绘制刻度1~12,每隔2xPI/12.0绘制一段for(sta=0;sta<=2*PI;sta+=2*PI/12){x=sin(sta);y=cos(sta);Pixel(30+27*x,30+27*y,1);Pixel(30+26*x,30+26*y,1);}
}/*重绘HMS中的某一指针函数(参数0,1,2分别为秒,分,时)*/
void Repaint_A_Hand(unsigned char i)
{float r,m;unsigned int x,y;m=(i==0||i==1) ? 60.0:12.0;//擦除r=Time_Back[i]/m*2*PI+1.5*PI;x=HMS_Hand_Length[i]*cos(r);y=HMS_Hand_Length[i]*sin(r);Line (30,30,x+30,y+30,0);//重绘r=Current_Time[i]/m*2*PI+1.5*PI;x=HMS_Hand_Length[i]*cos(r);y=HMS_Hand_Length[i]*sin(r);Line(30,30,x+30,y+30,1);//时间备份Time_Back[i]=Current_Time[i];
}void Display_HMS_Hand() //时间变化时重绘
{ //秒针与分针、时针接近重叠,或分钟与时钟接近重叠时也重绘Repaint_A_Hand(0); Repaint_A_Hand(1);Repaint_A_Hand(2);
}/*设置时间*/
void SET_DS1302()
{DS1302_Write_Data(0x8E,0X00); //写控制字,取消写保护DS1302_Write_Data(0x82,(Current_Time[1]/10<<4)|(Current_Time[1]%10)); //写入分DS1302_Write_Data(0x84,(Current_Time[2]/10<<4)|(Current_Time[2]%10)); //写入时DS1302_Write_Data(0x8E,0x80); //加保护
}/*读取当前时间(秒,分,时)*/
void GetTime()
{Current_Time[0]=DS1302_Read_Data(0x81); //读取秒Current_Time[1]=DS1302_Read_Data(0x83); //读取分 Current_Time[2]=DS1302_Read_Data(0x85); //读取时
}/*时,分调整*/
void Current_Time_Adjust()
{switch(Adjust_Index){case 2: Current_Time[2]=(Current_Time[2]+1)%24; break; //时 case 1: Current_Time[1]=(Current_Time[1]+1)%60; break; //分 }
}/*定时器0每秒刷新LCD显示*/
void T0_INT() interrupt 1
{TL0=0x00;TH0=0x4c;if(++count!=2) return;count=0;if(d_Flag==0) //如果是首次启动则绘制时钟面板,{ //绘制面板的调用可放在主程序中Clock_plate(); //但因为绘制指针和绘制面板都调用了sin函数d_Flag=1; //Keil C 会警告出现多重调用,因此本例将绘制} //面板的调用移到中断内部Display_HMS_Hand(); //显示当前时间指针
}/*键盘中断(INT0)*/
void EX_INT0() interrupt 0
{if(K1==0) //选择调用对象{if(Adjust_Index==-1|| Adjust_Index==1) Adjust_Index=3;Adjust_Index--;}else if(K2==0) //调整Current_Time_Adjust();else if(K3==0) //确定{SET_DS1302(); //将调整后的时间写入DS1302Adjust_Index=-1; //操作索引重设为-1,时间继续正常显示}
}/*主程序*/
void main()
{LCD12864_Init(); //液晶初始化fnSetPos(0,0); //从LCD左上角开始清屏LCD12864_cls();IE=0x83; //允许INT0,T0中断,使能总中断IT0=0x01;TMOD=0x01;TL0=0x00;TH0=0x4c;TR0=1;while(1){//如果未执行调整操作则正常读取当前时间if(Adjust_Index==-1) GetTime();}
}
3. 实验结果
三、LCD12864温度型时钟
1. 源代码
DS18B20.h
#ifndef __DS18B20_H_
#define __DS18B20_H_#include<reg51.h>void Delay1ms(unsigned int y); //1ms延时
void Delay480us(); //480us延时
unsigned char Ds18b20Init(); //初始化DS18B20
void Ds18b20WriteByte(unsigned char dat); //写字节
unsigned char Ds18b20ReadByte(); //读字节
void Ds18b20ChangTemp(); //温度转换
void Ds18b20ReadTempCom(); //发送读取温度命令
int Ds18b20ReadTemp(); //读取温度#endif
DS18B20.c
#include "DS18B20.h"
#include "lcd12864.h"sbit DQ=P3^7;void Delay1ms(unsigned int y) /*1ms延时*/
{unsigned int x;for( ; y>0; y--){for(x=110; x>0; x--);}
}void Delay480us() /*480us延时*///@11.0592MHz
{unsigned char i, j;i = 6;j = 38;do{while (--j);} while (--i);
}unsigned char Ds18b20Init() /*DS18B20初始化*/
{DQ = 0; //将总线拉低480us~960usDelay480us(); //480us的延时DQ = 1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低while(DQ) //等待DS18B20拉低总线{Delay1ms(5);if(DQ==1)//等待>5MS{return 0;//初始化失败}}return 1;//初始化成功
}void Ds18b20WriteByte(unsigned char dat) /*写字节函数*/
{unsigned char i,j;for(j=0; j<8; j++){DQ = 0; //每写入一位数据之前先把总线拉低1usi++;DQ = dat & 0x01; //然后写入一个数据,从最低位开始i=6;while(i--); //延时68us,持续时间最少60usDQ = 1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat >>= 1;}
}unsigned char Ds18b20ReadByte() /*读取字节函数*/
{unsigned char byte, bi;unsigned int i, j; for(j=8; j>0; j--){DQ = 0;//先将总线拉低1usi++;DQ = 1;//然后释放总线i++;i++;//延时6us等待数据稳定bi = DQ; //读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/byte = (byte >> 1) | (bi << 7); i = 4; //读取完之后等待48us再接着读取下一个数while(i--);}return byte;
}void Ds18b20ChangTemp() /*让18b20开始转换温度*/
{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc); //跳过ROM操作命令 Ds18b20WriteByte(0x44); //温度转换命令
}void Ds18b20ReadTempCom() /*发送读取温度命令*/
{ Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc); //跳过ROM操作命令Ds18b20WriteByte(0xbe); //发送读取温度命令
}int Ds18b20ReadTemp() /*读取温度*/
{int temp = 0;unsigned char tmh, tml;Ds18b20ChangTemp(); //先写入转换命令Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令tml = Ds18b20ReadByte(); //读取温度值共16位,先读低字节tmh = Ds18b20ReadByte(); //再读高字节temp = tmh;temp <<= 8;temp |= tml;return temp;
}
DS1302.h
#ifndef __DS1302_H_
#define __DS1302_H_#include<reg51.h>extern unsigned char TIME[7]; //加入全局变量sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;void delay_us(); //延时2us
void Ds1302Write(unsigned char addr, unsigned char dat); //写地址,写数据
unsigned char Ds1302Read(unsigned char addr); //读地址
void Ds1302Init(); //初始化
void Ds1302ReadTime(); #endif
DS1302.c
#include "DS1302.h"unsigned char code READ[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};//读命令 秒分时日月周年
unsigned char code WRITE[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//写命令 秒分时日月周年
unsigned char TIME[7] = {0, 0, 0x09, 0x18, 0x08, 0x03, 0x18}; //秒分时日月周年,存储格式是用BCD码//初始值的设定
void delay_us() /*延时2us*/
{
}void Ds1302Write(unsigned char addr, unsigned char dat) /*向DS1302写命令(地址+数据)*/
{unsigned char n;RST = 0;delay_us();SCLK = 0; //先将SCLK置低电平。delay_us();RST = 1; //然后将RST(CE)置高电平。delay_us();for (n=0; n<8; n++) //开始传送八位地址命令{DSIO=addr&0x01; //数据从低位开始传送addr>>=1;SCLK=1; //数据在上升沿时,DS1302读取数据delay_us();SCLK=0;delay_us();}for (n=0; n<8; n++) //写入8位数据{DSIO = dat&0x01;dat>>=1;SCLK=1; //数据在上升沿时,DS1302读取数据delay_us();SCLK=0;delay_us(); } RST = 0; //传送数据结束,拉低CE端delay_us();
}unsigned char Ds1302Read(unsigned char addr) /*读取一个地址的数据*/
{unsigned char n,dat,dat1;RST = 0;delay_us();SCLK = 0;//先将SCLK置低电平。delay_us();RST = 1;//然后将RST(CE)置高电平。delay_us();for(n=0; n<8; n++)//开始传送八位地址命令{DSIO = addr & 0x01;//数据从低位开始传送addr >>= 1;SCLK = 1;//数据在上升沿时,DS1302读取数据delay_us();SCLK = 0;//DS1302下降沿时,放置数据delay_us();}delay_us();for(n=0; n<8; n++)//读取8位数据{dat1 = DSIO;//从最低位开始接收dat = (dat>>1) | (dat1<<7);SCLK = 1;delay_us();SCLK = 0;//DS1302上升沿时,放置数据delay_us();}// RST = 0;
// delay_us(); //以下为DS1302复位的稳定时间,必须的。SCLK = 1;delay_us();DSIO = 0;delay_us();DSIO = 1;delay_us();return dat;
}void Ds1302Init() /*初始化DS1302*/
{unsigned char n;Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能for (n=0; n<7; n++) //写入7个字节的时钟信号:分秒时日月周年{Ds1302Write(WRITE[n],TIME[n]); //参数为地址和数据}Ds1302Write(0x8E,0x80); //打开写保护功能
}void Ds1302ReadTime() /*读取时钟信息*/
{unsigned char n;for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年{TIME[n] = Ds1302Read(READ[n]); //参数为地址}}
LCD12864.h
#ifndef __LCD12864_H
#define __LCD12864_H# include <reg51.h>/*接口定义模块*/
#define LCD12864_DATAPORT P0 //数据IO口sbit LCD12864_RS = P2^6; //(数据命令)寄存器选择输入
sbit LCD12864_RW = P2^5; //液晶读/写控制
sbit LCD12864_EN = P2^7; //液晶使能控制
sbit LCD12864_PSB = P3^2; //串/并方式控制
sbit LCD12864_RST = P3^3; //复位端/*函数声明模块*/
void LCD12864_Delay1ms(unsigned int c); //延时函数
void LCD12864_WriteCmd(unsigned char cmd); //写指令函数
void LCD12864_WriteData(unsigned char dat); //写数据函数
void LCD12864_Init(); //12864初始化函数 #endif
LCD12864.c
#include"lcd12864.h"void LCD12864_Delay1ms(unsigned int c) /*延时函数*/
{unsigned int a,b;for(; c>0; c--){for(b=199; b>0; b--){for(a=1; a>0; a--); }}
}void LCD12864_WriteCmd(unsigned char cmd) /*写指令函数*/
{ LCD12864_RS = 0; //选择命令LCD12864_RW = 0; //选择写入LCD12864_EN = 0; //初始化使能端LCD12864_DATAPORT = cmd; //放置数据LCD12864_EN = 1; //写时序LCD12864_Delay1ms(5);LCD12864_EN = 0;
}void LCD12864_WriteData(unsigned char dat) /*写数据函数*/
{LCD12864_RS = 1; //选择数据LCD12864_RW = 0; //选择写入LCD12864_EN = 0; //初始化使能端LCD12864_DATAPORT = dat; //放置数据LCD12864_EN = 1; //写时序LCD12864_Delay1ms(5); LCD12864_EN = 0;
}void LCD12864_Init() /*初始化函数*/
{LCD12864_PSB = 1; //选择并行输入LCD12864_RST = 1; //复位LCD12864_WriteCmd(0x30); //选择基本指令操作LCD12864_WriteCmd(0x0c); //显示开,关光标LCD12864_WriteCmd(0x01); //清除LCD12864的显示内容
}
main.c
#include <reg51.h>
#include "DS18B20.h"
#include "LCD12864.h"
#include "DS1302.h"unsigned DisplayData[8];
unsigned char code digit[]="0123456789";
unsigned char code Lcdshow[]="0123456789";
unsigned char code D1[]="温度: ";
unsigned char code D2[]="时间: ";
unsigned char code D3[]="星期: ";
unsigned char code D4[]="年份: ";void delay_us(unsigned int i) /*延时函数*/
{while(i--);
}void datapros(int temp) /*温度读取处理转换函数*/
{float tp; if(temp<0) //当温度值为负数{LCD12864_WriteCmd(0x80+0x00);LCD12864_WriteData('-'); // -temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*100+0.5; }else{ LCD12864_WriteCmd(0x80+0x03);LCD12864_WriteData('+');tp=temp; //因为数据处理有小数点所以将温度赋给一个浮点型变量temp=tp*0.0625*100+0.5; }DisplayData[1] = digit[temp/10000];DisplayData[2] = digit[temp/1000%10];DisplayData[3] = digit[temp/100%10];DisplayData[4] = digit[temp/10%10];DisplayData[5] = digit[temp % 10];
}void display_sta() /*正确显示函数*/
{unsigned char i;LCD12864_WriteCmd(0x80);i=0;while(D1[i]!='\0'){LCD12864_WriteData(D1[i]);i++; }LCD12864_WriteCmd(0x90);i=0;while(D2[i]!='\0'){LCD12864_WriteData(D2[i]);i++; }LCD12864_WriteCmd(0x88);i=0;while(D3[i]!='\0'){LCD12864_WriteData(D3[i]);i++; }LCD12864_WriteCmd(0x98);i=0;while(D4[i]!='\0'){LCD12864_WriteData(D4[i]);i++; }
}void display_temp() /*显示温度函数*/
{LCD12864_WriteData(DisplayData[1]);LCD12864_WriteData(DisplayData[2]);LCD12864_WriteData(DisplayData[3]);LCD12864_WriteData('.');LCD12864_WriteData(DisplayData[4]);LCD12864_WriteData(DisplayData[5]);LCD12864_WriteData(' ');LCD12864_WriteData(0xa1);LCD12864_WriteData(0xe6);
}void display_time() /*显示时间函数*/{LCD12864_WriteCmd(0x93);LCD12864_WriteData(Lcdshow[TIME[2]/16]); //显示小时LCD12864_WriteData(Lcdshow[TIME[2]%16]);LCD12864_WriteData('-');LCD12864_WriteData(Lcdshow[TIME[1]/16]); //显示分LCD12864_WriteData(Lcdshow[TIME[1]%16]);LCD12864_WriteData('-');LCD12864_WriteData(Lcdshow[TIME[0]/16]); //显示秒LCD12864_WriteData(Lcdshow[TIME[0]%16]);LCD12864_WriteCmd(0x8b);LCD12864_WriteData(Lcdshow[TIME[5]&0x07]); //显示星期LCD12864_WriteCmd(0x9b);LCD12864_WriteData(Lcdshow[TIME[6]/16]);LCD12864_WriteData(Lcdshow[TIME[6]%16]);LCD12864_WriteData('-');LCD12864_WriteData(Lcdshow[TIME[4]/16]);LCD12864_WriteData(Lcdshow[TIME[4]%16]);LCD12864_WriteData('-');LCD12864_WriteData(Lcdshow[TIME[3]/16]);LCD12864_WriteData(Lcdshow[TIME[3]%16]);
}void main()
{LCD12864_Init(); Ds1302Init(); display_sta(); while(1){Ds1302ReadTime(); //读取时间display_time(); //显示时间datapros(Ds18b20ReadTemp()); //数据处理函数display_temp();delay_us(1000); //延时1ms}
}
2. 实验结果
这篇关于51综合程序05-LCD12864相关应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!