51综合程序05-LCD12864相关应用

2023-12-05 13:04

本文主要是介绍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相关应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/457677

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*