基于PCF8563的单片机数字时钟
更新时间:2024-07-01 01:23:01 阅读量: 综合文库 文档下载
LCD1C21930pU1XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD393837363534333221222324252627281011121314151617P02P03P04P05AMPIRE128X64RP1987654321P00P01P02P03P04P05P06P07RP298765432110KP30P31P32P33P34P35P36P37X1C130p12MHz18XTAL29RST1k47u293031PSENALEEA181716151413121110987654321-VoutRSTDB7DB6DB5DB4DB3DB2DB1DB0ER/WRSV0VCCGNDCS2CS1R1C3P20P21RV154K1kP31P17P16P15P14P13P12P11P10P32P34P33P36P37K1K2K3设置键P03加键P04P101P112P123P134P145P156P167P178P1.0/T2P1.1/T2EXP1.2/ECIP1.3/CEX0P1.4/CEX1P1.5/CEX2P1.6/CEX3P1.7/CEX4AT89C51RD2P30P31P32P33P34P35P36P37P1[0..7]RP398765432110KP20P21P22P23P24P25P26P27RP498765432110KP10P11P12P13P14P15P16P17减键P05键盘电路+12VU2P20P2165SCLSDAOSCIOSCO84VDDVSSCLKOUTINT1273CRYSTALX2R24.7kP02321C420pFU3VCCDQGNDDS18B201N41487.0PCF8563D1D21N4148B13VC6温度检测电路47uFC50.1uF
//---库函数声明及相关定义---// #include
#define uchar unsigned char #define uint unsigned int sbit SDA=P2^1;//数据 sbit SCL=P2^0;//时钟
#define Databus P1 /*液晶数据总线*/
bit Reverse_Display=0;//是否反相显示(白底黑字/黑底白字) sbit RS=P3^3; /*数据\\指令 选择*/ sbit RW=P3^4; /*读\\写 选择*/ sbit EN=P3^2; /*读\\写使能*/ sbit cs1=P3^6; /*片选1*/ sbit cs2=P3^7; /*片选2*/
uchar g8563_Store[8]; /*时间交换区,全局变量声明*/
uchar code c8563_Store[8]={0x50,0x59,0x23,0x31,0x06,0x12,0x00,0x19}; /*写入时间初值:世纪,09年 7月 星期一 13日 07:59:00*/
sbit DQ=P0^2;//ds18b20与单片机连接口 float f_temp;//浮点型温度值 unsigned int tvalue;//温度值
unsigned char tflag; unsigned int temp=0;
unsigned char SegBuf_DS18B20[4]={0};
sbit menu=P0^3;//菜单 sbit add=P0^4;//加一 sbit dec=P0^5;//减一
uchar second,minute,hour,day,month,year,week,count=0;
/********************************/ /* 定义中文字库 */
/********************************/ uchar code Hzk[]={
0x40,0x20,0x10,0x0C,0xE3,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0x02,0x00,0x00,//年//0 0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x11,0x11,0x11,0x11,0x11,0xFF,0x00,0x00,0x00,0x00,//月//1 0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x01,0x01,0x21,0x41,0x3F,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,//日//2 0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,//星//3 0x00,0x48,0x46,0x41,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x49,0x41,0x40,0x00, //4 //5 //6 //7 //8 //9
0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,//
期
0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00,
0x00,0xFC,0x44,0x44,0x44,0xFC,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00,//时0x00,0x07,0x04,0x04,0x04,0x07,0x00,0x00,0x03,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,
0x80,0x40,0x20,0x98,0x87,0x82,0x80,0x80,0x83,0x84,0x98,0x30,0x60,0xC0,0x40,0x00,//分0x00,0x80,0x40,0x20,0x10,0x0F,0x00,0x00,0x20,0x40,0x3F,0x00,0x00,0x00,0x00,0x00,
0x12,0x12,0xD2,0xFE,0x91,0x11,0xC0,0x38,0x10,0x00,0xFF,0x00,0x08,0x10,0x60,0x00,//秒0x04,0x03,0x00,0xFF,0x00,0x83,0x80,0x40,0x40,0x20,0x23,0x10,0x08,0x04,0x03,0x00,
0x00,0x40,0x42,0x42,0x42,0x42,0x42,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x40,0x00,//天0x00,0x80,0x40,0x20,0x10,0x08,0x06,0x01,0x02,0x04,0x08,0x10,0x30,0x60,0x20,0x00,
0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,//一0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,0x00,0x00,//二//10 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0x00, 0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00,//三//11 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 0x00,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,//四//12 0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x22,0x7F,0x00,0x00, 0x00,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0xC2,0x82,0x02,0x00,0x00,0x00,//五//13 0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30,0x20,0x00, 0x10,0x10,0x10,0x10,0x10,0x91,0x12,0x1E,0x94,0x10,0x10,0x10,0x10,0x10,0x10,0x00,//六//14 0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x00,0x00,0x01,0x02,0x0C,0x78,0x30,0x00,0x00, 0x00,0x40,0x42,0x44,0x4C,0x40,0x40,0x7F, 0x40,0x40,0x48,0x44,0xE6,0x40,0x00,0x00, 0x00,0x40,0x44,0x44,0x44,0x44,0x44,0x44, 0x44,0x44,0x44,0x44,0xFF,0x00,0x00,0x00,//当//15 0x08,0x08,0xE8,0x29,0x2A,0x2E,0xE8,0x08, 0x08,0xCC,0x0A,0x0B,0xE8,0x0C,0x08,0x00, 0x00,0x00,0xFF,0x09,0x49,0x89,0x7F,0x00,
0x00,0x0F,0x40,0x80,0x7F,0x00,0x00,0x00,//前//16
0x10,0x22,0x64,0x0C,0x80,0x00,0xFE,0x92, 0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00, 0x04,0x04,0xFE,0x01,0x40,0x7E,0x42,0x42,
0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,//温//17
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0xA5, 0xA6,0xA4,0xFC,0x24,0x34,0x26,0x04,0x00, 0x40,0x20,0x9F,0x80,0x42,0x42,0x26,0x2A,
0x12,0x2A,0x26,0x42,0x40,0xC0,0x40,0x00,//度//18
0x00,0x00,0x00,0x00,0x7F,0x49,0x49,0x49, 0x49,0x49,0x7F,0x00,0x00,0x80,0x00,0x00, 0x01,0x81,0x41,0x21,0x1D,0x21,0x41,0x7F,
0x89,0x89,0x8D,0x89,0x81,0xC1,0x41,0x00,//是//19
0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x31,0x7B,0x7B,0x31,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//://20
0x40,0x40,0x42,0xCC,0x00,0x40,0xA0,0x9F, 0x81,0x81,0x81,0x9F,0xA0,0x20,0x20,0x00, 0x00,0x00,0x00,0x7F,0xA0,0x90,0x40,0x43,
0x2C,0x10,0x28,0x26,0x41,0xC0,0x40,0x00,//设//21
0x00,0x10,0x17,0xD5,0x55,0x57,0x55,0x7D, 0x55,0x57,0x55,0xD5,0x17,0x10,0x00,0x00, 0x40,0x40,0x40,0x7F,0x55,0x55,0x55,0x55,
0x55,0x55,0x55,0x7F,0x40,0x60,0x40,0x00,//置//22
0x40,0x42,0x44,0xCC,0x00,0x20,0x22,0x22, 0xE2,0x22,0x22,0x23,0x32,0x20,0x00,0x00, 0x00,0x40,0x20,0x1F,0x20,0x48,0x4C,0x4B,
0x48,0x48,0x4A,0x4C,0x58,0x60,0x20,0x00,//运//23
0x00,0x10,0x88,0xC4,0x23,0x40,0x42,0x42, 0x42,0x42,0x42,0xC2,0x43,0x62,0x40,0x00, 0x02,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,
0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,//行//24
0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xFF, 0x08,0x08,0x08,0x08,0x08,0xFC,0x08,0x00, 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0xFF,
0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,//中//25
0x00,0x06,0x09,0x09,0xE6,0xF0,0x18,0x08, 0x08,0x08,0x18,0x30,0x78,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x30,
0x20,0x20,0x20,0x10,0x08,0x00,0x00,0x00,//℃//26 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 空格//27 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
/****************************************/ /* 定义ASCII字库8列*16行 */
/****************************************/ uchar code Ezk[]={
/*此字体下对应的点阵为:宽x高=8x16 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0xF0,0xF8,0x08,0x68,0xF8,0xF0,0x00,0x00,0x07,0x0F,0x0B,0x08,0x0F,0x07, //0
0x00,0x20,0x20,0x30,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00, //1 0x00,0x30,0x38,0x08,0x88,0xF8,0x70,0x00,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x08,0x00, // 2 0x00,0x30,0x38,0x88,0x88,0xF8,0x70,0x00,0x00,0x06,0x0E,0x08,0x08,0x0F,0x07,0x00, //3 0x00,0x00,0xF8,0xF8,0x00,0xE0,0xE0,0x00,0x00,0x03,0x03,0x02,0x02,0x0F,0x0F,0x02,//4 0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00,//5 0x00,0xC0,0xE0,0x78,0x58,0xC8,0x80,0x00,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00,//6 0x00,0x08,0x08,0x88,0xE8,0x78,0x18,0x00,0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00,//7 0x00,0x70,0xF8,0xC8,0x88,0xF8,0x70,0x00,0x00,0x07,0x0F,0x08,0x09,0x0F,0x07,0x00,//8 0x00,0xF0,0xF8,0x08,0x08,0xF8,0xF0,0x00,0x00,0x00,0x09,0x0D,0x0F,0x03,0x01,0x00,//9 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // - -//10 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0xE0,0xE0,0x80,0x80,0x00, // -+-//11 0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, // ---//12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -.-//13 0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00 };
/*状态检查,LCD是否忙*/ void CheckState() {
uchar dat; /*状态信息,判断是否忙*/
RS=0; /*数据\\指令选择,D/I(RS)=“L” ,表示 DB7∽DB0 为显示指令数据*/
RW=1; /*R/W=“H” ,E=“H”数据被读到DB7∽DB0*/ do{
Databus=0x00;
EN=1; /*EN下降源*/ _nop_(); /*一个时钟延时*/ dat=Databus; EN=0;
dat=0x80 & dat;/*仅当第7位为0时才可操作(判别busy信号)*/ }while(!(dat==0x00)); }
/*写命令到LCD中*/
SendCommandToLCD(uchar com) {
CheckState();/*状态检查,LCD是否忙*/
RS=0; /*向LCD发送命令。RS=0写指令,RS=1写数据*/ RW=0; /*R/W=“L” ,E=“H→L”数据被写到 IR 或 DR */ Databus=com; /*com :命令*/
EN=1; /*EN下降沿*/ _nop_(); _nop_(); EN=0; }
/*设置页 0xb8是页的首地址*/ void SetLine(uchar page) {
page=0xb8|page; /*1011 1xxx 0<=page<=7 设定页地址--X 0-7,8行为一页64/8=8,共8页*/ SendCommandToLCD(page); }
/*设定显示开始行,0xc0是行的首地址*/ void SetStartLine(uchar startline) { startline=0xc0|startline; /*1100 0000*/
SendCommandToLCD(startline); /*设置从哪行开始:0--63,一般从0 行开始显示*/ }
/*设定列地址--Y 0-63 ,0x40是列的首地址*/ void SetColumn(uchar column) {
column=column &0x3f; /*column最大值为64,越出 0= /*开关显示,0x3f是开显示,0x3e是关显示*/ void SetOnOff(uchar onoff) { onoff=0x3e|onoff; /*0011 111x,onoff只能为0或者1*/ SendCommandToLCD(onoff); } /*写显示数据 */ void WriteByte(uchar dat) { CheckState();/*状态检查,LCD是否忙*/ RS=1; /*RS=0写指令,RS=1写数据*/ RW=0; /*R/W=“L” ,E=“H→L”数据被写到 IR 或 DR */ if(!Reverse_Display) /*根据Reverse_Display决定是否反相显示*/ Databus=dat; /*dat:显示数据*/ else Databus=~dat; EN=1; /*EN下降沿*/ _nop_(); _nop_(); EN=0; } /*选择屏幕screen: 0-全屏,1-左屏,2-右屏*/ void SelectScreen(uchar screen) { switch(screen) { case 0: cs1=0;/*全屏*/ _nop_(); _nop_(); _nop_(); cs2=0; _nop_(); _nop_(); _nop_(); break; case 1: cs1=0;/*左屏*/ _nop_(); _nop_(); _nop_(); cs2=1; _nop_(); _nop_(); _nop_(); break; case 2: cs1=1;/*右屏*/ _nop_(); _nop_(); _nop_(); cs2=0; _nop_(); _nop_(); _nop_(); break; } } /*清屏screen: 0-全屏,1-左屏,2-右*/ void ClearScreen(uchar screen) { uchar i,j; SelectScreen(screen); for(i=0;i<8;i++) /*控制页数0-7,共8页*/ { SetLine(i); SetColumn(0); for(j=0;j<64;j++) /*控制列数0-63,共64列*/ { WriteByte(0x00); /*写点内容,列地址自动加1*/ } } } /*初始化LCD*/ void InitLCD() { CheckState(); SelectScreen(0); SetOnOff(0); /*关显示*/ SelectScreen(0); SetOnOff(1); /*开显示*/ SelectScreen(0); ClearScreen(0); /*清屏*/ SetStartLine(0);/*开始行:0*/ } /*--------------------------显示全角汉字-----------------------*/ /*ss选屏参数,pagr选页参数,column选列参数,number选第几汉字输出*/ /*ss=1右屏2左屏,pagr=0,2,4,6第0~3行,column=0~3汉子出现的列,number选第几汉字输出*/ void Display(uchar ss,uchar page,uchar column,uchar number) { uchar i; SelectScreen(ss); column=column&0x3f; SetLine(page); /*写上半页*/ SetColumn(column); /*控制列*/ for(i=0;i<16;i++) /*控制16列的数据输出*/ { WriteByte(Hzk[i+32*number]);/*i+32*number汉字的前16个数据输出*/ } SetLine(page+1); /*写下半页*/ SetColumn(column); /*控制列*/ for(i=0;i<16;i++) /*控制16列的数据输出*/ { WriteByte(Hzk[i+32*number+16]);/*i+32*number+16汉字的后16个数据输出*/ } } /*---------------------显示半角汉字和数字和字母----------------------*/ /*选屏参数,pagr选页参数,column选列参数,number选第几汉字输出*/ void Displayen(uchar ss,uchar page,uchar column,uchar number) { uchar i; SelectScreen(ss); column=column&0x3f; SetLine(page); /*写上半页*/ SetColumn(column); for(i=0;i<8;i++) { WriteByte(Ezk[i+16*number]); } SetLine(page+1); /*写下半页*/ SetColumn(column); for(i=0;i<8;i++) { WriteByte(Ezk[i+16*number+8]); } } /******************************************** 内部函数,延时1 ********************************************/ void Delay() { // {P10=1;_nop_();P10=0;} _nop_(); _nop_(); /*根据晶振频率制定延时时间*/ } /******************************************** 内部函数,I2C开始 ********************************************/ void P8563_Start() { EA=0; SDA=1; SCL=1; Delay(); SDA=0; Delay(); SCL=0; } /******************************************** 内部函数,I2C结束 ********************************************/ void P8563_Stop() { SDA=0; SCL=0; Delay(); SCL=1; Delay(); SDA=1; Delay(); EA=1; } /******************************************** 内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1; ********************************************/ void P8563_WriteACK(uchar ack) { SDA=ack; Delay(); SCL=1; Delay(); SCL=0; } /******************************************** 内部函数,等待ACK ********************************************/ void P8563_WaitACK() { uchar errtime=20; SDA=1; Delay(); /*读ACK*/ SCL=1; Delay(); while(SDA) { errtime--; if(!errtime) P8563_Stop(); } SCL=0; Delay(); } /******************************************** 内部函数.输出数据字节 入口:B=数据 ********************************************/ void P8563_writebyte(uchar wdata) { uchar i; for(i=0;i<8;i++) { if(wdata&0x80) SDA=1; else SDA=0; wdata<<=1; SCL=1; Delay(); SCL=0; } P8563_WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯 } /******************************************** 内部函数.输入数据 出口:B ********************************************/ uchar P8563_Readbyte() { uchar i,bytedata; SDA=1; for(i=0;i<8;i++) { SCL=1; bytedata<<=1; bytedata|=SDA; SCL=0; Delay(); } return(bytedata); } /******************************************** 输出数据->pcf8563 ********************************************/ void P8563_writeData(uchar address,uchar mdata) { P8563_Start(); P8563_writebyte(0xa2); /*写命令*/ P8563_writebyte(address); /*写地址*/ P8563_writebyte(mdata); /*写数据*/ P8563_Stop(); } /******************************************** 输入数据<-pcf8563 ********************************************/ uchar P8563_ReadData(uchar address) /*单字节*/ { uchar rdata; P8563_Start(); P8563_writebyte(0xa2); /*写命令*/ P8563_writebyte(address); /*写地址*/ P8563_Start(); P8563_writebyte(0xa3); /*读命令*/ rdata=P8563_Readbyte(); P8563_WriteACK(1); P8563_Stop(); return(rdata); } void P8563_ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/ { uchar i; P8563_Start(); P8563_writebyte(0xa2); /*写命令*/ P8563_writebyte(address); /*写地址*/ P8563_Start(); P8563_writebyte(0xa3); /*读命令*/ for(i=0;i buff[i]=P8563_Readbyte(); if(i P8563_WriteACK(1); P8563_Stop(); } /******************************************** 内部函数,读入时间到内部缓冲区 ********************************************/ void P8563_Read() { uchar time[7],century; P8563_ReadData1(0x02,0x07,time); century=time[5]; g8563_Store[0]=time[0]&0x7f; /*秒*/ g8563_Store[1]=time[1]&0x7f; /*分*/ g8563_Store[2]=time[2]&0x3f; /*小时*/ g8563_Store[3]=time[3]&0x3f; /*日*/ g8563_Store[4]=time[4]&0x07; /*星期*/ g8563_Store[5]=time[5]&0x1f; /*月*/ g8563_Store[6]=time[6]&0xff; /*年*/ g8563_Store[7]=century&0x80; /*取世纪,00为2000,80为1900*/ if(g8563_Store[7]==0x00)g8563_Store[7]=20; if(g8563_Store[7]==0x80)g8563_Store[7]=19; } /******************************************** 读入时间到内部缓冲区----外部调用 ********************************************/ void P8563_gettime() { P8563_Read(); if(g8563_Store[0]==0) P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/ } /******************************************** 写时间修改值 ********************************************/ void P8563_settime() { P8563_writeData(2,g8563_Store[0]);//秒 P8563_writeData(3,g8563_Store[1]);//分 P8563_writeData(4,g8563_Store[2]);//时 P8563_writeData(5,g8563_Store[3]);//日 P8563_writeData(6,g8563_Store[4]);//星期 if(g8563_Store[7]==0x20)g8563_Store[5]=(g8563_Store[5]&0x3F);//判断世纪 if(g8563_Store[7]==0x19)g8563_Store[5]=(g8563_Store[5]|0x80);//判断世纪 P8563_writeData(7,g8563_Store[5]);//月 P8563_writeData(8,g8563_Store[6]);//年 } /******************************************** P8563的初始化 ********************************************/ void P8563_init() { uchar i; if((P8563_ReadData(0xa)&0x3f)!=0x8) /*检查是否第一次启动,是则初始化时间*/ { for(i=0;i<8;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/ P8563_settime(); P8563_writeData(0x0,0x00); P8563_writeData(0xa,0x8); /*8:00报警*/ P8563_writeData(0x1,0x12); /*报警有效*/ P8563_writeData(0xd,0xf0); } } //---BCD转换16函数---// void BCD_16( ) { uchar i,ucData1,ucData2; for(i=0;i<7;i++) { ucData1=g8563_Store[i]/16; //BCD码转十六进制 ucData2=g8563_Store[i]; g8563_Store[i]=ucData1*10+ucData2; } } //---DS18B20延时函数---// void delay_18B20(unsigned int i)//延时1微秒 { while(i--); } //---DS18B20复位函数---// //DS18B20要求数据线拉低500US即可复位。 void ds1820rst() { unsigned char x=0; } DQ = 1;//DQ复位 delay_18B20(4);//延时 DQ = 0;//DQ拉低 delay_18B20(100);//精确延时大于480us DQ = 1;//拉高 delay_18B20(40); //---DS18B20读数据函数---// unsigned char ds1820rd() { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; //给脉冲信号 dat>>=1; DQ = 1; //给脉冲信号 if(DQ) dat|=0x80; delay_18B20(10); } return(dat); } //---DS18B20写数据函数---// void ds1820wr(unsigned char wdata) { unsigned char i=0; } for (i=8; i>0; i--) { DQ = 0; DQ = wdata&0x01; delay_18B20(10); DQ = 1; wdata>>=1; } //---读取温度值并转换---// read_temp() { unsigned char a,b; ds1820rst(); ds1820wr(0xCC);//跳过ROM _nop_(); //ds1820wr(0x4E);//写EEPROM,发出向内部RAM的3、4 字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据 // ds1820wr(0x00);//Th //ds1820wr(0x00);//Tl ds1820wr(0x7f);//12 bits温度分辨率0x1f, 0x3f, 0x5f ,0x7f温度读数分辨率分别对应0.5, 0.25, 0.125 ,0.0625 //ds1820wr(0xcc); //跳过读EPROM序列 //ds1820wr(0x48); 将RAM 中第3 、4 字节的内容复制到EEPROM 中. ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ _nop_(); ds1820wr(0x44);//*启动温度转换*/ ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0xbe);//*读取温度*/ a=ds1820rd(); b=ds1820rd(); tvalue=b; tvalue<<=8; tvalue=tvalue|a; if(tvalue<0x0fff)tflag=0; else {tvalue=~tvalue+1; tflag=1; } f_temp=tvalue*(0.0625); // 温度在寄存器中为12位,分辨率为0.0625 tvalue=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5时四舍五入 return(tvalue); } //---填充显示缓冲区函数---// void DisplayBuf_DS18B20(uint n) { SegBuf_DS18B20[3] =n; SegBuf_DS18B20[2] =n/10; SegBuf_DS18B20[1] =n/100; } if(SegBuf_DS18B20[1]==0)SegBuf_DS18B20[1]=10;//消除前面的0 if(tflag==0)SegBuf_DS18B20[0] =11; //正温度,不显示符号 if(tflag==1)SegBuf_DS18B20[0] =12; //负温度,显示“-”号 void DisplaySecond(uchar x) //写入12864秒 { uchar i,j; i=x/10; j=x; Displayen(1,4,0*8,i); Displayen(1,4,1*8,j); } void DisplayMinute(uchar x) //写入12864分 { uchar i,j; i=x/10; j=x; Displayen(2,4,4*8,i); Displayen(2,4,5*8,j); } void DisplayHour(uchar x) //写入12864小时 { uchar i,j; i=x/10; j=x; Displayen(2,4,0*8,i); Displayen(2,4,1*8,j); } void DisplayDay(uchar x) //写入12864天 { uchar i,j; i=x/10; j=x; Displayen(1,0,2*8,i); Displayen(1,0,3*8,j); } void DisplayMonth(uchar x) //写入11864月 { uchar i,j; i=x/10; j=x; Displayen(2,0,6*8,i); Displayen(2,0,7*8,j); } void DisplayYear(uchar x) //写入12864年 { uchar i,j; i=x/10; j=x; Displayen(2,0,2*8,i);//0 Displayen(2,0,3*8,j);//0 } void DisplayWeek(uchar x) //写入12864星期 { Display(2,2,2*16,(x+8)); } void DisplayCentury(uchar x) //写入12864世纪 { uchar i,j; i=x/10; j=x; Displayen(2,0,0*8,i); Displayen(2,0,1*8,j); } void displayPCF8563(void) { DisplaySecond(g8563_Store[0]); DisplayMinute(g8563_Store[1]); DisplayHour(g8563_Store[2]); DisplayDay(g8563_Store[3]); DisplayMonth(g8563_Store[5]); DisplayYear(g8563_Store[6]); DisplayWeek(g8563_Store[4]); DisplayCentury(g8563_Store[7]); } void displayDS18B20(void) { Displayen(1,6,0*8,SegBuf_DS18B20[0]);//+- Displayen(1,6,1*8,SegBuf_DS18B20[1]);//温度十位 Displayen(1,6,2*8,SegBuf_DS18B20[2]);//温度个位 Displayen(1,6,3*8,13);//小数点 Displayen(1,6,4*8,SegBuf_DS18B20[3]);//小数点1位 Display(1,6,3*16,26);//度 } void turn_val(uchar newval,uchar flag,uchar newaddr,uchar s1num) //newval是时间日期值,flag是时间日期增减标识,newaddr是读取数据的地址,s1num是年月日时分秒星期的数字标识 { uchar ucData1,ucData2,SETCentury; newval=P8563_ReadData(newaddr); switch(newaddr) { case 0x02:newval=(newval&0x7f); /*秒*/ break; case 0x03:newval=(newval&0x7f); /*秒*/ break; case 0x04:newval=(newval&0x3f);/*小时*/ break; case 0x05:newval=(newval&0x3f); /*日*/ break; case 0x06:newval=(newval&0x07); /*星期*/ break; case 0x07:newval=(newval&0x1f);/*月*/ break; case 0x08:newval=(newval&0xff);/*年*/ } ucData1=newval/16; //BCD码转十六进制 ucData2=newval; newval=ucData1*10+ucData2; if(flag) //判断是加一还是减一 { newval++; switch(s1num) { case 1: if(newval>99) { SETCentury=P8563_ReadData(0x07); g8563_Store[7]=SETCentury&0x80; /*取世纪,00为2000,80为1900*/ if(g8563_Store[7]==0x00)g8563_Store[7]=19;//2099年变为1900年 if(g8563_Store[7]==0x80)g8563_Store[7]=20;//1999年变为2000年 if(g8563_Store[7]==20)g8563_Store[5]=(g8563_Store[5]&0x3F); if(g8563_Store[7]==19)g8563_Store[5]=(g8563_Store[5]|0x80); P8563_writeData(7,g8563_Store[5]);//重新写月,从而把世纪状态写回 P8563。 newval=0; } DisplayCentury(g8563_Store[7]); DisplayYear(newval); break; case 2: if(newval>12) newval=1; DisplayMonth(newval); break; case 3: if(newval>31) newval=1; DisplayDay(newval); break; case 4: if(newval>6) newval=0; DisplayWeek(newval); break; case 5: if(newval>23) newval=0; DisplayHour(newval); break; case 6: if(newval>59) newval=0; DisplayMinute(newval); break; case 7: if(newval>59) newval=0; DisplaySecond(newval); break; default:break; } } else { newval--; switch(s1num) { case 1: if(newval==0xff) { SETCentury=P8563_ReadData(0x07);//读取月,月的高位1为世纪19**年,0表示20**年 g8563_Store[7]=SETCentury&0x80; /*取世纪,00为2000,80为1900*/ if(g8563_Store[7]==0x00)g8563_Store[7]=19;//2000年变为1999年 if(g8563_Store[7]==0x80)g8563_Store[7]=20;//1999年变为2000年 if(g8563_Store[7]==20)g8563_Store[5]=(g8563_Store[5]&0x3F); if(g8563_Store[7]==19)g8563_Store[5]=(g8563_Store[5]|0x80); P8563_writeData(7,g8563_Store[5]);//重新写月,从而把世纪状态写回P8563。 newval=99; } DisplayCentury(g8563_Store[7]); DisplayYear(newval); break; case 2: if(newval==0) newval=12; DisplayMonth(newval); break; case 3: if(newval==0) newval=31; DisplayDay(newval); break; case 4: if(newval==0xff) newval=6; DisplayWeek(newval); break; case 5: if(newval==0xff) newval=23; DisplayHour(newval); break; case 6: if(newval==0xff) newval=59; DisplayMinute(newval); } } break; case 7: if(newval==0xff) newval=59; DisplaySecond(newval); break; default:break; ucData1=newval/10;//十六进制转BCD码 ucData2=newval; newval=ucData1*16+ucData2; P8563_writeData(newaddr,newval); } void delayKEY(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //键盘扫描程序 void key_scan(void) { uchar s1num=0; //s1num记录光标的位置的编号 if(menu==0) { delayKEY(5); if(menu==0) { while(!menu); //menum测试到由0到1的变化,也就是按下松开的变化,s1num加1 s1num++; while(1) { if(menu==0) { delayKEY(5); if(menu==0) { while(!menu); s1num++; //menum测试到由0到1的变化,也就是按下松开的变化,s1num再加1 } } 字。 1302 P8563_writeData(0x0,0x20);//停止计时,开始相关设置。 if(s1num==1) { Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,0);//年 Display(1,2,3*16,27);//空格 year=P8563_ReadData(0x08); year=year&0xff;//读取年 Reverse_Display=1; DisplayYear(((year/16)*10+(year)));//设置年的时候反相显示即黑底白Reverse_Display=0; if(add==0) { delayKEY(3); if(add==0) { while(!add); turn_val(year,1,0x08,1); } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); turn_val(year,0,0x08,1);//读取当前年值,根据减小年值,并写入 } } } if(s1num==2) 黑底白字 { DisplayYear(((year/16)*10+(year))); //年变回白底黑字。 Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,1);//月 Display(1,2,3*16,27);//空格 month=P8563_ReadData(0x07); month=month&0x1f;//读取月 Reverse_Display=1; DisplayMonth(((month/16)*10+(month))); //设置月的时候反相显示即Reverse_Display=0; if(add==0) { delayKEY(3); if(add==0) { while(!add); turn_val(month,1,0x07,2); } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); turn_val(month,0,0x07,2); } } } if(s1num==3) { DisplayMonth(((month/16)*10+(month))); //月变回白底黑字。 Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,2);//日 Display(1,2,3*16,27);//空格 day=P8563_ReadData(0x05); day=day&0x3f;//读取日 Reverse_Display=1; DisplayDay(((day/16)*10+(day))); //设置日的时候反相显示即黑底白字 Reverse_Display=0; if(add==0) { delayKEY(3); if(add==0) { while(!add); turn_val(day,1,0x05,3); } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); 底白字 turn_val(day,0,0x05,3); //写入日寄存器 } } } if(s1num==4) { DisplayDay(((day/16)*10+(day)));//天变回白底黑字。 Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,3);//星 Display(1,2,3*16,4);//期 week=P8563_ReadData(0x06); week=week&0x07;//读取星期 Reverse_Display=1; DisplayWeek(((week/16)*10+(week))); //设置星期的时候反相显示即黑Reverse_Display=0; if(add==0) 白字 } { delayKEY(3); if(add==0) { while(!add); turn_val(week,1,0x06,4); } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); turn_val(week,0,0x06,4); } } if(s1num==5) { DisplayWeek(((week/16)*10+(week)));//星期变回白底黑字 Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,5);//时 Display(1,2,3*16,27);//空格 hour=P8563_ReadData(0x04); hour=hour&0x3f;//读取小时 Reverse_Display=1; DisplayHour(((hour/16)*10+(hour))); //设置时的时候反相显示即黑底Reverse_Display=0; if(add==0) { delayKEY(3); if(add==0) { while(!add); turn_val(hour,1,0x04,5); } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); turn_val(hour,0,0x04,5); 黑底白字 } } } if(s1num==6)//调时间分 { DisplayHour(((hour/16)*10+(hour))); //小时变回白底黑字 Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,6);//分 Display(1,2,3*16,27);//空格 minute=P8563_ReadData(0x03); minute=minute&0x7f;//读取分 Reverse_Display=1; DisplayMinute(((minute/16)*10+(minute))); //设置分的时候反相显示即Reverse_Display=0; if(add==0) { delayKEY(5); if(add==0) { while(!add); turn_val(minute,1,0x03,6);//写入分寄存器 } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); turn_val(minute,0,0x03,6);//写入分寄存器 } 黑底白字 } } if(s1num==7)//调时间秒 { DisplayMinute(((minute/16)*10+(minute)));//分变回白底黑字 Display(1,2,0*16,21);//设 Display(1,2,1*16,22);//置 Display(1,2,2*16,7);//秒 Display(1,2,3*16,27);//空格 second=P8563_ReadData(0x02); second=second&0x7f;//读取秒 Reverse_Display=1; DisplaySecond(((second/16)*10+(second))); //设置秒的时候反相显示即Reverse_Display=0; if(add==0) { delayKEY(3); if(add==0) { while(!add); if(second==0x60) second=0x00; turn_val(second,1,0x02,7); } } if(dec==0) { delayKEY(3); if(dec==0) { while(!dec); turn_val(second,0,0x02,7); } } } if(s1num==8) { DisplaySecond(((second/16)*10+(second)));//秒变回白底黑字 Display(1,2,0*16,23);//运 Display(1,2,1*16,24);//行 Display(1,2,2*16,25);//中 Display(1,2,3*16,27);//空格 P8563_writeData(0x0,0x00);//设置结束,开始计时 s1num=0;//s1num清零// break; } } } } } void Init_DIS() { Displayen(2,0,0*8,2);//2 Displayen(2,0,1*8,0);//0 Displayen(2,0,2*8,0);//0 Displayen(2,0,3*8,0);//0 Display(2,0,2*16,0);//年 Displayen(2,0,6*8,1);//1 Displayen(2,0,7*8,2);//2 Display(1,0,0*16,1);//月 Displayen(1,0,2*8,3);//3 Displayen(1,0,3*8,1);//1 Display(1,0,2*16,2);//日 Display(2,2,0*16,3);//星 Display(2,2,1*16,4);//期 Display(2,2,2*16,8);//天 Displayen(2,4,0*8,2);//2 Displayen(2,4,1*8,3);//3 Display(2,4,1*16,5);//时 Displayen(2,4,4*8,5);//5 Displayen(2,4,5*8,9);//9 Display(2,4,3*16,6);//时 Displayen(1,4,0*8,5);//4 Displayen(1,4,1*8,9);//7 Display(1,4,1*16,7);//时 Display(2,6,0*16,17);//温 Display(2,6,1*16,18);//度 } Display(2,6,2*16,19);//是 Display(2,6,3*16,20);//: Display(1,2,0*16,23);//运 Display(1,2,1*16,24);//行 Display(1,2,2*16,25);//中 /*主函数*/ void main() { P8563_init();//p8563初始化 InitLCD(); /*初始12864*/ Init_DIS(); while(1) { P8563_gettime(); BCD_16( ); displayPCF8563(); temp=read_temp();//读取温度 DisplayBuf_DS18B20(temp); displayDS18B20( ); key_scan(); } }
正在阅读:
基于PCF8563的单片机数字时钟07-01
海豚绘本花园-重点品资料02-28
2016GRE阅读机经 - -经典反复重现题整理(附答案)04-03
鲜乳中抗生素残留检验04-20
泰州市专业技术人员公修科目“沟通与协调能力”测试题及答案06-28
公共政策概论网考题目大全04-06
潍坊歌尔实习报告04-28
导师介绍(结构) - 图文12-04
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 单片机
- 时钟
- 基于
- PCF8563
- 数字
- ITMS在网络中的位置和作用
- 五年级下册综合实践课教案陕师大版
- 安徽重点项目-芜湖年产43000吨阻燃、隔音、隔热材料生产线项目可
- 年产8万吨聚丙烯生产工艺设计
- 2013年中考数学试卷分类汇编2--5:分式
- 网络论坛设计
- 031128=PBM
- 外科习题
- 2010年12月英语六级全真预测卷及解析(1)
- 出国旅游英语句子大全
- 2017年新人教版小学3三年级数学上册期末复习试卷【全套】
- 钢轨探伤工复习思考题及答案
- 2016年申论考试名言警句篇 必看
- 原位微区分析在矽卡岩矿床矿物中的研究进展
- 高一物理 气体性质
- S版六年级上册作文
- 第四版人民币801天蓝冠号全分析
- 经济法知识教案
- 市政工程小三线施工流程
- 2016-2022年中国相机皮套市场竞争现状报告 - 图文