12864液晶电子时钟+温度显示
12864显示温度曲线
12864显示温度曲线//12864并行连接,PSB接地正极#include#include#include#define uint unsigned int#define uchar unsigned charsbit rs=P2^0; /*数据\指令选择*/sbit rw=P2^1; /*读\写选择*/sbit e=P2^2; /*读\写使能*/sbit ds=P3^3; //18B20信号脚uint temp;float ftemp;uchar code table[]="0123456789.d"; void writecom(uchar com);void writedat(uchar dat);void initinal(void);//12MHZ晶振延时50微秒void delay50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}void dsreset() // ds18b20初始化函数{uint i;ds=0; //拉低总线开始复位i=103;while(i>0)i--;ds=1;//释放总线i=4;while(i>0)i--;// 省去了等待芯片返回应答的过程。
}bit readbit(void) //ds18b20读取一个二进制位,参照时序图{ uint i;bit dat;ds=0;i++;ds=1;i++,i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar tempread(void) //ds18b20读取一个字节的数据{ uchar i,j,dat;dat=0;for(i=0;i<8;i++){j=readbit();dat=(j<<7)|(dat>>1); //}return(dat);}void tempwrite(uchar dat) //ds18b20写入字节数据{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb==1) // 写1{ds=0; // 拉低总线以开始一个写时序i++;i++;ds=1; // 释放总线i=8;while(i>0)i--;}else // 写0{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tempchang(void) //温度转换{dsreset();delay50us(20);tempwrite(0xcc); //tempwrite(0x44); //}uint gettemp() // 获取温度{uchar a,b;dsreset();delay50us(2000); //延时100毫秒消除恐怖85度tempwrite(0xcc); //tempwrite(0xbe); //a=tempread(); //b=tempread(); //temp=b;temp<<=8; //////temp=temp|a;ftemp=temp*0.0625; //temp=ftemp*10+0.5; //ftemp=ftemp+0.05; //return temp; //}/*------------------检查忙位-----------------------------*/ void chkbusy(){rs=0;rw=1;e=1;P0=0xff ;while((P0&0x80)==0x80);e=0;}/*************读数据************/uchar read(){uchar shuju;chkbusy();P0=0xff;rs=1;rw=1;e=0;delay50us(1);e=1;shuju=P0;// delay(5);e=0;return(shuju);}//增加画点子程序void DrawPoint(uchar X,uchar Y,uchar Color) {uchar Row,Tier,Tier_bit ;uchar ReadOldH,ReadOldL ;writecom(0x34);writecom(0x36);Tier=X>>4 ;Tier_bit=X&0x0f ;if(Y<32){Row=Y ;}else{Row=Y-32 ;Tier+=8 ;}writecom(Row+0x80);writecom(Tier+0x80);read();ReadOldH=read();ReadOldL=read();writecom(Row+0x80);writecom(Tier+0x80);if(Tier_bit<8){switch(Color){case 0 :ReadOldH&=(~(0x01<<(7-Tier_bit))); break ;case 1 :ReadOldH|=(0x01<<(7-Tier_bit)); break ;case 2 :ReadOldH^=(0x01<<(7-Tier_bit)); break ;default :break ;}writedat(ReadOldH);writedat(ReadOldL);}else{switch(Color){case 0 :ReadOldL&=(~(0x01<<(15-Tier_bit))); break ;case 1 :ReadOldL|=(0x01<<(15-Tier_bit)); break ;case 2 :ReadOldL^=(0x01<<(15-Tier_bit)); break ;default :break ;}writedat(ReadOldH);writedat(ReadOldL);}writecom(0x30);}//写命令void writecom(uchar com){chkbusy();rw=0;rs=0;delay50us(1);P0=com;e=1;delay50us(10);e=0;delay50us(10);}//写数据void writedat(uchar dat){chkbusy();rw=0;rs=1;delay50us(1);P0=dat;e=1;delay50us(10);e=0;delay50us(10);}//初始化void initinal(void){delay50us(2);writecom(0x30);delay50us(4);writecom(0x30);delay50us(4);writecom(0x0e);delay50us(4);writecom(0x01);delay50us(240);writecom(0x06);delay50us(10);}void clrscreen(){writecom(0x01);delay50us(10);}//------------------清整个GDRAM空间---------------------------- void clrgdram(){unsigned char x,y ;for(y=0;y<64;y++)for(x=0;x<16;x++){writecom(0x34);writecom(y+0x80);//行地址writecom(x+0x80);//列地址writecom(0x30);writedat(0x00);writedat(0x00);}}//------------------------------------------------------------ //主函数void main(){uchar i,j,e,colour=1;uint a ;rw=0;initinal();clrgdram();delay50us(2);// clrscreen();writecom(0x34);while(1){uint a,b,c,d;DrawPoint(17,6,colour); DrawPoint(17,22,colour); DrawPoint(17,38,colour); DrawPoint(17,54,colour); for(j=16;j<124;j++){DrawPoint(16,j-16,colour); DrawPoint(j,63,colour); DrawPoint(i,e,colour); writecom(0x80); writedat(table[6]); writedat(table[7]); writecom(0x90); writedat(table[5]); writedat(table[1]); writecom(0x88); writedat(table[3]); writedat(table[5]); writecom(0x98); writedat(table[1]); writedat(table[9]);}for(i=16;i<124;i++){tempchang();a=gettemp();e=73-a/10;DrawPoint(i,e,colour); delay50us(10000);b=a/100;c=a%100/10;d=a%100%10; writecom(0x83); writedat(table[b]); delay50us(1); writedat(table[c]); delay50us(1); writedat(table[10]); delay50us(1); writedat(table[d]); delay50us(1); writedat(table[11]); delay50us(4); writecom(0x83); }clrgdram();// writecom(0x36); // delay50us(5);// clrgdram();// clrscreen();// tempchang();// a=gettemp();}}。
电子信息工程专业毕业设计--基于51单片机的12864液晶显示器的设计和研究
目录设计总说明 (I)INTRODUCTION (II)1 绪论 (1)1.1课题背景及研究意义 (1)1.2课题研究的主要内容 (1)1.3国内外发展状况与存在问题 (1)2 总体方案设计与论述 (2)2.1 系统需求分析 (2)2.2 系统总体方案设计 (2)2.2.1 设计方案论证 (2)2.2.2总体结构框图 (3)3系统单元模块设计 (3)3.1系统硬件示意图 (3)3.2主控芯片(STC89C52模块)[5] (4)3.3 时钟控制模块[13] (6)3.3.1 DS1302简介 (6)3.3.2引脚及功能表 (7)3.3.3工作原理 (7)3.3.4 DS1302电路设计图[9] (8)3.4 温度控制模块 (8)3.5 12864接口电路模块 (9)3.6 按键电路模块 (9)3.7 电源电路模块 (10)3.8 印制电路板[9] (10)4系统整体调试与结果分析 (11)4.1 系统总体程序流程介绍 (11)4.2 按键程序设计 (13)4.3 12864驱动程序设计[15] (14)4.3.1 ST7920芯片介绍[14] (14)4.3.2 ST7920驱动程序设计 (17)4.4 12864应用程序设计 (20)4.4.1 文字显示程序设计 (20)4.4.2 点、线显示程序设计 (22)4.4.3 图形、图片显示程序设计 (23)4.5 菜单程序设计 (26)5设计调试及进一步研究 (28)5.1 系统测试 (28)5.1.1 软件调试 (28)5.1.2 硬件调试 (29)5.2 进一步研究的工作 (30)6总结 (30)鸣谢................................................................................................................................ 错误!未定义书签。
12864液晶图像显示图文教程——最全版
由图可以看到水平坐标一个单位是两字节(即 16 位 D15~D0),X 地址会自动加 1,是直接加一个单位 (即两字节 16 位),比如 0001(也即 0X80+000X80+01),从第一行第一列跳到第一行第二列。 代码: void display_image(uchar *p) { uchar i,j; write_cmd(0x34);//扩充指令集动作 write_cmd(0x34);//关绘图显示功能 /*上半屏显示设置*/ for(i=0;i<32;i++)//上半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x80); //水平地址 for(j=0;j<16;j++) { write_data(*p);//连续写入 16 个字节 p++; } } /*下半屏半屏显示设置*/ for(i=0;i<32;i++)//下半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x88);//水平地址 for(j=0;j<16;j++)//连续写入 16 个字节 { write_data(*p); p++; } } write_cmd(0x36);//开绘图显示 write_cmd(0x30);//回到基本指令集 } 源程序: #include <reg52.h> #include "12864.h" X 坐标(水平)方向以 2 字节 Byte 为单位,Y 坐标(垂直) 方向以 1 位 Bit 为单位,先连续写入垂直与水平坐标,再写入 两字节数据到 GDRAM。 这里是这样进行的:i=0 时,j=0,1 时,写入两字节到垂直 (0X80+00)水平(0X80+00)这格(D15~D0)里;然后 X 坐标地址自增 1, 地址变为垂直 (0X80+00) , 水平 (0X80+01) 这格,在 j=2,3 时写入两字节,………一直到垂直(0X80+00) 水平(0X80+07)这格,在 j=14,15 时写入两字节,此时循环 for(j=0;j<16;j++)结束跳出,刚好第一行 128 位写完数据;然后 i++,开始写第二行……
12864液晶电子钟具有按键可调闹钟温度显示
12864液晶电子钟具有按键可调闹钟温度显示理解才是最主要程序已全部通过硬件测试,请放心使用。
(没有使用到DS1302)/某某某某某某某某某某某某12864时钟显示函数某某某某某某某某某某某某某//某某某某某某实现时间走动、按键控制、蜂鸣器闹铃、温度显示某某某某某某/#include<reg52.h>#include<tdio.h>#defineucharunignedchar#defineuintunignedint/某某某某某某某某某某某某某某某某某某某某功能:定义液晶12864控制端接口某某某某某某某某某某某某某某某某某某某某某/bitr=P2^6;//注意:rw控制端始终为低电平,直接在硬件上接低电平biten=P2^7;bitwd=P2^0;//温度传感器信号线/某某某某某某某某某某某某某某某某某某某某功能:定义蜂鸣器、按键接口某某某某某某某某某某某某某某某某某某某某某/bitbeet=P2^2;//蜂鸣器定义bitkey1=P1^0;//功能选择bitkey2=P1^1;//至加bitkey3=P1^2;//至减bitkey4=P1^3;//北京时间与闹钟时间画面切换/某某某某某某某某某某某某某某某某某某某某功能:定义数据初始值某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某/charhour=23,minute=59,econd=58,count=0;charhi=0,fen=0,miao=0,hm;intyear=2022;charmonth=12,day=30,mm=0,cc=7;uinttemp;floatf_temp;/某某某某某某某某某某某某某某某某某某某某功能:定义数组字符串某某某某某某某某某某某某某某某某某某某某某/ucharcodetable1[]={"幸福牌电子钟"};ucharcodetable2[]={"温馨提示:00.0℃"};/某某某某某某某某某某某某某某某某某某某某功能:延时函数某某某某某某某某某某某某某某某某某某某某某某某某某某某/voiddelay(uintz){uint某,y;for(某=z;某>0;某--)for(y=110;y>0;y--);}/某某某某某某某某某某某某某某某某某某某功能:蜂鸣器响应某某某某某某某某某某某某某某某某某某某某某某某/voidfengmingqi(){beet=0;delay(1);beet=1;delay(1);}理解才是最主要/某某某某某某某某某某某某某某某某某某某某功能:液晶12864读写数据某某某某某某某某某某某某某某某某某某/void某ieling_hu(ucharaa,ucharbb){if(aa==1){r=0;}if(aa==0){r=1;}P0=bb;delay(1);en=1;delay(1);en=0;delay(1);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864写入地址某某某某某某某某某某某某某某某某某某/void某ieludizhi(uchar某,uchary){witch(某){cae1:某ieling_hu(1,0某80+y);return;//return返回的意思cae2:某ieling_hu(1,0某90+y);return;cae3:某ieling_hu(1,0某88+y);return;cae4:某ieling_hu(1,0某98+y);return;}}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864写入字符串某某某某某某某某某某某某某某某某某/void某iezifuchuan(uchar某dd){while(某dd!='\0'){某ieling_hu(0,某dd++);}}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864清屏函数某某某某某某某某某某某某某某某某某某某某某/voidqingping(){某ieling_hu(1,0某01);//清屏某ieling_hu(1,0某01);//清屏某ieling_hu(1,0某01);//清屏delay(20);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864初始化指令操作某某某某某某某某某某某某某某某某某某/voidinit_12864(){某ieling_hu(1,0某30);//基本指令操作某ieling_hu(1,0某30);//基本指令操作某ieling_hu(1,0某0C);//0某0c:无光标,O某OF:光标反白显示某ieling_hu(1,0某01);//清屏理解才是最主要某ieling_hu(1,0某06);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864初始化字串显示某某某某某某某某某某某某某某某某某某/voidinit_zifu(){某ieludizhi(1,0);某iezifuchuan("欢迎使用");delay(1);某ieludizhi(2,0);某iezifuchuan("幸福牌电子钟");delay(1);某ieludizhi(3,0);某iezifuchuan("订购热线");delay(1);某ieludizhi(4,0);某iezifuchuan("Phone:0777-66914");delay(9534);qingping();某ieludizhi(1,0);某iezifuchuan(table1);delay(1);某ieludizhi(4,0);某iezifuchuan(table2);delay(1);某ieludizhi(3,5);某iezifuchuan("星期");某ieludizhi(2,2);某iezifuchuan("年月日");}/某某某某某某某某某某某某某某某某某某某功能:时间、年月日显示函数某某某某某某某某某某某某某某某某某某某某/voiddiplay(){某ieludizhi(3,0);//显示时分秒某ieling_hu(0,0某30+hour/10);某ieling_hu(0,0某30+hour%10);某ieling_hu(0,':');某ieling_hu(0,0某30+minute/10);某ieling_hu(0,0某30+minute%10);某ieling_hu(0,':');某ieling_hu(0,0某30+econd/10);某ieling_hu(0,0某30+econd%10);某ieludizhi(2,0);//显示年某ieling_hu(0,0某30+year/1000);某ieling_hu(0,0某30+year%1000/100);某ieling_hu(0,0某30+year%100/10);某ieling_hu(0,0某30+year%10);某ieludizhi(2,3);//显示月某ieling_hu(0,0某30+month/10);某ieling_hu(0,0某30+month%10);某ieludizhi(2,5);//显示日某ieling_hu(0,0某30+day/10);某ieling_hu(0,0某30+day%10);}/某某某某某某某某某某某某某某某某某某某功能:闹钟(时间、年月日)显示函数某某某某某某某某某某某某某某某某某某某某/voiddiplay1(){理解才是最主要某ieludizhi(3,0);//显示时分秒某ieling_hu(0,0某30+hi/10);某ieling_hu(0,0某30+hi%10);某ieling_hu(0,':');某ieling_hu(0,0某30+fen/10);某ieling_hu(0,0某30+fen%10);某ieling_hu(0,':');某ieling_hu(0,0某30+miao/10);某ieling_hu(0,0某30+miao%10);某ieludizhi(2,0);//显示年某ieling_hu(0,0某30+year/1000);某ieling_hu(0,0某30+year%1000/100);某ieling_hu(0,0某30+year%100/10);某ieling_hu(0,0某30+year%10);某ieludizhi(2,3);//显示月某ieling_hu(0,0某30+month/10);某ieling_hu(0,0某30+month%10);某ieludizhi(2,5);//显示日某ieling_hu(0,0某30+day/10);某ieling_hu(0,0某30+day%10);}/某某某某某某某某某某某某某某某某某某某功能:星期函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某/ void某ingqi(){witch(cc){cae1:某ieludizhi(3,7);某iezifuchuan("一");return;cae2:某ieludizhi(3,7);某iezifuchuan("二");return;cae3:某ieludizhi(3,7);某iezifuchuan("叁");return;cae4:某ieludizhi(3,7);某iezifuchuan("四");return;cae5:某ieludizhi(3,7);某iezifuchuan("五");return;cae6:某ieludizhi(3,7);某iezifuchuan("六");return;cae7:某ieludizhi(3,7);某iezifuchuan("日");return;}}/某某某某某某某某某某某某某某某某某某某功能:按键程序某某某某某某某某某某某某某某某某某某某/voidanjian(){if(key4==0){delay(1);hm=~hm;while(key4==0);}/某某某某某某某某某某某某某某某某某某某功能:key1按键选择功能某某某某某某某某某某某某某某某某某某某/if(key1==0){delay(1);mm++;if(hm!=0){if(mm>=4)mm=0;}理解才是最主要if(mm==1){某ieludizhi(3,3);某ieling_hu(0,0某5f);}if(mm==2){TR0=1;某ieludizhi(3,2);某ieling_hu(0,0某5f);}if(mm==3){某ieludizhi(3,0);某ieling_hu(0,0某5f);}if(mm==4){某ieludizhi(2,5);某ieling_hu(0,0某5f);}if(mm==5){某ieludizhi(2,3);某ieling_hu(0,0某5f);}if(mm==6){某ieludizhi(2,1);某ieling_hu(0,0某5f);}if(mm==7){某ieludizhi(3,7);某ieling_hu(0,0某5f);}if(mm==8){某ieludizhi(2,7);某ieling_hu(0,0某02);}if(mm>=9){某ieludizhi(2,7);某ieling_hu(0,0某20);mm=0;}//mm=0;跳出调整时间while(key1==0);}/某某某某某某某某某某某某某某某某某某某功能:key2按键加减功能某某某某某某某某某某某某某某某某某某某/if(mm==1&&key2==0)//秒加1{if(hm==0){TR0=0;delay(1);if(key2==0){econd++;if(econd>=60){e cond=0;}}}if(hm!=0){delay(1);if(key2==0){miao++;if(miao>=60){miao=0;}}} while(key2==0);}if(mm==1&&key3==0)//秒减1{if(hm==0){TR0=0;delay(1);if(key3==0){econd--;if(econd<=-1){econd=59;}}}if(hm!=0){delay(1);if(key3==0){miao--;if(miao<=-1){miao=59;}}}while(key3==0);}if(mm==2&&key2==0)//分加1{if(hm==0){delay(1);if(key2==0){minute++;if(minute>=60){minut e=0;}}}if(hm!=0){delay(1);if(key2==0){fen++;if(fen>=60){fen=0;}}}while(key2==0);}if(mm==2&&key3==0)//分减1{if(hm==0){delay(1);if(key3==0){minute--;if(minute<=-1){minute=59;}}}if(hm!=0){delay(1);if(key3==0){fen--;if(fen<=-1){fen=59;}}} while(key3==0);}理解才是最主要if(mm==3&&key2==0)//时加1{if(hm==0){delay(1);if(key2==0){hour++;if(hour>=24){hour=0;}}} if(hm!=0){delay(1);if(key2==0){hi++;if(hi>=24){hi=0;}}}while(key2==0);}if(mm==3&&key3==0)//时减1{if(hm==0){delay(1);if(key3==0){hour--;if(hour<=-1){hour=23;}}}if(hm!=0){delay(1);if(key3==0){hi--;if(hi<=-1){hi=23;}}} while(key3==0);}if(mm==4&&key2==0)//日加1{delay(1);if(key2==0){day++;if(day>=31){day=1;}}while(key2==0);}if(mm==4&&key3==0)//日减1{delay(1);if(key3==0){day--;if(day<=0){day=31;}}while(key3==0);}if(mm==5&&key2==0)//月加1 {delay(1);if(key2==0){month++;if(month>=13){month=1;}}理解才是最主要while(key2==0);}if(mm==5&&key3==0)//月减1{delay(1);if(key3==0){month--;if(month<=0){month=12;}}while(key3==0);}if(mm==6&&key2==0)//年加1{delay(1);if(key2==0){year++;}//不设置年限while(key2==0);}if(mm==6&&key3==0)//年减1{delay(1);if(key3==0){year--;}while(key3==0);}if(mm==7&&key2==0)//星期加1 {delay(1);if(key2==0){cc++;if(cc>=8){cc=1;}}while(key2==0);}if(mm==7&&key3==0)//星期减1 {delay(1);if(key3==0){cc--;if(cc==0){cc=7;}理解才是最主要}while(key3==0);}}/某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某功能:18B20所有函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//某某某某某某某某某某某某某某某某某某某18B20复位,初始化函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voiddreet(void){uinti;wd=0;i=103;while(i>0)i--;wd=1;i=4;while(i>0)i--;}/某某某某某某某某某某某某某某某某某某某18B20读1位函数某某某某某某某某某某某某某某某某某某某某某某某某某某/bittempreadbit(void){uinti;bitdat;wd=0;i++;//i++起延时作用wd=1;i++;i++;dat=wd;i=8;while(i>0)i--;return(dat);}/某某某某某某某某某某某某某某某某某某某18B20读1个字节函数某某某某某某某某某某某某某某某某某某某某某某某某某某/uchartempread(void){uchari,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);理解才是最主要}/某某某某某某某某某某某某某某某某某某某18B20写一个字节数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voidtempwritebyte(uchardat){uinti;ucharj;bittetb;for(j=1;j<=8;j++){tetb=dat&0某01;dat=dat>>1;if(tetb)//写1{wd=0;i++;i++;wd=1;i=8;while(i>0)i--;}ele{wd=0;//写0i=8;while(i>0)i--;wd=1;i++;i++;}}}/某某某某某某某某某某某某某某某某某某某18B20开始获取温度并转换函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voidtempchange(void){dreet();delay(1);tempwritebyte(0某cc);//写跳过读ROM指令tempwritebyte(0某44);//写温度转换指令}/某某某某某某某某某某某某某某某某某某某18B20读取寄存器中存储的温度数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/uintget_temp(){uchara,b;dreet();delay(1);理解才是最主要tempwritebyte(0某cc);tempwritebyte(0某be);a=tempread();//读低8位b=tempread();//读高8位temp=b;temp<<=8;//两个字节组合为1个字temp=temp|a;f_temp=temp某0.0625;//温度在寄存器中为12位分辨率位0.0625°temp=f_temp某10+0.5;//乘以10表示小数点后面只取1位,加0.5是四舍五入f_temp=f_temp+0.05;returntemp;//temp是整型}/某某某某某某某某某某某某某某某某某某某18B20发送数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/{do{SBUF=某parr++;//发送数据while(!TI);//等待发送完成标志为1TI=0;//标志清零}while(某parr);//保持循环直到字符为'\0'}/某某某某某某某某某某某某某某某某某某某某某某某某功能:主函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某/ voidmain(){ucharbuff[4];TMOD=0某01;//设置T0为工作方式1EA=1;ET0=1;TR0=1;//开启T0中断TH0=-50000/256;TL0=-50000%256;init_12864();init_zifu();hm=0;while(1){if(count>5&&count<18){tempchange();//开始获取温度get_temp();//读取寄存温度printf(buff,"%f",f_temp);某ieludizhi(4,5);某ieling_hu(0,0某30+temp/100);某ieling_hu(0,0某30+temp%100/10);理解才是最主要某ieling_hu(0,0某2e);某ieling_hu(0,0某30+temp%100%10);}if(hm==0)diplay();//如果hm=0显示北京时间,否则显示闹钟时间elediplay1();anjian();//按键判断某ingqi();//显示星期if(minute==59&&econd==59){fengmingqi();}//整点报时if(hi==hour&&fen==minute&&miao>=econd&&miao<=econd+3){fengmi ngqi();}//闹钟}}/某某某某某某某某某某某某某某某某某某某某某某某某功能:中断函数某某某某某某某某某某某某某某某某某某某某某某某某某某/ {TH0=-50000/256;TL0=-50000%256;count++;if(count==20){count=0;econd++;if(econd==60){econd=0;minute++;if(minute==60) {minute=0;hour++;if(hour==24){hour=0;day++;cc++;if(cc==8)cc=1; if(day==31){day=1;month++;if(month==13)理解才是最主要{month=1;year++; }}} } } } }。
12864LCD上显示温湿度
12864LCD显示温湿度第一种方式:/**********************DHT11与12864LCD************************/ #include <>#define uchar unsigned char#define uint unsigned intuchar lcd_x,lcd_y,data_byte=0,count;uint TH_data,TL_data,RH_data,RL_data,CK_data;uint TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;uchar num;sbit RS = P2^0;;uchar wendu[6];uchar shidu[6];/********************************************************1ms延时函数********************************************************/void delay(int z){ int x,y;for(x=z;x>0;x--)for(y=125;y>0;y--); }/********************************************************50us延时函数********************************************************/void delay_50us(uint t){uint j;for(;t>0;t--)for(j=19;j>0;j--);}/********************************************************50ms延时函数********************************************************/ void delay_50ms(uint t){uint j;for(;t>0;t--)for(j=6245;j>0;j--);}/********************************************************12864液晶写指令********************************************************/ void write_12864com(uchar com){ lcdrs=0;lcdrw=0;delay_50us(1);P0=com;lcden=1;delay_50us(10);lcden=0;delay_50us(2);}/********************************************************12864液晶写数据********************************************************/ void write_dat(ucha r dat) { lcdrs=1;lcdrw=0;delay_50us(1);P0=dat;lcden=1;delay_50us(10);lcden=0;delay_50us(2); }/********************************************************12864液晶初始化********************************************************/void init12864lcd(void) {delay_50ms(2);write_12864com(0x30);delay_50us(4);write_12864com(0x30);delay_50us(4);write_12864com(0x0f);delay_50us(4);write_12864com(0x01);delay_50us(240);write_12864com(0x06);delay_50us(10);write_12864com(0x0c);delay_50us(10); }/********************************************************12864液晶显示函数********************************************************/ void display1(void){uchar i;write_12864com(0x80);for(i=0;i<18;i++){write_dat(table2[i]);delay_50us(1); } }/********************************************************12864液晶显示函数********************************************************/ void display2(void){uchar i;write_12864com(0x90);for(i=0;i<18;i++){write_dat(table3[i]);delay_50us(1); } }/********************************************************12864液晶显示函数********************************************************/ void display3(void){ uchar i;write_12864com(0x88);for(i=0;i<8;i++){ write_dat(table4[i]);delay_50us(1); }}/********************************************************12864液晶显示函数********************************************************/ void displaywendu(void){ uchar i;write_12864com(0x94);for(i=0;i<3;i++){ write_dat(wendu[i]);delay_50us(1);}for(i=0;i<1;i++){write_dat(table5[i]);delay_50us(1);}for(i=4;i<5;i++){write_dat(wendu[i]);delay_50us(1); } }/********************************************************12864液晶显示函数********************************************************/ void displayshidu(void) {uchar i;write_12864com(0x8C);for(i=0;i<3;i++) {write_dat(shidu[i]);delay_50us(1); }for(i=0;i<1;i++){ write_dat(table5[i]);delay_50us(1);}for(i=4;i<5;i++){write_dat(shidu[i]);delay_50us(1);} }/********************************************************SHT11写字节程序********************************************************/char s_write_byte(unsigned char value){unsigned char i,error=0;for (i=0x80;i>0;i>>=1) //高位为1,循环右移{ if (i&value) DATA=1; //和要发送的数相与,结果为发送的位else DATA=0;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;}DATA=1; //释放数据线SCK=1;error=DATA; //检查应答信号,确认通讯正常_nop_();_nop_();_nop_();SCK=0;DATA=1;return error; //error=1 通讯错误}/********************************************************SHT11读字节程序********************************************************/char s_read_byte(unsigned char ack){unsigned char i,val=0;DATA=1; //释放数据线for(i=0x80;i>0;i>>=1) //高位为1,循环右移{SCK=1;if(DATA)val=(val|i); //读一位数据线的值SCK=0; }DATA=!ack; //如果是校验,读取完后结束通讯;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;_nop_();_nop_();_nop_();DATA=1; //释放数据线return val; }/********************************************************SHT11启动传输********************************************************/void s_transstart(void){DATA=1;SCK=0; //准备_nop_();SCK=1;_nop_();DATA=0;_nop_();SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();DATA=1;_nop_();SCK=0; }/********************************************************SHT11连接复位********************************************************/void s_connectionreset(void){ unsigned char i;DATA=1;SCK=0; //准备for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位{ SCK=1;SCK=0;}s_transstart(); //启动传输}/********************************************************SHT11温湿度检测********************************************************/char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsign ed char mode){unsigned error=0;unsigned int i;s_transstart(); //启动传输switch(mode) //选择发送命令{ case TEMP : error+=s_write_byte(MEASURE_TEMP);break; //测量温度case HUMI : error+=s_write_byte(MEASURE_HUMI);break; //测量湿度default : break;}for (i=0;i<65535;i++)if(DATA==0) break; //等待测量结束if(DATA) error+=1;// 如果长时间数据线没有拉低,说明测量错误*(p_value) =s_read_byte(ACK); //读第一个字节,高字节(MSB)*(p_value+1)=s_read_byte(ACK); //读第二个字节,低字节(LSB)*p_checksum =s_read_byte(noACK); //read CRC校验码return error; // error=1 通讯错误}/********************************************************SHT11温湿度值标度变换及温度补偿********************************************************/ void calc_sth10(flo at *p_humidity ,float *p_temperature){const float C1=; // 12位湿度精度修正公式const float C2=+; // 12位湿度精度修正公式const float C3=; // 12位湿度精度修正公式const float T1=+; // 14位温度精度5V条件修正公式const float T2=+; // 14位温度精度5V条件修正公式float rh=*p_humidity; // rh: 12位湿度float t=*p_temperature; // t: 14位温度float rh_lin; // rh_lin: 湿度linear值float rh_true; // rh_true: 湿度ture 值float t_C; // t_C : 温度℃t_C=t* - 40; //补偿温度rh_lin=C3*rh*rh + C2*rh + C1; //相对湿度非线性补偿rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度对于温度依赖性补偿if(rh_true>100)rh_true=100; //湿度最大修正if(rh_true<rh_true=; //湿度最小修正*p_temperature=t_C; //返回温度结果*p_humidity=rh_true; //返回湿度结果}/********************************************************主函数********************************************************/void main(void){unsigned int temp,humi;value humi_val,temp_val; //定义两个共同体,一个用于湿度,一个用于温度unsigned char error; //用于检验是否出现错误unsigned char checksum; //CRCinit12864lcd();display1();display2();display3();s_connectionreset(); //启动连接复位while(1){error=0; //初始化error=0,即没有错误error+=s_measure((unsigned char*)&,&checksum,TEMP); //温度测量error+=s_measure((unsigned char*)&,&checksum,HUMI); //湿度测量if(error!=0) s_connectionreset(); ////如果发生错误,系统复位else{=(float); //转换为浮点数=(float); //转换为浮点数calc_sth10(&,&; //修正相对湿度及温度temp=*10;humi=*10;wendu[0]=temp/1000+'0'; //温度百位wendu[1]=temp%1000/100+'0'; //温度十位wendu[2]=temp%100/10+'0'; //温度个位wendu[3]=0x2E; //小数点wendu[4]=temp%10+'0'; //温度小数点后第一位displaywendu();shidu[0]=humi/1000+'0'; //湿度百位shidu[1]=humi%1000/100+'0'; //湿度十位shidu[2]=humi%100/10+'0'; //湿度个位shidu[3]=0x2E; //小数点shidu[4]=humi%10+'0'; //湿度小数点后第一位displayshidu(); }Delay(800);//等待足够长的时间,以现行下一次转换}}。
LCD12864显示实时时钟例程可运行
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}void Write_DS1302(uchar add,uchar dat)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
12864LCD液晶显示原理及使用方法
12864L CD液晶显示原理及使用方法液晶简介液晶是一种在一定温度范围内呈现既不同于固态液态又不同于气态的特殊物质态,它既具有各向异性的晶体所特有的双折射性又具有液体的流动性液晶显示器件(英文的简写为L CD)就是利用液晶态物质的液晶分子排列状态在电场中改变而调制外界光的被动型显示器件。
点阵式图形液晶显示屏是LCD 的一种能够动态显示图形汉字以及各种符号信息为各种电子产品提供了友好的人机界面点阵式图形液晶显示屏的主要特点如下(这些特点也就是LCD的特点):工作电压低、微功耗、体积小、可视面积大、无电磁辐射、数字接口、寿命长等特点。
12864L CD是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器及128×64 全点阵液晶显示器组成。
可完成图形显示,也可以显示8×4 个(16×16 点阵)汉字或者显示16×4个(8×16 点阵)ASCII码。
分为两种,带字库的和不带字库的。
不带字库的L CD需要自己提供字库字模,此时可以根据个人喜好设置各种字体显示风格,设计上较为灵活。
带字库的LCD提供字库字模,但是只能显示GB2312的宋体。
各有优缺点,根据不同应用场景灵活选择。
其液晶模块原理图如下所示。
12864L CD点阵图形液晶模块原理框图下面给出了其应用连接电路,分别介绍其各引脚的功能和作用。
如下表所示:12864L CD 的引脚说明管脚号管脚名称LEVER 管脚功能描述1GND 0 电源地2VCC+5.0V 电源电压3VLCD- 液晶显示器驱动电压4RS (D/I)H/LD/I=“H”,表示DB7∽DB0 为显示数据D/I=“L”,表示DB7∽DB0 为显示指令数据5R/WH/LR/W=“H”,E=“H”数据被读到D B7∽DB0R/W=“L”,E=“H→L”数据被写到IR或DR6EN H/LR/W=“L”,E 信号下降沿锁存DB7∽DB0R/W=“H”,E=“H”DDRAM数据读到DB7∽DB0 7DB0 H/L 数据线8DB1 H/L数据线9DB2 H/L 数据线10DB3H/L 数据线11DB4H/L数据线12DB5H/L数据线13DB6H/L数据线14DB7H/L数据线15CS1H/L H:选择芯片(右半屏)信号16CS2H/L H:选择芯片(左半屏)信号17RETH/L复位信号,低电平复位18VEE -10VLCD驱动负电压19LED+- LED 背光板电源20LED-- LED 背光板电源12864L CD点阵图形液晶模块应用连接电路液晶驱动设置在理解12864LCD硬件原理和管脚功能之后,可以针对LCD进行驱动的编写,分两种情况:仿真环境下和实物开发板编程。
12864汉字液晶显示--按键电子时钟程序(具有闪烁,移位,加一,减一功能)
//12864汉字液晶显示--按键电子时钟程序(具有闪烁,移位,加一,减一功能)#include <reg52.h>#include <intrins.h>#define uchar unsigned charvoid lcd_ini();void ascii_change(void);void delay();void wri_add(uchar com);void wri_dat(uchar com1);void shan(void);void disp();void tkey(void);sbit cs=P1^7;sbit sid=P1^6;sbit sclk=P1^5;bit flag=1;uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态uchar data clock[3]={23,45,12};uchar code clockname[10]={"北京时间:"};uchar data num[6];/*******主程序*************/void main(){lcd_ini();count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒TMOD=0x01;TL0=0XB0;TH0=0X3C;EA=1;ET0=1;IT0=1;EX0=1;TR0=1;while(1){back:ascii_change();disp();delay();if(flag==1)goto back;tkey();shan();delay();}}/****lcd初始化*******/void lcd_ini(){wri_add(0x30);delay();wri_add(0x0c);delay();wri_add(0x01);delay();wri_add(0x06);delay();}/********定时程序*************/ void timer1() interrupt 1 using 2 {TL0=0XB0;TH0=0X3C;count--;if(count==0){count=10;clock[2]++;//秒//}elsegoto out;if(clock[2]==60){clock[2]=0;clock[1]++;//分//}if(clock[1]==60){clock[1]=0;clock[0]++;}if(clock[0]==24)//时//clock[0]=0;out:_nop_();}/*******十位个位转换成ASCII码************/ void ascii_change(void){num[5]=clock[2]-(clock[2]/10)*10+0x30;num[4]=clock[2]/10+0x30;num[3]=clock[1]-(clock[1]/10)*10+0x30;num[2]=clock[1]/10+0x30;num[1]=clock[0]-(clock[0]/10)*10+0x30;num[0]=clock[0]/10+0x30;}/********廷时程序*************/void delay(){uchar i,j;for (i=250;i>0;i--)for (j=250;j>0;j--);}/*****Write address*********/void wri_add(uchar com){uchar i,j,k;cs=0;cs=1;dat=0xf8;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/*********Write data*************/ void wri_dat(uchar com1){uchar i,j,k;cs=0;cs=1;dat=0xfa;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/******display program***********/ void disp(){uchar i,k=0;wri_add(0x80);for (i=1;i<=9;i++)wri_dat(clockname[i-1]);wri_add(0x90);for (i=1;i<=6;i++) {k++;if(k==3||k==5)wri_dat(clockname[8]);//时间之间的冒号。
12864显示温度
/**************************************/ #include<STC12C5A60S2.h>#include<intrins.h>#include<math.h>#include<stdlib.h>/**************************************/ #define uchar unsigned char#define uint unsigned int#define nops(); {_nop_();_nop_();_nop_();_nop_();}//端口定义sbit LCD_CS=P3^5;sbit LCD_SID=P3^6; //串行数据线sbit LCD_SCLK=P3^4; //串上时钟输入sbitdq = P2^2;uchar a=0;int flag=0;ucharw,m,n;uchar num1=0;/**************************************/ //延时函数/**************************************/ void delay(unsigned int n){while (n--);}voidDelay_nms(uchar n){uchari;uchar j;for(i=0;i<n;i++)for(j=0;j<125;j++) //大概1ms_nop_();}voiddelay_ms(unsigned int t){unsigned char m = 120;while(t--)while(m--);}/**************************************///串行发送一个字节/**************************************/voidLCD_sendbyte(uchar byte){uchari;for(i=0;i<8;i++){LCD_SCLK=0; //拉低时钟线_nop_();LCD_SID=(bit)(byte&0x80); //发送最高位数据LCD_SCLK=1; //上升沿发送数据byte=byte<<1; //左移一位}}/****************************************///写指令/****************************************/voidLCD_write_com(uchar com){LCD_CS=1;LCD_sendbyte(0xf8); //送入5个连续的“1“,启动一个周期,11111,RW(0),RS(0),0 LCD_sendbyte(0xf0&com); //取高四位,数据分两次传送,//每个字节的内容被送入两个字节//高四位放在第一个字节的高四位LCD_sendbyte(0xf0&(com<<4)); //低四位放在第二个字节的高四位LCD_CS=0;Delay_nms(10); //串行不支持读操作,不可检测忙操作,这里用延时替代}/******************************************///写数据/******************************************/voidLCD_write_dat(uchardat){LCD_CS=1;LCD_sendbyte(0xfa); //送入5个连续的“1“,启动一个周期,11111,RW(0),RS(1),0 LCD_sendbyte(0xf0&dat); //取高四位,数据分两次传送,//每个字节的内容被送入两个字节//高四位放在第一个字节的高四位LCD_sendbyte(0xf0&(dat<<4)); //低四位放在第二个字节LCD_CS=0;Delay_nms(10);/********************************************///LCD初始化/********************************************/voidLCD_init(void){LCD_write_com(0x30); //选择基本指令集LCD_write_com(0x0c); //开显示,无游标,不反白LCD_write_com(0x01); //清除显示屏幕,把DDRAM位址计数器调整为00H Delay_nms(5); //清屏操作时间较长1.6ms 因此加此延时LCD_write_com(0x02); //清DDRAM位址归位,此处貌似与清屏重复LCD_write_com(0x06); //设定光标右移,整体显示不移动}/** UART初始化* 波特率:9600*/voidUART_init(void){SCON = 0x50; // 10位uart,允许串行接受TMOD |= 0x20; // 定时器1工作在方式2(自动重装)TH1 = 0xFD;TL1 = 0xFD;ES = 1;TR1 = 1;EA = 1;}/** UART 发送一字节*/voidUART_send_byte(intdat){SBUF = dat;while (TI == 0);TI = 0;}/********************************************///18B20初始时序/********************************************/void init_18b20(void){bit flag1 = 1;while(flag1){while(flag1){dq = 1;delay(1);dq = 0;delay(250);dq = 1;delay(30);flag1 = dq;//UART_send_byte(0x80);} //UART_send_byte(0x81);delay(225);flag1 = ~dq;} // UART_send_byte(0x82);dq = 1;}void write_18b20(unsigned char com) {unsigned char i;for(i = 8;i > 0;i--){dq = 1;_nop_();dq = 0;nops();dq = com & 0x01;delay(30);com>>= 1;}dq = 1;delay(1);}unsigned char read_18b20(void){unsigned char i;unsigned char dat = 0;for(i = 8;i > 0;i--){dq = 1;_nop_();dat>>= 1;dq = 0;nops();dq = 1;nops();if(dq)dat |= 0x80;delay(30);}dq = 1;returndat;}void start_18b20(void){init_18b20();write_18b20(0xcc);write_18b20(0x44);}int read_18b20_temp(void){unsigned char temp_data[2];unsignedint temp;init_18b20();write_18b20(0xcc);write_18b20(0xbe);temp_data[0] = read_18b20();temp_data[1] = read_18b20();temp = temp_data[1];temp<<= 8;temp |= temp_data[0];temp>>= 4;return temp;}//***************************************************************************** *********************//任意位置显示字符串//***************************************************************************** *********************void dis(ucharx,uchary,uchar code *s){ //x为横坐标,y位纵坐标,*s表示指针,为数据的首地址switch(y) //选择纵坐标{case 0: LCD_write_com(0x80+x);break; //第1行case 1: LCD_write_com(0x90+x);break; //第2行case 2: LCD_write_com(0x88+x);break; //第3行case 3:LCD_write_com(0x98+x);break; //第4行default:break;}while(*s>0) //写入数据,直到数据为空{LCD_write_dat(*s); //写数据Delay_nms(5); //等待写入s++; //下一字符}}//***************************************************************************** *********************//主函数//***************************************************************************** *********************main(){intans;LCD_init();UART_init(); //初始化液晶while(1) //进入死循环,防止看门狗复位{start_18b20();delay_ms(1000);ans = read_18b20_temp();UART_send_byte(ans);w=ans;dis(0,0,"**公司"); //显示第1行dis(0,1,"工资:"); //显示第2行LCD_write_dat(0x30+w/10);LCD_write_dat(0x30+w%10);dis(6,1,"℃");dis(0,2,"当前温度:℃"); //显示第3行dis(0,3,"当前湿度:%RH"); //显示第4行}}voidser() interrupt 4{RI=0;a=SBUF; }。
12864中文资料
12864液晶名称含义12864是128*64点阵液晶模块的点阵数简称,业界约定俗成的简称。
基本参数液晶屏类型 STN FSTN模块显示效果:黄绿底黑字蓝底白字白底黑字视角6点钟12点钟驱动方式 1/64 DUTY 1/9 BIAS背光LED白色LED黄绿色控制器KS0108或兼容ST7920 T6963C数据总线 8 位并口/6800 方式串口温度特性工作温度:-20℃~+70℃ 储藏温度:-30℃~+80℃点阵格式 128 x 64基本用途:该点阵的屏显成本相对较低,适用于各类仪器,小型设备的显示领域。
基本用途:该点阵的屏显成本相对较低,适用于各类仪器,小型设备的显示领域。
液晶模组使用注意事项1 当您在你的产品设计中使用本液晶模组,注意液晶的视角与你的产品用途相一致。
2 液晶屏是玻璃为基础的,跌落或与硬物撞击会引起液晶屏破裂或粉碎。
尤其是边角处。
3 尽管在液晶表面的偏振片有抑制反光的表层,应当小心不要划伤表面,一般推荐在液晶表面采用透明塑胶材料的保护屏。
4 如果液晶模组储藏在低于规定的温度以下,液晶材料会凝结而性能恶化。
如果液晶模组储藏在高于规定的温度以上,液晶材料的分子排列方向会转变为液态,可能无法恢复到原来的状态。
超出温度和湿度范围,会引起偏振片剥落或起泡。
因此,液晶模组应储藏在规定的温度范围。
5 如液晶表面遇口水或滴水,应立即擦除,避免长时间过后引起色彩变化或留下污点。
水蒸气会引起ITO电极腐蚀。
6 如果需要清洁液晶屏表面,应该用棉或软布轻快地擦拭,仍不能清除时,呵气之后再擦拭。
7 液晶模组的驱动应遵照规定的额定指标,避免故障及永久损坏。
对液晶材料施加直流电压,会引起液晶材料迅速恶化,应该确保提供交流波形的M信号的连续应用。
特别是,在电源开关时应遵照供电顺序,避免驱动锁存及直流直接加至液晶屏。
8 机械注意事项:a) 液晶模组是在高精度下调试安装的。
避免外力撞击,不要对其改变或修改。
b) 不要篡改金属框的任何突出部分。
LCD12864显示实时时钟例程可运行
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}void Write_DS1302(uchar add,uchar dat)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
毕业设计—基于单片机的12864时钟显示
学士学位毕业论文(设计)题目:基于单片机的12864时钟显示摘要电子时钟是一种非常广泛日常计时工具,给人们的带来了很大的方便,在社会上越来越流行。
它可以对年、月、日、星期、时、分、秒进行计时,采用直观的数字显示,可以同时显示年月日时分秒等信息,还有时间校准等功能。
该电子时钟主要采用STC89C52单片机作为主控核心,用DS1302时钟芯片作为时钟、液晶12864显示屏显示。
STC89C52单片机是由深圳宏晶科技公司推出的,功耗小,电压可选用4~6V电压供电;DS1302时钟芯片是美国DALLAS公司推出的具有细电流充电功能的低功耗实时时钟芯片,它可以对年、月、日、星期、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小;数字显示是采用的12864液晶显示屏来显示,可以同时显示年、月、日、星期、时、分、秒等信息。
此外,该电子时钟还具有时间校准等功能。
关键词:STC89C51单片机,DS1302时钟芯片,液晶12864AbstractElectronic clock is a very extensive daily timing tool, to the people has brought great convenience, more and more popular in the community. It can be the year, month, date, day, hour, minute, second for a time, using intuitive digital display, can display information such as year, month, day, hour, and time alignment functions. The electronic clock is used mainly as a master STC89C52 microcontroller core, with theDS1302 clock chip as a clock, LCD display12864. STC89C52 SCM is a Shenzhen Hong Crystal Technology has introduced, power consumption, voltage can be selected 4 ~ 6V voltage power supply; DS1302 clock chip is American DALLAS company launched with a fine current charging low-power real-time clock chip, it can year, month, date, day, hour, minute, second for a time, also has a leap year compensation and other functions, DS1302 and long life, small error; 12864 LCD digital display isused to display that can display year, month, date, day, hour, minute, second and so on. In addition, the electronic clock also has a time calibration function.Key Words:STC89C51 microcontroller, DS1302 clock chip, LCD 12864目录1绪论 (3)1.1时钟发展史 (3)1.2 目前的研究现状 (4)1.3研究目的及意义 (4)2 总体方案设计 (5)2.1 方案的选择 (5)2.1.1设计要求 (5)2.1.2方案的选择 (5)2.2总体方案组成框图 (6)3系统硬件设计 (6)3. 1主芯片模块 (6)3.1.1 中断系统 (8)3.1.2常用寄存器 (8)3.2晶振和复位电路 (10)3.2.1晶振电路 (10)3.2.2复位电路 (11)3.3 DS1302时钟芯片电路 (11)3.3.1 DS1302引脚图 (11)3.3.2 DS1302寄存器 (12)3.3.3 DS1302外围电路 (13)3.4 LCD12864显示模块 (13)3.4.1 LCD12864引脚功能 (13)3.4.2 LCD12864指令说明 (14)3.4.3 LCD12864电路接线 (15)3.5 红外遥控模块 (16)4 系统软件设计 (17)4.1 主程序设计 (17)4.2 LCD12864驱动程序 (19)4.3 DS1302驱动程序 (21)4.4 红外遥控程序 (24)5 调试结果 (25)5.1 正常显示日期时间画面 (26)5.2 进入调整时间日期画面 (26)5.3图片显示画面 (26)6总结 (27)致谢 (28)参考文献 (29)附录一 (31)附录二 (32)1绪论1.1时钟发展史很早以前,人类主要是利用天文现象和流动物质的连续运动来计时。
基于51单片机的12864显示温度(ds18b20)
#ifndef __LCD12864_H#define __LCD12864_H//---包含头文件---//#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//---如果使用画图模式定义这个---//#define LCD12864_PICTURE//---定义使用的IO口---//#define LCD12864_DATAPORT P1 //数据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^4; //复位端//---声明全局函数---//void LCD12864_Delay1ms(uint c);uchar LCD12864_Busy(void);void LCD12864_WriteCmd(uchar cmd);void LCD12864_WriteData(uchar dat);void LCD12864_Init();void LCD12864_ClearScreen(void);void LCD12864_SetWindow(uchar x, uchar y);void LCD12864_DrowPic(uchar *a);void LCD12864_DrowPoint(uchar x, uchar y);#endif#ifndef __TEMP_H_#define __TEMP_H_#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//--定义使用的IO口--//sbit DSPORT=P3^3;//--声明全局函数--//void Delay1ms(uint );uchar Ds18b20Init();void Ds18b20WriteByte(uchar com);uchar Ds18b20ReadByte();void Ds18b20ChangTemp();void Ds18b20ReadTempCom();int Ds18b20ReadTemp();#endif#include"lcd12864.h"/****************************************************************************** ** 函数名: LCD12864_Delay1ms* 函数功能: 延时1MS* 输入: c* 输出: 无******************************************************************************* /void LCD12864_Delay1ms(uint c)uchar a,b;for(; c>0; c--){for(b=199; b>0; b--){for(a=1; a>0; a--);}}}/****************************************************************************** ** 函数名: LCD12864_Busy* 函数功能: 检测LCD是否忙* 输入: 无* 输出: 1或0(1表示不忙,0表示忙)******************************************************************************* /uchar LCD12864_Busy(void){uchar i = 0;LCD12864_RS = 0; //选择命令LCD12864_RW = 1; //选择读取LCD12864_EN = 1;LCD12864_Delay1ms(1);while((LCD12864_DA TAPORT & 0x80) == 0x80) //检测读取到的值{i++;if(i > 100){LCD12864_EN = 0;return 0; //超过等待时间返回0表示失败}}LCD12864_EN = 0;return 1;}/****************************************************************************** ** 函数名: LCD12864_WriteCmd* 函数功能: 写命令* 输入: cmd* 输出: 无******************************************************************************* /void LCD12864_WriteCmd(uchar cmd){uchar i;i = 0;while( LCD12864_Busy() == 0){LCD12864_Delay1ms(1);i++;if( i>100){return; //超过等待退出}}LCD12864_RS = 0; //选择命令LCD12864_RW = 0; //选择写入LCD12864_EN = 0; //初始化使能端LCD12864_DATAPORT = cmd; //放置数据LCD12864_EN = 1; //写时序LCD12864_Delay1ms(1);LCD12864_EN = 0;}/****************************************************************************** ** 函数名: LCD12864_WriteData* 函数功能: 写数据* 输入: dat* 输出: 无******************************************************************************* /void LCD12864_WriteData(uchar dat){uchar i;i = 0;while( LCD12864_Busy() == 0){LCD12864_Delay1ms(1);i++;if( i>100){return; //超过等待退出}}LCD12864_RS = 1; //选择数据LCD12864_RW = 0; //选择写入LCD12864_EN = 0; //初始化使能端LCD12864_DATAPORT = dat; //放置数据LCD12864_EN = 1; //写时序LCD12864_Delay1ms(1);LCD12864_EN = 0;}/****************************************************************************** ** 函数名: LCD12864_ReadData* 函数功能: 读取数据* 输入: 无* 输出: 读取到的8位数据******************************************************************************* /#ifdef LCD12864_PICTUREuchar LCD12864_ReadData(void){uchar i, readValue;i = 0;while( LCD12864_Busy() == 0){LCD12864_Delay1ms(1);i++;if( i>100){return 0; //超过等待退出}}LCD12864_RS = 1; //选择命令LCD12864_RW = 1;LCD12864_EN = 0;LCD12864_Delay1ms(1); //等待LCD12864_EN = 1;LCD12864_Delay1ms(1);readValue = LCD12864_DA TAPORT;LCD12864_EN = 0;return readValue;}#endif/****************************************************************************** ** 函数名: LCD12864_Init* 函数功能: 初始化LCD12864* 输入: 无* 输出: 无******************************************************************************* /void LCD12864_Init(){LCD12864_PSB = 1; //选择并行输入LCD12864_RST = 1; //复位LCD12864_WriteCmd(0x30); //选择基本指令操作LCD12864_WriteCmd(0x0c); //显示开,关光标LCD12864_WriteCmd(0x01); //清除LCD12864的显示内容}/****************************************************************************** ** 函数名: LCD12864_ClearScreen* 函数功能: 在画图模式下,LCD12864的01H命令不能清屏,所以要自己写一* * 屏函数* 输入: 无* 输出: 无******************************************************************************* /#ifdef LCD12864_PICTUREvoid LCD12864_ClearScreen(void){uchar i,j;LCD12864_WriteCmd(0x34); //开启拓展指令集for(i=0;i<32;i++) //因为LCD有纵坐标32格所以写三十二次{LCD12864_WriteCmd(0x80+i); //先写入纵坐标Y的值LCD12864_WriteCmd(0x80); //再写入横坐标X的值for(j=0;j<32;j++) //横坐标有16位,每位写入两个字节的的数据,也{ //就写入32次以为当写入两个字节之后横坐标会自LCD12864_WriteData(0x00); //动加1,所以就不用再次写入地址了。
基于51单片机的12864液晶显示的万年历
附录程序
/*****************说明*********************************** 基于 51 单片机的 12864 液晶显示的万年历
版权所有,如需转载请通知本人,不得用于商业用途 ,仅限学习交流之用
*****************************************************************/
3
图-1 主控制系统
2.3.2 时钟电路模块的设计 DS1302 是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、
时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进 行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一 个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容, 但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
//延时 1MS/次
unsigned char
{
sec,min,hour,day,month,year,cen,week,
unsigned char i;
next,aa,bb,cc,dd,mm,temp0,LunarMonth,
while(--a)
LunarDay,LunarYear;
{
int temp;
9三三系统的软件设计系统的软件设计3131程序流程框图程序流程框图图图aa主程序流程图主程序流程图10图b计算阳历程序流程图计算阳历程序流程图1112图图cc时间调整程序流程图时间调整程序流程图yynnyynnyy图图dd设置温度报警闹钟的数据保存到设置温度报警闹钟的数据保存到at24c02at24c02中中是否进入温度报警上下限温度设置设置是否进入设置闹钟时间设置报警温度上下限开始设置闹钟的时间开始报警闹钟的开关是否开起at24c02存设置的功能保蜂鸣器开启闹钟报警功能开启结束设置13五五作品功能实现作品功能实现通过硬件的焊接与程序的编写本电子万年历终于完成了实现的功能如下
12864LCD上显示温湿度.
12864LCD显示温湿度第一种方式:/**********************DHT11与12864LCD************************/ #include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar lcd_x,lcd_y,data_byte=0,count;uint TH_data,TL_data,RH_data,RL_data,CK_data;uint TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;uchar num;sbit RS = P2^0;//并行指令,数据选择信号sbit RW = P2^1;//读写信号sbit EN = P2^2;//并行使能信号sbit PSB = P2^3;//并串口选择信号sbit RST = P2^5;//复位信号sbit io = P1^0;//DHT11总线void read_io();//开始信号,读数据并校验void delay(uint a);//延时函数void LCD_init();//LCD初始化程序void write_cmd(uchar cmd);//写指令void write_data(uchar dat);//写数据bit check_busy();//检测LCD忙信号//void clear_gcrom();//清除GCROMvoid delay1();//10us延时void lcd_dis_code(uint cmd_addr,uchar num,uchar dis[]);//显示函数void lcd_pos(unsigned char X,unsigned char Y);//LCD显示位置计算uchar code lcd[]={"温湿度检测系统"};uchar code lcd1[]={" 温度:"};uchar code lcd2[]={" 湿度:"};uchar code lcd3[]={"℃"};uchar code lcd4[]={"%RH"};uchar str1[]={" "};uchar str2[]={" "};void main(){uchar k,j;LCD_init();lcd_dis_code(0x80,16,lcd);lcd_dis_code(0x88,9,lcd1);lcd_dis_code(0x98,9,lcd2);lcd_dis_code(0x8e,2,lcd3);lcd_dis_code(0x9e,5,lcd4);while(1){read_io();//读取温湿度数据//clear_gcrom();//湿度for(k=0; k<2; k++){lcd_pos(4,k+4);write_data(str1[k]);}//clear_gcrom();//温度for(j=0; j<2; j++){lcd_pos(3,j+4);write_data(str2[j]);}delay(500);}}void delay1()//延时10us{unsigned char i;for(i=0; i<3; i++);}void lcd_pos(unsigned char X,unsigned char Y){unsigned char pos;if ( X == 1 ){ pos = 0x80 ; }else if ( X == 2 ){ pos = 0x90 ; }else if ( X == 3 ){ pos = 0x88 ; }else{ pos = 0x98 ; }write_cmd(Y | pos);//数据指针=80+地址变量}/**********************DHT11模块**********************/ uchar receive_byte()//接收一个字节{uchar i,temp;for(i=0;i<8; i++){count = 2;while((!io) && count++)//等待50us低电平结束,并防止死循环temp = 0;delay1();delay1();delay1();if (io==1){temp = 1;count = 2;while(io && count++);}elsetemp = 0;data_byte<<=1;data_byte|=temp;}return (data_byte);}void read_io()//开始信号,读数据并校验{io = 0;delay(18);//主机拉低18msio = 1;//DATA总线由上拉电阻拉高主机延时20usdelay1();delay1();delay1();delay1();io = 1;//主机设置为输入高电平,判断从机响应信号if(!io){count = 2;while((!io)&&count++);//判断DHT11发出80us低电平响应信号是否结束count = 2;while(io && count++);//判断DHT11拉高总线80us高电平是否结束RH_temp = receive_byte();RL_temp = receive_byte();TH_temp = receive_byte();TL_temp = receive_byte();CK_temp = receive_byte();io = 1;num = (RH_temp + RL_temp + TH_temp + TL_temp);//数据校验if(num == CK_temp){RH_data = RH_temp;RL_data = RL_temp;TH_data = TH_temp;TL_data = TL_temp;CK_data = CK_temp;}}//湿度整数部分str1[0] = (char)(0x30 + RH_data/10);str1[1] = (char)(0x30 + RH_data%10);//温度整数部分str2[0] = (char)(0x30 + TH_data/10);str2[1] = (char)(0x30 + TH_data%10);}/**********************E N D**********************//**********************12864模块程序**********************/ /*void clear_gcrom(){uchar i,j,k;lcd_x = 0x80;lcd_y = 0x80;write_cmd(0x34);for(i = 0 ; i < 2 ; i++) //上下两屏幕{for(j = 0 ; j < 32 ; j++){write_cmd(lcd_y+j);write_cmd(lcd_x);for(k = 0 ; k < 16 ; k++){write_data(0x00);}}lcd_x = 0x88;}write_cmd(0x36);write_cmd(0x30);}*/void lcd_dis_code(uint cmd_addr,uchar num,uchar dis[]) {uint i;write_cmd(cmd_addr);for(i=0; i<num; i++)write_data(dis[i]);}void LCD_init(){PSB = 1;RST = 0;delay(5);RST = 1;delay(5);write_cmd(0x34);//扩充指令delay(5);write_cmd(0x30);//基本指令delay(5);write_cmd(0x0c);//显示开关光标delay(5);write_cmd(0x01);//清屏delay(5);}bit check_busy(){bit temp;RS = 0;RW = 1;EN = 1;delay(5);temp = (bit)(P0&0x80); //按位与操作EN = 0;return (temp);}void write_cmd(uchar cmd){while(check_busy());RS = 0;RW = 0;EN = 0;delay(5);P0 = cmd;delay(5);EN = 1;delay(5);EN = 0;}void write_data(uchar dat){while(check_busy());RS = 1;RW = 0;EN = 0;P0 = dat;delay(5);EN = 1;delay(5);EN = 0;}void delay(uint a){uchar i;while(a--){for(i=0; i<113; i++);}}/**********************E N D**********************/第二种编程方式,其实大体都差不了多少#include <reg52.h> #include <intrins.h>/******************************************************** 宏定义********************************************************/#define uint unsigned int#define uchar unsigned char#define noACK 0#define ACK 1#define STATUS_REG_W 0x06#define STATUS_REG_R 0x07#define MEASURE_TEMP 0x03#define MEASURE_HUMI 0x05#define RESET 0x1eenum {TEMP,HUMI};typedef union //定义共用同类型{unsigned int i;float f;}value;/********************************************************位定义********************************************************/sbit lcdrs=P2^0;sbit lcdrw=P2^1;sbit lcden=P2^2;sbit SCK = P1^0;sbit DA TA = P1^1;/********************************************************变量定义********************************************************/uchar table2[]="SHT11 温湿度检测";uchar table3[]="温度为:℃";uchar table4[]="湿度为:";uchar table5[]=".";uchar wendu[6];uchar shidu[6];/******************************************************** 1ms延时函数********************************************************/void delay(int z){ int x,y;for(x=z;x>0;x--)for(y=125;y>0;y--); }/******************************************************** 50us延时函数********************************************************/void delay_50us(uint t){uint j;for(;t>0;t--)for(j=19;j>0;j--);}/********************************************************50ms延时函数********************************************************/void delay_50ms(uint t){uint j;for(;t>0;t--)for(j=6245;j>0;j--);}/********************************************************12864液晶写指令********************************************************/void write_12864com(uchar com){ lcdrs=0;lcdrw=0;delay_50us(1);P0=com;lcden=1;delay_50us(10);lcden=0;delay_50us(2);}/********************************************************12864液晶写数据********************************************************/ void write_dat(uchar dat) { lcdrs=1;lcdrw=0;delay_50us(1);P0=dat;lcden=1;delay_50us(10);lcden=0;delay_50us(2); }/********************************************************12864液晶初始化********************************************************/void init12864lcd(void) {delay_50ms(2);write_12864com(0x30);delay_50us(4);write_12864com(0x30);delay_50us(4);write_12864com(0x0f);delay_50us(4);write_12864com(0x01);delay_50us(240);write_12864com(0x06);delay_50us(10);write_12864com(0x0c);delay_50us(10); }/******************************************************** 12864液晶显示函数********************************************************/void display1(void){uchar i;write_12864com(0x80);for(i=0;i<18;i++){write_dat(table2[i]);delay_50us(1); } }/******************************************************** 12864液晶显示函数********************************************************/void display2(void){uchar i;write_12864com(0x90);for(i=0;i<18;i++){write_dat(table3[i]);delay_50us(1); } }/******************************************************** 12864液晶显示函数********************************************************/void display3(void){ uchar i;write_12864com(0x88);for(i=0;i<8;i++){ write_dat(table4[i]);delay_50us(1); }}/******************************************************** 12864液晶显示函数********************************************************/void displaywendu(void){ uchar i;write_12864com(0x94);for(i=0;i<3;i++){ write_dat(wendu[i]);delay_50us(1);}for(i=0;i<1;i++){write_dat(table5[i]);delay_50us(1);}for(i=4;i<5;i++){write_dat(wendu[i]);delay_50us(1); } }/******************************************************** 12864液晶显示函数********************************************************/void displayshidu(void) {uchar i;write_12864com(0x8C);for(i=0;i<3;i++) {write_dat(shidu[i]);delay_50us(1); }for(i=0;i<1;i++){ write_dat(table5[i]);delay_50us(1);}for(i=4;i<5;i++){write_dat(shidu[i]);delay_50us(1);} }/******************************************************** SHT11写字节程序********************************************************/char s_write_byte(unsigned char value){unsigned char i,error=0;for (i=0x80;i>0;i>>=1) //高位为1,循环右移{ if (i&value) DATA=1; //和要发送的数相与,结果为发送的位else DA TA=0;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;}DA TA=1; //释放数据线SCK=1;error=DATA; //检查应答信号,确认通讯正常_nop_();_nop_();_nop_();SCK=0;DA TA=1;return error; //error=1 通讯错误}/******************************************************** SHT11读字节程序********************************************************/char s_read_byte(unsigned char ack){unsigned char i,val=0;DA TA=1; //释放数据线for(i=0x80;i>0;i>>=1) //高位为1,循环右移{SCK=1;if(DATA)val=(val|i); //读一位数据线的值SCK=0; }DA TA=!ack; //如果是校验,读取完后结束通讯;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;_nop_();_nop_();_nop_();DA TA=1; //释放数据线 return val; }/******************************************************** SHT11启动传输********************************************************/void s_transstart(void){DATA=1;SCK=0; //准备_nop_();SCK=1;_nop_();DATA=0;_nop_();SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();DATA=1;_nop_();SCK=0; }/******************************************************** SHT11连接复位********************************************************/void s_connectionreset(void){ unsigned char i;DA TA=1;SCK=0; //准备for(i=0;i<9;i++) //DA TA保持高,SCK时钟触发9次,发送启动传输,通迅即复位{ SCK=1;SCK=0;}s_transstart(); //启动传输 }/********************************************************SHT11温湿度检测********************************************************/char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode){unsigned error=0;unsigned int i;s_transstart(); //启动传输switch(mode) //选择发送命令{ case TEMP : error+=s_write_byte(MEASURE_TEMP);break; //测量温度case HUMI : error+=s_write_byte(MEASURE_HUMI);break; //测量湿度default : break;}for (i=0;i<65535;i++)if(DATA==0) break; //等待测量结束if(DATA) error+=1; // 如果长时间数据线没有拉低,说明测量错误*(p_value) =s_read_byte(ACK); //读第一个字节,高字节 (MSB)*(p_value+1)=s_read_byte(ACK); //读第二个字节,低字节 (LSB)*p_checksum =s_read_byte(noACK); //read CRC校验码return error; // error=1 通讯错误 }/******************************************************** SHT11温湿度值标度变换及温度补偿********************************************************/ void calc_sth10(float *p_h umidity ,float *p_temperature){const float C1=-4.0; // 12位湿度精度修正公式const float C2=+0.0405; // 12位湿度精度修正公式const float C3=-0.0000028; // 12位湿度精度修正公式const float T1=+0.01; // 14位温度精度 5V条件修正公式const float T2=+0.00008; // 14位温度精度 5V条件修正公式float rh=*p_humidity; // rh: 12位湿度float t=*p_temperature; // t: 14位温度float rh_lin; // rh_lin: 湿度 linear值float rh_true; // rh_true: 湿度 ture值float t_C; // t_C : 温度℃t_C=t*0.01 - 40; //补偿温度rh_lin=C3*rh*rh + C2*rh + C1; //相对湿度非线性补偿rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度对于温度依赖性补偿if(rh_true>100)rh_true=100; //湿度最大修正if(rh_true<0.1)rh_true=0.1; //湿度最小修正*p_temperature=t_C; //返回温度结果*p_humidity=rh_true; //返回湿度结果 }/******************************************************** 主函数********************************************************/ void main(void){unsigned int temp,humi;value humi_val,temp_val; //定义两个共同体,一个用于湿度,一个用于温度unsigned char error; //用于检验是否出现错误unsigned char checksum; //CRCinit12864lcd();display1();display2();display3();s_connectionreset(); //启动连接复位while(1){error=0; //初始化error=0,即没有错误error+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP); //温度测量error+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI); //湿度测量if(error!=0) s_connectionreset(); ////如果发生错误,系统复位else{humi_val.f=(float)humi_val.i; //转换为浮点数temp_val.f=(float)temp_val.i; //转换为浮点数calc_sth10(&humi_val.f,&temp_val.f); //修正相对湿度及温度 temp=temp_val.f*10;humi=humi_val.f*10;wendu[0]=temp/1000+'0'; //温度百位wendu[1]=temp%1000/100+'0'; //温度十位wendu[2]=temp%100/10+'0'; //温度个位wendu[3]=0x2E; //小数点wendu[4]=temp%10+'0'; //温度小数点后第一位displaywendu();shidu[0]=humi/1000+'0'; //湿度百位shidu[1]=humi%1000/100+'0'; //湿度十位shidu[2]=humi%100/10+'0'; //湿度个位shidu[3]=0x2E; //小数点shidu[4]=humi%10+'0'; //湿度小数点后第一位displayshidu(); }Delay(800);//等待足够长的时间,以现行下一次转换}}。
stm3212864lcd显示时间和温度
stm3212864lcd显示时间和温度#include "stm32f10x.h"#include "stdio.h"//-------------------------------------------------------------------------------------------------#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键0#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键1 #define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键2#define KEY0_PRES 1 //KEY0#define KEY1_PRES 2 //KEY1#define WKUP_PRES 3 //WK_UP//-------------------------------------------------------------------------------------------------//位带操作,实现51类似的GPIO控制功能//具体实现思想,参考<>第五章(87页~92页).//IO口操作宏定义#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))//IO口地址映射#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08//IO口操作,只对单一的IO口!//确保n的值小于16!#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入//-------------------------------------------------------------------------------------------------#define LED0 PAout(8) // PA8#define LED1 PDout(2) // PD2#define LED2 PAout(2)#define LED3 PAout(3)//-------------------------------------------------------------------------------------------------// lcd12864//-------------------------------------------------------------------------------------------------#define SID_H GPIOC->BSRR=GPIO_Pin_7#define SID_L GPIOC->BRR=GPIO_Pin_7#define CS_H GPIOC->BSRR=GPIO_Pin_8#define CS_L GPIOC->BRR=GPIO_Pin_8#define SCLK_H GPIOC->BSRR=GPIO_Pin_6#define SCLK_L GPIOC->BRR=GPIO_Pin_6#define x1 0x80#define x2 0x88#define y 0x80#define comm 0#define dat1 1u8 const num_lcd[]={"0123456789"};void Clr_Scr(void);void LCD_Write_String(u8 X,u8 Y,uc8 *s);//12864u8 A,B,C,D;void display_temp_time(void);void display_main(void);void display_1(void);//-------------------------------------------------------------------------------------------------// DS1302//-------------------------------------------------------------------------------------------------#define ds1302clk GPIO_Pin_12#define ds1302dat GPIO_Pin_13#define ds1302rst GPIO_Pin_14uint8_ttime_ds1302[7]={0x00,0x54,0x10,0x08,0x12,0x01,0x08};uint8_t read[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读秒、分、时、日、月、周、年的寄存器地址uint8_t write[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写秒、分、时、日、月、周、年的寄存器地址//按键中断按下显示时间,所以需要全局变量uint8_t i=0,g[7];void ds1302_data(uint8_t *read);uint8_t DSPH[]={"00"};uint8_t DSPM[]={"00"};uint8_t DSPS[]={"00"};uint8_t DSPN[]={"00"};uint8_t DSPY[]={"00"};uint8_t DSPR[]={"00"};//-------------------------------------------------------------------------------------------------//-------------------------------------------------------------------------------------------------// DS18b20//-------------------------------------------------------------------------------------------------float DS18B20_Get_Temp(void);uint8_t DS18B20_Init(void);//-------------------------------------------------------------------------------------------------#define HIGH 1#define LOW 0//-------------------------------------------------------------------------------------------------#define DS18B20_CLK RCC_APB2Periph_GPIOC#define DS18B20_PIN GPIO_Pin_13#define DS18B20_PORT GPIOC//带参宏,可以像内联函数一样使用,输出高电平或低电平#define DS18B20_DATA_OUT(a) if (a) \GPIO_SetBits(GPIOC,GPIO_Pin_13);\else \GPIO_ResetBits(GPIOC,GPIO_Pin_13)//读取引脚的电平#define DS18B20_DATA_IN() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)uint8_t DSPWD[]={"00"};uint8_t str[2]={0};uint8_t temp;//-------------------------------------------------------------------------------------------------typedef struct{uint8_t humi_int; //湿度的整数部分uint8_t humi_deci; //湿度的小数部分uint8_t temp_int; //温度的整数部分uint8_t temp_deci; //温度的小数部分uint8_t check_sum; //校验和}DS18B20_Data_TypeDef;//---------------------------------------------------------------------------------------------------------------------------------------------------------------------static u8 fac_us=0;//us延时倍乘数static u16 fac_ms=0;//ms延时倍乘数//-------------------------------------------------------------------------------------------------volatile u32 time = 0;//-------------------------------------------------------------------------------------------------unsigned char sz[5]={0x00,0x01,0x02,0x03,0x04};//-------------------------------------------------------------------------------------------------void delay_init(void);void delay_ms(u16 nms);void delay_us(u32 nus);void KEY_Init(void);//void Delay_us(__IO u32 nTime);void delay_init(void);//-------------------------------------------------------------------------------------------------// 系统定时器初始化//-------------------------------------------------------------------------------------------------void delay_init(void){SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8fac_us=SystemCoreClock/8000000; //为系统时钟的1/8fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数}//-------------------------------------------------------------------------------------------------void delay_us(u32 nus){u32 temp;SysTick->LOAD=nus*fac_us; //时间加载SysTick->VAL=0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16))); //等待时间到达SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器}//--------------------------------------------------------------------//延时nms//注意nms的范围//SysTick->LOAD为24位寄存器,所以,最大延时为://nms<=0xffffff*8*1000/SYSCLK//SYSCLK单位为Hz,nms单位为ms//对72M条件下,nms<=1864//--------------------------------------------------------------------void delay_ms(u16 nms){u32 temp;SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)SysTick->VAL =0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//等待时间到达SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器}//-------------------------------------------------------------------------------------------------// 中断优先级配置//-------------------------------------------------------------------------------------------------void NVIC_Configuration1(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级}//-------------------------------------------------------------------------------------------------// 外部中断初始化函数//-------------------------------------------------------------------------------------------------void EXTIX_Init(void){EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //外部中断,需要使能AFIO时钟KEY_Init(); //初始化按键对应io模式GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSour ce5); //GPIOC.5 中断线以及中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line5;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSour ce15); //GPIOA.15 中断线以及中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line15;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSour ce0); //GPIOA.0 中断线以及中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);}//-----------------------------------------------------------------// 按键中断函数//-----------------------------------------------------------------void EXTI0_IRQHandler(void){delay_ms(10);if(WK_UP==1){LED0=!LED0;LED1=!LED1;Clr_Scr();A=1;Clr_Scr();//===================================== ============================//printf("测试");//printf("\r\n 现在温度 %.1f 度\r\n",DS18B20_Get_Temp());}EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路挂起位}//-----------------------------------------------------------------void EXTI9_5_IRQHandler(void){delay_ms(10);if(KEY0==0){LED0=!LED0;A=0;//printf("稍等");//adcx=Get_Adc_Average(ADC_Channel_1,10);//temp =(float) adcx/4096*3.3;//printf("\r\n The current AD value = 0x%04X \r\n",adcx);//printf("\r\n The current AD value = %f V \r\n",temp);}EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中断标志位}//-----------------------------------------------------------------void EXTI15_10_IRQHandler(void){delay_ms(10);if(KEY1==0){LED1=!LED1;A=2;//printf("硕硕");// ds1302_data(read);//printf("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time_ds1302[6],g[6],time_ds1302[4],g[4],time_ds1302[ 3],g[3],//time_ds1302[2],g[2],time_ds1302[1],g[1],time_ds1302[0],g[ 0],g[5]);}EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15线路挂起位}//===================================== ========================================= ===================//-------------------------------------------------------------------------------------------------// LED GPIO 初始化//-------------------------------------------------------------------------------------------------void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP B2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_2|GPIO_Pin_3; //LED0-->PA.8 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出,IO口速度为50MHzGPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高}//-------------------------------------------------------------------------------------------------// GPIO 按键初始化//-------------------------------------------------------------------------------------------------void KEY_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP B2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA15GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0}//-------------------------------------------------------------------------------------------------// 串口配置//-------------------------------------------------------------------------------------------------void USART1_Config(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_/doc/400b4fab7c1cfad6185fa 744.html ART_BaudRate = 9600;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_WordLength = USART_WordLength_8b;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_StopBits = USART_StopBits_1;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Parity = USART_Parity_No ;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_HardwareFlowControl =USART_HardwareFlowControl_None;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_Cmd(USART1, ENABLE);}//--------------------------------------------------------------------// 配置USART1接收中断//--------------------------------------------------------------------void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}//--------------------------------------------------------------------//--------------------------------------------------------------------// 重定向c库函数printf到USART1//--------------------------------------------------------------------int fputc(int ch, FILE *f){//发送一个字节数据到USART1USART_SendData(USART1, (uint8_t) ch);//等待发送完毕while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return (ch);}// 重定向c库函数scanf到USART1int fgetc(FILE *f){while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(USART1);}//--------------------------------------------------------------------// 串口3配置//--------------------------------------------------------------------void USART3_Config(void){NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB, &GPIO_InitStructure);USART_/doc/400b4fab7c1cfad6185fa 744.html ART_BaudRate = 9600;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_WordLength = USART_WordLength_8b;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_StopBits = USART_StopBits_1;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Parity = USART_Parity_No ;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART3, &USART_InitStructure);USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);USART_Cmd(USART3, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}//===================================== ========================================= ========================================= ========================================= =====// DS1302//===================================== ========================================= ========================================= ========================================= =====void DS1302_GPIO(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStruct.GPIO_Pin = ds1302clk|ds1302rst; //clk、rst配置为输出GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin = ds1302dat;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //IO配置为双向GPIO_Init(GPIOB, &GPIO_InitStruct);}//-------------------------------------------------------------------------------------------------//-------------------------------------------------------------------------------------------------void write_1302byte(uint8_t dat){uint8_t i = 0;GPIO_ResetBits(GPIOB,ds1302clk);delay_us(2);//延时大约2usfor(i = 0;i < 8;i ++){GPIO_ResetBits(GPIOB,ds1302clk); //ds1302clk=0;if(dat&0x01)GPIO_SetBits(GPIOB,ds1302dat);else GPIO_ResetBits(GPIOB,ds1302dat);delay_us(2);GPIO_SetBits(GPIOB,ds1302clk);dat >>= 1;delay_us(1);}}//-----------------------------------------------uint8_t read_1302(uint8_t add){uint8_t i=0;uint8_t Return_dat=0x00;GPIO_ResetBits(GPIOB,ds1302rst);GPIO_ResetBits(GPIOB,ds1302clk);delay_us(3);GPIO_SetBits(GPIOB,ds1302rst);delay_us(3);write_1302byte(add);for(i=0;i<8;i++){GPIO_SetBits(GPIOB,ds1302clk);Return_dat >>= 1;GPIO_ResetBits(GPIOB,ds1302clk);if(GPIO_ReadInputDataBit(GPIOB,ds1302dat)==1) //数据线此时为高电平{Return_dat = Return_dat|0x80;}}delay_us(1);GPIO_ResetBits(GPIOB,ds1302rst); //ds1302rst=0;释放总线return Return_dat;}//-----------------------------------------------void write_1302(uint8_t add,uint8_t dat) //向指定寄存器写入一个字节的数据{GPIO_ResetBits(GPIOB,ds1302rst);GPIO_ResetBits(GPIOB,ds1302clk); //ds1302rst=0;//ds1302clk=0;delay_us(1);GPIO_SetBits(GPIOB,ds1302rst); //ds1302rst=1;delay_us(2);write_1302byte(add);write_1302byte(dat);GPIO_ResetBits(GPIOB,ds1302rst);GPIO_ResetBits(GPIOB,ds1302clk); //ds1302clk=0;//ds1302rst=0;delay_us(1);}//-----------------------------------------------void ds1302_init(uint8_t*write,uint8_t*time) //初始化1302 {uint8_t i=0,j=0;write_1302(0x8e,0x00);for(i=0;i<7;i++){j=time_ds1302[i]%10;time_ds1302[i]=(time_ds1302[i]/10)*16+j;}for(i=0;i<7;i++){write_1302(write[i],time_ds1302[i]);}write_1302(0x8e,0x80);//-----------------------------------------------void ds1302_data(uint8_t *read){//中断按键按下显示时间,所以定义为全局变量//uint8_t i=0,g[7],time_ds1302[7];//static uint8_t s = 1;for(i=0;i<7;i++){time_ds1302[i]=read_1302(read[i]);}//===================================== ==========/*for(i=0;i<7;i++){g[i]=time_ds1302[i]%16; time_ds1302[i]=time_ds1302[i]/16;}*///此时已转换成10进制数,g[i]里面存放的是秒分时日月周年的各个位数据//而此时的time[i]存放的是十位数据//if(s != (time[0]+g[0]))//printf("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time_ds1302[6],g[6],time_ds1302[4],g[4],time_ds1302[ 3],g[3],//time_ds1302[2],g[2],time_ds1302[1],g[1],time_ds1302[0],g[ 0],g[5]);//s = time[0]+g[0];//---------------------------------------------------------------------------------------------------------------------------------------------------------------------// DS18B20温度传感器//-------------------------------------------------------------------------------------------------void DS18B20_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的结构体RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE); //开启DS18B20_PORT的外设时钟GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHzGPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORTGPIO_SetBits(DS18B20_PORT, DS18B20_PIN);}//-------------------------------------------------------------------------------------------------void DS18B20_Mode_IPU(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置引脚模式为浮空输入模式GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT}//-------------------------------------------------------------------------------------------------void DS18B20_Mode_Out_PP(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置引脚速率为50MHzGPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT}//-------------------------------------------------------------------------------------------------void DS18B20_Rst(void){DS18B20_Mode_Out_PP(); //主机设置为推挽输出DS18B20_DATA_OUT(LOW);delay_us(750); // 主机至少产生480us的低电平复位信号DS18B20_DATA_OUT(HIGH); //主机在产生复位信号后,需将总线拉高delay_us(15); //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲}//-------------------------------------------------------------------------------------------------//检测从机给主机返回的存在脉冲//0:成功//1:失败//-------------------------------------------------------------------------------------------------uint8_t DS18B20_Presence(void){uint8_t pulse_time = 0;DS18B20_Mode_IPU(); //主机设置为上拉输入//等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号//如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲while( DS18B20_DATA_IN() && pulse_time<100 ){pulse_time++;delay_us(1); //经过100us后,存在脉冲都还没有到来}if( pulse_time >=100 )return 1;elsepulse_time = 0;while( !DS18B20_DATA_IN() && pulse_time<240 ) //存在脉冲到来,且存在的时间不能超过240us{pulse_time++;delay_us(1);}if( pulse_time >=240 )return 1;elsereturn 0;}//从DS18B20读取一个bituint8_t DS18B20_Read_Bit(void){uint8_t dat; //读0和读1的时间至少要大于60usDS18B20_Mode_Out_PP();DS18B20_DATA_OUT(LOW); //读时间的起始:必须由主机产生 >1us <15us 的低电平信号delay_us(10);DS18B20_Mode_IPU(); //设置成输入,释放总线,由外部上拉电阻将总线拉高//Delay_us(2);if( DS18B20_DATA_IN() == SET )dat = 1;elsedat = 0;delay_us(45); //这个延时参数请参考时序图return dat;}//从DS18B20读一个字节,低位先行uint8_t DS18B20_Read_Byte(void){uint8_t i, j, dat = 0;for(i=0; i<8; i++){j = DS18B20_Read_Bit();dat = (dat) | (j<<i);}return dat;}//写一个字节到DS18B20,低位先行void DS18B20_Write_Byte(uint8_t dat) {uint8_t i, testb;DS18B20_Mode_Out_PP();for( i=0; i<8; i++ ){testb = dat&0x01;dat = dat>>1;//写0和写1的时间至少要大于60us if (testb){DS18B20_DATA_OUT(LOW);//1us < 这个延时 < 15usdelay_us(8);DS18B20_DATA_OUT(HIGH);delay_us(58);}else{DS18B20_DATA_OUT(LOW);//60us < Tx 0 < 120usdelay_us(70);DS18B20_DATA_OUT(HIGH);//1us < Trec(恢复时间) < 无穷大delay_us(2);}}}//-------------------------------------------------------------------------------------------------void DS18B20_Start(void){DS18B20_Rst();DS18B20_Presence();DS18B20_Write_Byte(0XCC); // 跳过 ROMDS18B20_Write_Byte(0X44); // 开始转换}//-------------------------------------------------------------------------------------------------uint8_t DS18B20_Init(void){DS18B20_GPIO_Config();DS18B20_Rst();return DS18B20_Presence();}//温度 = 符号位 + 整数 + 小数*0.0625float DS18B20_Get_Temp(void){uint8_t tpmsb, tplsb;short s_tem;float f_tem;DS18B20_Rst();DS18B20_Presence();DS18B20_Write_Byte(0XCC); // 跳过 ROMDS18B20_Write_Byte(0X44); // 开始转换DS18B20_Rst();DS18B20_Presence();DS18B20_Write_Byte(0XCC); // 跳过 ROMDS18B20_Write_Byte(0XBE); // 读温度值tplsb = DS18B20_Read_Byte();tpmsb = DS18B20_Read_Byte();s_tem = tpmsb<<8;s_tem = s_tem | tplsb;if( s_tem < 0 ) // 负温度f_tem = (~s_tem+1) * 0.0625;elsef_tem = s_tem * 0.0625;return f_tem;}//===================================== ========================================= ===void Show_Temperature(void){</i);temp=DS18B20_Get_Temp();str[0]=temp/10;str[1]=temp%10;DSPWD[0]=str[0]+0x30;DSPWD[1]=str[1]+0x30;}//-------------------------------------------------------------------------------------------------//---------------------------------------------------------------------------------------------------------------------------------------------------------------------// LCD12864//---------------------------------------------------------------------------------------------------------------------------------------------------------------------void Lcds_Config(void){// SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);/*PC4-A0*/// GPIO_SetBits(GPIOC, GPIO_Pin_12);//预置为高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;。
LCD12864液晶电子钟
长沙学院《单片机原理及应用》课程设计说明书题目 LCD12864液晶显示电子钟设计系(部)专业(班级)姓名学号指导教师起止日期《单片机原理及应用》课程设计任务书系(部):专业:课题名称LCD12864液晶显示电子钟设计设计内容及要求1、课题内容:设计一种基于AT89S52 单片机的液晶显示电子时钟,要求如下:(1)、能正确显示时间、日期和星期显示格式为:时间:XX 小时:XX 分:XX 秒;日期:XX 年:XX 月:XX 日;星期:X。
(2)、时间能够由按键调整,误差小于1S。
(3)、闹钟功能:时间运行到与闹钟设定时间时,闹钟响(持续响3秒)。
(4)、报时功能:时间运行到正点时间时,闹钟响,几点钟就响几声(每声持续响2 秒,每两声之间时间间隔1 秒)。
液晶显示器第一行显示“数字电子钟”;第二行显示“当前时间”;第三行显示日期和星期;第四行显示最近一个闹钟的设定时间。
2、要求:完成该系统的硬件和软件的设计,在Proteus 软件上仿真通过,并提交一篇课程设计说明书。
设计工作量1、汇编或C51 语言程序设计;2、程序调试;3、在Proteus 上进行仿真成功,进行实验板下载调试;4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序分析、仿真分析、调试过程,参考文献、设计总结等。
进度安排起止日期设计内容(或预期目标)备注第一天课题介绍,答疑,收集材料,C51介绍第二天设计方案论证,练习编写C51程序第三天——第六天程序设计第六天——第八天程序调试、仿真第九天——第十天系统测试并编写设计说明书教研室意见年月日系(部)主管领导意见年月日目录一、整体方案设计 (4)1、单片机的选择 (4)2、单片机结构 (4)二、前期准备 (5)三、程序设计 (8)1、键盘约定 (8)2、界面显示 (9)3、全局变量的定义 (9)4、系统时钟 (9)5、闹钟控制时间的设定 (9)四、总结与体会 (10)参考文献 (11)一、整体方案设计1、单片机的选择单片微型计算机主要由微处理器、存储器、I/O接口电路等组成。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
12864液晶电子时钟+温度显示
上午花了一上午时间,用12864 液晶写了一个电子时钟加温度传感器程序,
先说一下程序的功能,可以实现显示年月日时间和温度,
年月日和时间是可通过按键调节的,调节相应的选项时,该选项会闪烁,并停止走时,当调节完毕后时钟恢复走时。
现在将程序和思路写下来,以便日后查看和与大家探讨改进,欢迎高手提出宝贵意见。
我使用的是HJ12864M-1 带字库液晶,所以在显示上稍微方便一点。
下面先
来说一下我的编程思路。
时间更新用的是单片机自带的定时器,液晶要显示数字必需将它转换成ASCii 码的形式,数字0-9 的ASCii 码与数字之间有一个定
量的关系,当数字加上0x30 之后便得到该数字的ASCii 码,这样以来液晶更
新数据就变得简单了。
调节时间时对应选项闪烁,是通过不断的交替写入数据和空格实现的。
温度显示用的是DS18B20,,将测得的当前温度不断更新显示在
液晶上。
调节时间用的是三个独立按键。
由于这个程序我使用模块化来写的,就只能将每个模块分别给出来,大家只要组装一下便可以使用。
如果需要完整程序的可以给我留言我发给你们。
下面是12864 液晶的初始化,读写命令,及读忙操作
#include “lcd12864.h”#include reg52.hsbit RS=P2 ; //控制端口位定义sbit
RW=P2;s b it EN=P2;vo id init_12864(){delay(40);write_com(0x30);//8 位数据格
式,基本指令显示delay(10); //延时时间write_com(0x30);//8 位数据格式,基本
指令显示delay(37);write_com(0x0C);//开显示、关闭光标delay(10);
write_com(0x01);//清屏指令delay(10); //延时write_com(0x06);//设置显示点:指
针自加1}tips:感谢大家的阅读,本文由我司收集整编。
仅供参阅!。