手头有个DS1302时钟芯片,正好学习一下。这个蕊片具有掉电时钟继续走时的特点(要有电池或超级电容)。还是KEIL编程序,PROTEUS做仿真,然后加实物,用的lcd240×64液晶屏,驱动芯片是t6963c,做了一个简单的开心万年历.







关于此屏幕的Proteus仿真文件下载请到:http://www.51hei.com/bbs/dpj-42069-1.html
LCD240*64液晶的51单片机驱动程序:
- #include<reg52.h> // 52头文件
- #include<intrins.h> // 包含_onp_
- #define uchar unsigned char //宏定义uchar 为unsigned char
- #define uint unsigned int //宏定义uint 为unsiened int
- #define nop() _nop_() //宏定义延时
- #define wds1302_sec 0x80 //秒数据地址
- #define wds1302_min 0x82 //分数据地址
- #define wds1302_hr 0x84 //时数据地址
- #define wds1302_date 0x86 //日数据地址
- #define wds1302_month 0x88 //月数据地址
- #define wds1302_day 0x8a //星期数据地址
- #define wds1302_year 0x8c //年数据地址
- #define ds1302_control 0x8e //控制数据地址
- #define ds1302_charger 0x90 //涓流
- #define ds1302_clkburst 0xbe
- #define rds1302_sec 0x81 //秒数据地址
- #define rds1302_min 0x83 //分数据地址
- #define rds1302_hr 0x85 //时数据地址
- #define rds1302_date 0x87 //日数据地址
- #define rds1302_month 0x89 //月数据地址
- #define rds1302_day 0x8b //星期数据地址
- #define rds1302_year 0x8d //年数据地址
- sbit ce=P1^0; //片选
- sbit cd=P1^3; //命令或数据
- sbit rd=P1^4; //读
- sbit wr=P1^5; //写
- sbit rst=P1^6; //复位
- sbit rest=P3^5; //1302复位
- sbit sclk=P3^6; //1302时钟
- sbit io=P3^7; //1302输入输出口
- void read1302display();
- //sbit sta0=P2^0; //测执行命令忙
- //sbit sta1=P2^1; //测读写数据忙
- //sbit sta2=P2^3; //测连续写忙
- uchar time_buf1[8]={0x15,0x12,0x04,0x16,0x25,0x00};//年月日时分秒周
- uchar buf[8] ;//空年月日时分秒周
- //uchar buf1[8]; //存修改完成的时间数据
- uint text_size,graphic_size; //定义文本区和图形区宽度
- uint text_startaddr,graphic_startaddr; //文本和图形土起始位
- uint text_startaddr_l,text_startaddr_h; //定义文本区起始高位低位置
- uint graphic_startaddr_l,graphic_startaddr_h; //定义图形区首地址
- uint *p; //图片数据指针
- uint t,t1,key; //中断计数变量
- uchar bcd[2]; //从DS1302读出数据转BCD码
- uchar flag=0,next; //进入调节标志位
- uchar yx=0; //键盘返回有效的值
- uchar code cgtab[]={
- //--黑点 --
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- //-- 年 --
- 0x08,0x08,0x1F,0x11,0x21,0x41,0x1F,0x11,
- 0x11,0x11,0xFF,0x01,0x01,0x01,0x01,0x01,
- 0x00,0x08,0xFC,0x00,0x00,0x10,0xF8,0x00,
- 0x00,0x04,0xFE,0x00,0x00,0x00,0x00,0x00,
- //-- 月 --
- 0x00,0x0F,0x08,0x08,0x08,0x0F,0x08,0x08,
- 0x08,0x0F,0x08,0x08,0x10,0x10,0x20,0x40,
- 0x10,0xF8,0x10,0x10,0x10,0xF0,0x10,0x10,
- 0x10,0xF0,0x10,0x10,0x10,0x10,0x50,0x20,
- //-- 日 --
- 0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x1F,
- 0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,
- 0x10,0xF8,0x10,0x10,0x10,0x10,0x10,0xF0,
- 0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0x00,
- //-- 时 --
- 0x00,0x04,0x7E,0x44,0x47,0x44,0x44,0x7C,
- 0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00,
- 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x88,
- 0x48,0x48,0x08,0x08,0x08,0x48,0x28,0x10,
- //-- 分 --
- 0x00,0x04,0x04,0x08,0x08,0x10,0x20,0x4F,
- 0x84,0x04,0x04,0x04,0x04,0x08,0x11,0x20,
- 0x80,0x80,0x40,0x40,0x20,0x10,0x08,0xEE,
- 0x24,0x20,0x20,0x20,0x20,0x20,0x40,0x80,
- //-- 秒 --
- 0x04,0x0E,0x78,0x08,0x08,0xFE,0x08,0x1D,
- 0x1A,0x28,0x28,0x48,0x88,0x08,0x08,0x0B,
- 0x20,0x20,0x20,0x20,0xA8,0xA6,0xA2,0x20,
- 0x24,0x24,0x28,0x10,0x20,0x40,0x80,0x00,
- //-- 周 --
- 0x00,0x3F,0x21,0x21,0x2F,0x21,0x21,0x3F,
- 0x20,0x27,0x24,0x24,0x24,0x47,0x84,0x00,
- 0x08,0xFC,0x08,0x48,0xE8,0x08,0x28,0xF8,
- 0x48,0xE8,0x48,0x48,0x48,0xC8,0x28,0x10,
- //-- 闹 --
- 0x40,0x37,0x10,0x42,0x41,0x5F,0x41,0x41,
- 0x4F,0x49,0x49,0x49,0x49,0x41,0x41,0x40,
- 0x04,0xFE,0x04,0x04,0x24,0xF4,0x04,0x24,
- 0xF4,0x24,0x24,0x24,0x64,0x04,0x14,0x08,
- //-- 钟 --
- 0x10,0x10,0x10,0x1C,0x21,0x21,0x7D,0x91,
- 0x11,0xFD,0x11,0x10,0x14,0x18,0x10,0x00,
- 0x20,0x20,0x20,0x24,0xFE,0x24,0x24,0x24,
- 0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20,
- //-- 0 --
- 0x00,0x00,0x03,0x06,0x0C,0x0C,0x0C,0x0C,
- 0x0C,0x0C,0x0C,0x0C,0x06,0x03,0x00,0x00,
- 0x00,0x00,0xE0,0x30,0x18,0x18,0x18,0x18,
- 0x18,0x18,0x18,0x18,0x30,0xE0,0x00,0x00,
- //-- 1 --
- 0x00,0x00,0x00,0x03,0x01,0x01,0x01,0x01,
- 0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,
- 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,
- 0x80,0x80,0x80,0x80,0x80,0xC0,0x00,0x00,
- //-- 2 --
- 0x00,0x00,0x03,0x06,0x0C,0x0C,0x00,0x00,
- 0x00,0x00,0x01,0x03,0x06,0x0F,0x00,0x00,
- 0x00,0x00,0xC0,0x60,0x30,0x30,0x30,0x30,
- 0x60,0xC0,0x80,0x10,0x10,0xF0,0x00,0x00,
- //-- 3 --
- 0x00,0x00,0x03,0x06,0x0C,0x00,0x00,0x01,
- 0x00,0x00,0x00,0x0C,0x06,0x03,0x00,0x00,
- 0x00,0x00,0xC0,0x60,0x30,0x30,0x60,0xC0,
- 0x60,0x30,0x30,0x30,0x60,0xC0,0x00,0x00,
- //-- 4 --
- 0x00,0x00,0x00,0x01,0x03,0x02,0x06,0x0C,
- 0x0C,0x18,0x1F,0x00,0x00,0x01,0x00,0x00,
- 0x00,0x40,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
- 0xC0,0xC0,0xF0,0xC0,0xC0,0xE0,0x00,0x00,
- //-- 5 --
- 0x00,0x00,0x0F,0x0C,0x0C,0x0C,0x0F,0x0E,
- 0x00,0x00,0x00,0x0C,0x06,0x03,0x00,0x00,
- 0x00,0x00,0xF0,0x00,0x00,0x00,0xC0,0x60,
- 0x30,0x30,0x30,0x30,0x60,0xC0,0x00,0x00,
- //-- 6 --
- 0x00,0x00,0x03,0x06,0x0C,0x0C,0x0D,0x0E,
- 0x0C,0x0C,0x0C,0x0C,0x06,0x03,0x00,0x00,
- 0x00,0x00,0xC0,0x60,0x30,0x00,0xC0,0x60,
- 0x30,0x30,0x30,0x30,0x60,0xC0,0x00,0x00,
- //-- 7 --
- 0x00,0x00,0x0F,0x0F,0x08,0x00,0x00,0x00,
- 0x01,0x01,0x03,0x03,0x03,0x03,0x00,0x00,
- 0x00,0x00,0xF0,0xF0,0x30,0x60,0xC0,0xC0,
- 0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
- //-- 8 --
- 0x00,0x00,0x03,0x06,0x0C,0x0C,0x06,0x03,
- 0x06,0x0C,0x0C,0x0C,0x06,0x03,0x00,0x00,
- 0x00,0x00,0xC0,0x60,0x30,0x30,0x60,0xC0,
- 0x60,0x30,0x30,0x30,0x60,0xC0,0x00,0x00,
- //-- 9 --
- 0x00,0x00,0x03,0x06,0x0C,0x0C,0x0C,0x0C,
- 0x06,0x03,0x00,0x0C,0x06,0x03,0x00,0x00,
- 0x00,0x00,0xC0,0x60,0x30,0x30,0x30,0x30,
- 0x70,0xF0,0x30,0x30,0x60,0xC0,0x00,0x00,
- //-- : --
- 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0F,
- 0x0F,0x06,0x00,0x06,0x0F,0x0F,0x06,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- //-- 祝 --
- 0x20,0x13,0x12,0x02,0xFE,0x0A,0x12,0x3B,
- 0x56,0x90,0x10,0x11,0x11,0x12,0x14,0x18,
- 0x08,0xFC,0x08,0x08,0x08,0x08,0x08,0xF8,
- 0xA8,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00,
- //-- 您 --
- 0x09,0x09,0x13,0x12,0x34,0x59,0x91,0x12,
- 0x14,0x11,0x10,0x02,0x51,0x50,0x90,0x0F,
- 0x00,0x00,0xFC,0x04,0x48,0x40,0x50,0x4C,
- 0x44,0x40,0x80,0x00,0x84,0x92,0x12,0xF0,
- //-- 刻 --
- 0x08,0x04,0x04,0xFF,0x04,0x08,0x10,0x7F,
- 0x02,0x04,0x09,0x72,0x06,0x19,0xE0,0x00,
- 0x04,0x04,0x84,0xC4,0x04,0xA4,0xA4,0x24,
- 0x24,0xA4,0x24,0x24,0x04,0x84,0x94,0x08,
- //-- 都 --
- 0x10,0x12,0x7F,0x12,0x14,0xFF,0x08,0x12,
- 0x3F,0x62,0xA2,0x3E,0x22,0x22,0x3E,0x22,
- 0x00,0x7C,0x44,0x44,0x48,0x48,0x50,0x48,
- 0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
- //-- 开 --
- 0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0xFF,
- 0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,
- 0x08,0xFC,0x20,0x20,0x20,0x20,0x24,0xFE,
- 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
- //-- 心 --
- 0x02,0x01,0x00,0x00,0x08,0x08,0x28,0x28,
- 0x28,0x48,0x88,0x08,0x08,0x08,0x07,0x00,
- 0x00,0x00,0x80,0xC0,0x80,0x00,0x08,0x04,
- 0x02,0x02,0x02,0x00,0x10,0x10,0xF0,0x00,
- //-- 间 --
- 0x20,0x1B,0x08,0x40,0x4F,0x48,0x48,0x48,
- 0x4F,0x48,0x48,0x48,0x4F,0x48,0x40,0x40,
- 0x04,0xFE,0x04,0x24,0xF4,0x24,0x24,0x24,
- 0xE4,0x24,0x24,0x24,0xE4,0x24,0x14,0x08
- };
- /*********************延时函数************************************/
- void delay(uint a)
- {
- uchar b;
- for( ;a>0;a--)
- for(b=110;b>0;b--);
- }
- /***********************键盘扫描************************************/
- char key_scan()
- {
- uchar temp; //定义变量
- P0=0xef; //把高位一条拉低电平 11101111 给P0
- temp=P0; //把P0口电平读回给临时变量
- if((temp&0x0f)!=0x0f) //检测有无按键按下
- {
- delay(10); //延时10毫秒
-
- temp=P0; //把P0口数值读给变量
- P0=0xef; //重新给P0口赋值
- if((temp&0x0f)!=0x0f) //检测有无按键按下
- {
- temp=P0; //把P0口数值读给变量
- switch(temp) //分支选择数值
- {
- case 0xee: //11101110 按键1按下
- key=1; //按键值为1
-
- break; //返回退出
- case 0xed: //11101101 按键4按下
- key=4; //按键值为4
- break; //返回退出
- case 0xeb: //11101011 按键7按下
- key=7; //按键值为7
- break; //返回退出
- case 0xe7: //11100111 按键*按下
- key='*'; //按键值为*
- break; //返回退出
- }
- while(temp!=0x0f) //等待按键抬起
- {
- temp=P0; // 把P0数值给变量
- temp=temp&0x0f; // 检测按键是否抬起
- }
- yx=1; //键盘输入值有效
- }
- }
- P0=0xdf; //把高位拉低一条 11011111 值给P0
- temp=P0; //把P0口电平读回给临时变量
- if((temp&0x0f)!=0x0f) //检测有无按键按下
- {
- delay(10); //延时10毫秒
- P0=0xdf; //再把数值给P0
- temp=P0; //P0数值读给变量
- if((temp&0x0f)!=0x0f) //再次检测有无键按下
- {
- temp=P0; //把P0口数值赋给变量
- switch(temp) //分支选择
- {
- case 0xde: //11011110 按键2按下
- key=2; //按键值为2
- break; //返回退出
- case 0xdd: //11011101 按键5按下
- key=5; //按键值为5
- break; //返回退出
- case 0xdb: //11011011 按键8按下
- key=8; //按键值为8
- break; //退出返回
- case 0xd7: //11010111 按键0按下
- key=0; //返回值为0
- break; //返回退出
- }
- while(temp!=0x0f) //等待按键抬起
- {
- temp=P0; // 把P0数值给变量
- temp=temp&0x0f; // 检测按键是否抬起
- }
- yx=1; //键盘输入值有效
- }
- }
- P0=0xbf; //把高位拉低一条,10111111 把值给P0口
- temp=P0; //把P0口电平读回给临时变量
- if((temp&0x0f)!=0x0f) //检测有无按键按下
- {
- delay(10); //延时10毫秒
- P0=0xbf; //把值再给P0口
- temp=P0; //读回P0口实际值
- if((temp&0x0f)!=0x0f) //再检测有无按键按下
- {
- temp=P0; //重新读回P0口值
- switch(temp) //分支选择
- {
- case 0xbe: //10111110 按键3按下
- key=3; //按键值为3
- yx=1; //键盘输入值有效
- break; //返回退出
- case 0xbd: //10111101 安键6按下
- key=6; //按键值为6
- yx=1; //键盘输入值有效
- break; //返回退出
- case 0xbb: //10111011 按键9按下
- key=9; //按键值为9
- yx=1; //键盘输入值有效
- break; //返回退出
- case 0xb7: //10110111 按键#按下
- // key='#'; //按键值为#
- flag=1;
- break; //返回退出
- }
- while(temp!=0x0f) //等待按键抬起
- {
- temp=P0; // 把P0数值给变量
- temp=temp&0x0f; // 检测按键是否抬起
- }
-
- }
- }
-
- return key; //函数结束返回按键数值
- }
- /****************************ds1302写数据******************************/
- void write_date(uchar date)
- {
- uchar i,k; //定义变量
- k=date; //数据赋给变量
- rest=0; //置复位为0
- sclk=0;
- rest=1; //选中蕊片
- // k=k>>1;
- for(i=0;i<8;i++) //循环8位数据
- {
-
- if(k&0x01)io=1; //取出K低位给IO口
- sclk=0; //拉低时钟
- sclk=1; //拉高时钟数据给DS1302
-
- k=k>>1; //变量右移一位
- }
- rest=0;
- sclk=0;
- }
-
- /**************************ds1302地址写入数据****************************/
- void write_ad_dat(uint addr,uchar date)
- {
- uchar i; // 定义变量
- rest=0; // 复位片选
- sclk=0; // 拉低时钟
- rest=1; // 置位片选
- for(i=0;i<8;i++) // 8次循环
- {
- io=addr&0x01; // 把地址中低位给IO口
- sclk=1; // 拉高时钟使数据有效
- sclk=0; // 拉低时钟给下个高电平做准备
- addr>>=1; // 地址数据右移一位
- }
- for(i=0;i<8;i++) // 8次循环
- {
- io=date&0x01; // 把数据低位给IO口
- sclk=1; // 拉高时钟,使数据有效
- sclk=0; // 拉低时钟
- date>>=1; // 数据右移一位
- }
- rest=0; // 复位片选
- }
- /***************************读1302数据***********************************/
- uchar read_date()
- {
- uchar i,k; //定义变量
- rest=1; //片选为置位
- sclk=1; //拉高1302时钟
- for(i=0;i<8;i++) //8位数据循环
- {
-
- if(io) //读IO口状态给变量K
- {
- k=k|0x80; //如果IO口为1,变量赋值为1
- }
- sclk=1; //拉高时钟
- delay(1);
- sclk=0; //拉低时钟写入数据
- k=k>>1; //变量数据右移一位
- }
- rest=0; //关片选
- return k; //8位数据结束返回变量数值
- }
- /********************************读地址数据********************************/
- uchar read_add_dat(uint addr)
- {
- uchar i,j; //定义变量
- rest=0; //复位片选
- sclk=0; // 拉低时钟电平
- rest=1; // 置位片选
- for(i=0;i<8;i++) // 8位循环
- {
- sclk=0; // 拉低时钟
- io=addr&0x01; // 地址数据低位给IO口
- sclk=1; // 拉高时钟,使数据有效
- addr>>=1; // 地址数据右移一位
- }
- for(i=0;i<8;i++) // 8次循环
- {
- j>>=1; // 变量右移一位
- sclk=0; // 拉低时钟
- if(io) j|=0x80; // 如果IO口读出高电平,给变量高位置1
- sclk=1; // 拉高电平给下次读数据做准备
- }
- rest=0; // 复位片选
- return j; // 返回读出的变量值
- }
- /*******************写命令*****************************************/
- void wrcomm(uchar comm)
- {
- ce=0; //选中芯 片
- rd=1; //读高电平无效
- cd=1; //操作命令
- wr=0; //写使能
- P2=comm; //把命令送给总线
- nop(); //延时
- wr=1; //拉高写
- }
- /*******************写数据******************************************/
- void wrdate(uchar date)
- {
- ce=0; //使能片选
- rd=1; //读无效
- cd=0; //操作命令
- wr=0; //使能写
- P2=date; //数据送给总线
- nop(); //延时
- wr=1; //拉高写
- }
- /*******************测读写命令忙***********************************/
- void check_sta01()
- {
- uchar a; //定义变量
- ce=0; //使能片选
- wr=1; //禁写
- cd=1; //命令有效
- while(1) //循环
- {
- P2=0xff; //P2口为已知的高电平
- rd=0; //使能读
- a=P2; //读总线状态
- nop(); //延时
- rd=1; //拉高读
- if((a&0x03)==0x03) //测试等于0000 0011
- return; //测试如果读写数据为不忙跳出循环
- }
- }
- /*******************测试连续写忙************************************/
- void check_sta03()
- {
- uchar a; //定义变量
- ce=0; //全能片选
- wr=1; //禁写
- cd=1; //命令有效
- while(1)
- {
- P2=0xff; //使P2为已知的高电平
- rd=0; //使能读
- a=P2; //读总线状态
- nop(); //延时
- rd=1; //拉高读
- if((a&0x08)==0x08) //测试等于00001000
- return; //测试如果连续读为不忙跳出循环
- }
- }
- /************************写无参数命令************************************/
- void no_parameter(uchar comm)
- {
- check_sta01(); //测忙
- wrcomm(comm); //写命令
- }
- /************************写双字节参数命令*********************************/
- void double_parameter(uint a,uint b,uchar c)
- {
- check_sta01(); //测忙
- wrdate(a); //写第一字节参数
- check_sta01(); //测忙
- wrdate(b); //写第二节节参数
- check_sta01(); //测忙
- wrcomm(c); //写命令
- }
- /************************清屏全亮或全灭***********************************/
- void all_display(uchar state,uchar vlue)
- {
- uint i,k; //定义变量
- if(state==0) //判断state是否为0为文本区
- {
- double_parameter(text_startaddr_l,text_startaddr_h,0x24); //文本区低位和高位起始地址
- no_parameter(0xb0); //连续写命令
- for(i=1;i<9;i++)
- {
- for(k=0;k<30;k++) //每行为30字符(240*64 )
- {
- check_sta03(); //测忙
- wrdate(vlue);
- } //写入vlue值,0或1
- }
- check_sta03(); //测忙
- wrcomm(0xb2); //关连续写
- }
- if(state==1) //判断state是否为1
- {
- double_parameter(graphic_startaddr_l,graphic_startaddr_h,0x24); //图开形区起始低,高位
- no_parameter(0xb0); //连续写命令
- for(i=30*64;i>0;i--) //循环
- {
- check_sta03(); //测连续写忙
- wrdate(vlue); //写入vlue值
- }
- check_sta03(); //测忙
- wrcomm(0xb2); // 关闭连续写
- }
- }
- /****************************文本方式下写8*8字符******************************************/
- void text_ascii(uchar *addr,uchar hang,uchar lie)
- {
- uchar temp; //定义变量
- uchar low; //定义变量
- uchar high; //定义变量
- temp=30*(hang-1)+(lie-1); //每行30字符乘行加列,计算写入起始位置
- low=temp&0x00ff; //把结果低位赋给低变量
- high=(temp>>8)&0x00ff; //把结果高位给高变量
- double_parameter(low,high,0x24); //写入文本起始位置
- no_parameter(0xb0); //连续写命令
- check_sta03(); //测忙
- wrdate(*addr); //写入字符地址指针
- check_sta03(); //测连续写忙
- wrcomm(0xb2); //关闭连续写
- }
- /**************************graphic下显示图片*********************************************/
- void display(uchar *p,uchar hang,uchar lie)
- {
- uchar m,n; //定义变量
- uint temp; //定义变量
- temp=(hang-1)*30+lie; //计算图形写入地址
- graphic_startaddr_l=temp&0x00ff; //取出低位数据
- graphic_startaddr_h=(temp>>8)&0x00ff;
- double_parameter(graphic_startaddr_l,graphic_startaddr_h,0x24);//写入图形首地址
- no_parameter(0xb0); //连续写命令
- for(m=240;m>0;m--) //循环行数
- {
- for(n=30;n<0;n--) //每字节8位,列数/8
- {
- check_sta03(); //测忙
- wrdate(* p++); //写入图形指针,然后加1地址
- }
- }
- check_sta03(); //测忙
- wrcomm(0xb2); //关闭连续写
- }
- /************************text下显示16*16汉字**********************************************
- ***************text模式下是8*8字符,每个汉字要4个字符组成*********************************/
- void hz_display(uchar addr,uchar hang,uchar lie)
- {
- uint temp; //定义变量
- uchar low,high; //定义变量
- temp=30*2*(hang-1)+(lie-1)*2; //把字的坐标地址赋给变量
- low=temp&0x00ff; //取出坐标低位数值
- high=(temp>>8)&0x00ff; //右移8位取出坐标高位数值
- double_parameter(low,high,0x24); //写入汉字坐标
- no_parameter(0xb0); //开连续写
- check_sta03(); //测忙
- wrdate(addr); //写入汉字左上4分之1
- check_sta03(); //测试忙
- wrdate(addr+2); //写入汉字右上4分之1
- check_sta03(); //测忙
- wrcomm(0xb2); //关闭连续写
- delay(1);
- temp=30*2*(hang-1)+30+(lie-1)*2; //重新计算汉字坐标也就是写下部份,地址加一行(8*8)
- low=temp&0x00ff; //取出低位数值给变量
- high=(temp>>8)&0x00ff; //右移8位取出高位给变量
- double_parameter(low,high,0x24); //写入新起始地址(写汉字下部份)
- no_parameter(0xb0); //连续写命令
- check_sta03(); //测忙
- wrdate(addr+1); //写入汉字左下4分之1
- check_sta03(); //测忙
- wrdate(addr+3); //写入汉字右下4分之1
- check_sta03(); //测忙
- wrcomm(0xb2); //关闭连续写
- }
- /******************************自定义汉字写入CGRAM***************************************/
- void cgram()
- {
- uint m=0; //定义变量
- double_parameter(0x07,0x00,0x22); //设定最高的1K为CGRAM 寄存器偏移设定
- double_parameter(0x00,0x3c,0x24); //
- no_parameter(0xb0); //开连续写
- for(m=0;m<896+32;m++) //循环
- {
- check_sta03(); //测忙
- wrdate(cgtab[m]); //写入数据
- }
- check_sta03(); //测忙
- wrcomm(0xb2); //关闭连续写
- }
- /*****************************定时器初始化*************************************************/
- void time()
- {
- TMOD=0x01; //开定时器0
- TH0=(65536-5000)/256; //赋值高
- TL0=(65536-5000)%256; //赋值低
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- TR0=1; //启动定时器0
- }
- /****************************中断函数*********************************/
- void t0time()interrupt 1
- {
- TH0=(65536-5000)/256; //重新赋值高位
- TL0=(65536-5000)%256; //重新赋值低位
- t++; //变量加
- if(t==1000) //变量计数到
- {
- t=0; //t重0开始
- t1=!t1; //t1取反给t1
- }
- }
- /**************************显示汉字基本画面*************************************/
- void display1()
- {
- hz_display(0x80+(26-1)*4,1,6); //开
- hz_display(0x80+(27-1)*4,1,7); //心
- hz_display(0x80+(5-1)*4,1,8); //时
- hz_display(0x80+(10-1)*4,1,9); //钟
- hz_display(0x80+(13-1)*4,2,3); //2
- hz_display(0x80+(11-1)*4,2,4); //0
- // hz_display(0x80+(12-1)*4,2,5); //1
- // hz_display(0x80+(16-1)*4,2,6); //5
- hz_display(0x80+(2-1)*4,2,7); //年
- // hz_display(0x80+(12-1)*4,2,8); //1
- // hz_display(0x80+(13-1)*4,2,9); //2
- hz_display(0x80+(3-1)*4,2,10); //月
- // hz_display(0x80+(15-1)*4,2,12); //4
- hz_display(0x80+(4-1)*4,2,13); //日
- hz_display(0x80+(5-1)*4,3,3); //时
- hz_display(0x80+(28-1)*4,3,4); //间
- // hz_display(0x80+(12-1)*4,3,6); //1
- // hz_display(0x80+(17-1)*4,3,7); //6
- hz_display(0x80+(21-1)*4,3,8); //:
- // hz_display(0x80+(13-1)*4,3,9); //2
- // hz_display(0x80+(16-1)*4,3,10); //5
- hz_display(0x80+(6-1)*4,3,11); //分
- hz_display(0x80+(7-1)*4,3,14); //秒
- hz_display(0x80+(22-1)*4,4,2); //祝
- hz_display(0x80+(23-1)*4,4,3); //您
- hz_display(0x80+(5-1)*4,4,4); //时
- hz_display(0x80+(5-1)*4,4,5); //时
- hz_display(0x80+(24-1)*4,4,6); //刻
- hz_display(0x80+(24-1)*4,4,7); //刻
- hz_display(0x80+(6-1)*4,4,8); //分
- hz_display(0x80+(6-1)*4,4,9); //分
- hz_display(0x80+(7-1)*4,4,10); //秒
- hz_display(0x80+(7-1)*4,4,11); //秒
- hz_display(0x80+(25-1)*4,4,12); //都
- hz_display(0x80+(26-1)*4,4,13); //开
- hz_display(0x80+(27-1)*4,4,14); //心
- }
- /**************************INIT************************************************/
- void init()
- {
-
- time();
- rst=0; //拉低液晶屏复位脚
- nop(); //延时
- nop(); //延时
- nop(); //延时
- rst=1; //拉高电平置位
- text_size=graphic_size=30*64; //文本和图形区宽度
- text_startaddr=0x0000; //文本区首地址
- text_startaddr_l=text_startaddr; //文本首地址低位
- text_startaddr_h=text_startaddr>>8; //文本首地址高位
- graphic_startaddr=text_startaddr+text_size; //图形区首地址
- graphic_startaddr_l=graphic_startaddr; //图形区首地址低位
- graphic_startaddr_h=graphic_startaddr>>8; //图形区首地址高位
- double_parameter(text_startaddr_l,text_startaddr_h,0x40); //写入文本首地址
- double_parameter(30,0x00,0x41); //写入文本区长度(一行几个字节)
- double_parameter(graphic_startaddr_l,graphic_startaddr_h,0x42); //写入图形区首地址
- double_parameter(30,0x00,0x43); //写入图形区长度(一行几个字节)
-
- no_parameter(0x80); //文本 或 图形
- no_parameter(0x98); //图形开文本关
- all_display(1,0xff); //表屏全亮
- delay(5000); //延时
- no_parameter(0xa7); //显示8行光标
- no_parameter(0x94); //文本开图形关
- cgram(); //把字模写入显示屏自定义的CGRAM里
- all_display(0,0x00); //把文本区全显示白
-
- }
- /***********123123************写入DS1302年,月,日,时分数据****************************/
- void write1302()
- {
-
- write_ad_dat(0x8e,0x00); //关闭写保护
- write_ad_dat(wds1302_sec,0x80); //暂停
- write_ad_dat(wds1302_year,buf[0]); //写年
- write_ad_dat(wds1302_month,buf[1]); //写月
- write_ad_dat(wds1302_date,buf[2]); //写天
- write_ad_dat(wds1302_hr,buf[3]); //写读小时
- write_ad_dat(wds1302_min,buf[4]); //写分
- write_ad_dat(wds1302_sec,buf[5]); //写秒
- write_ad_dat(ds1302_control,0x80); //开写保护
- }
- /****************************时间调节程序***********************************************/
- void time_tz()
- {
- uint z; // 定义变量
- uchar s,g; // 变量十位,个位,高位,低位
- while(flag) //如果#按下表示要调节
-
- {
- if(next==0) //调节年十位标志
- {
- write_ad_dat(0x8e,0x00); //关闭写保护
- write_ad_dat(wds1302_sec,0x80); //暂停1302
- buf[0]&=0x0f; //清空年十位,变成0000
- buf[0]|=key_scan()<<4; //键盘返回值左移4位变高位或上数组高位
- if(yx)next=1;
- write_ad_dat(wds1302_year,buf[0]); //写年数据
- read1302display(); //读出1302中数据
- hz_display(0x80+0*4,2,5); //年十位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[0]>>4))*4,2,5); //年十位
- yx=0; //标志位有效(就是有按键按下)
- } //清除按键有效标志位
- if(next==1) //调节年个位标志
- {
- buf[0]&=0xf0; //清空年个位,变成0000
- buf[0]|=key_scan(); //键盘返回值或上数组
- if(yx)next=2; //如果如果按键标志位为有效,使调标志到下一调节位
- write_ad_dat(wds1302_year,buf[0]); //写年数据
- read1302display(); //读1302中数据供显示
- hz_display(0x80+0*4,2,6); //年个位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[0]))*4,2,6); //个十位
- yx=0; //清除键盘有效标志位
- }
- if(next==2) //月十位调节标志
- {
- buf[1]&=0x0f; //清空月十位,变成0000
- if((1>=key_scan())&yx) //测试键盘输入数小于等于1和输入有效都为1
- {
- buf[1]|=key<<4; //键盘返回值左移4位变高位或上数组高位
- next=3; //使调节标志位到月个位有效
- }
- write_ad_dat(wds1302_month,buf[1]); //写月
- read1302display(); //读出1302中数据供显示
- hz_display(0x80+0*4,2,8); //月十位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[1]>>4))*4,2,8); //月十位
- yx=0; //清除键盘输入数值有效位
- }
- if(next==3) //月个位调节标志
- {
- buf[1]&=0xf0; //清空月个位,变成0000
- if((2>=key_scan())&yx) //测试输入值小于等于2和输入有效
- {
- buf[1]|=key; //键盘返回值或上数组(给数组赋值)
- next=4; //使调节标志位到小时调节
- }
- write_ad_dat(wds1302_month,buf[1]); //写月
- read1302display(); //读1302数据
- hz_display(0x80+0*4,2,9); //月个位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[1]&0x0f))*4,2,9); //月个位
- yx=0; //清除键盘输入有效位
- }
-
- if(next==4) //日十位调节标志
- {
- buf[2]&=0x0f; //清空日十位,变成0000
- if((3>=key_scan())&yx) //如果输入值小于等于3和键盘输入地为1
- {
- buf[2]|=key<<4; //键盘返回值左移4位变高位或上数组高位
- next=5; //使调节标志位到日个位
- }
- write_ad_dat(wds1302_date,buf[2]); //写日数据
- read1302display(); //读出1302数据
- hz_display(0x80+0*4,2,11); //日十位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[2]>>4))*4,2,11); //日十位
- yx=0; //清除键盘输入有效
- }
-
- if(next==5) //日个位调节标志
- {
- buf[2]&=0xf0; //清空日个位,变成0000
- if((9>=key_scan())&yx) //如果输入值小于等于9和输入有效都为1
- {
- buf[2]|=key; //键盘返回值或上数组
- next=6; //使调节标志为时十位有效
- if(buf[2]>0x31)next=4; //如果输入的日数据大于31天,回到日十位重新输入
- }
- write_ad_dat(wds1302_date,buf[2]); //写日数据
- read1302display(); //读出1302中数据
- hz_display(0x80+0*4,2,12); //日个位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[2]&0x0f))*4,2,12); //日个位
- yx=0; //清除键盘输入有效标志
- }
- if(next==6) //小时调节标志
- {
- buf[3]&=0x0f; //清空时十位,变成0000
- if((2>=key_scan())&yx) //如果输入的值小于等于2,和键盘输入有效
- {
- buf[3]|=key<<4; //键盘返回值左移4位变高位或上数组高位
- next=7; //使调节标志位以小时的个位
- }
- write_ad_dat(wds1302_hr,buf[3]); //写小时数据
- read1302display(); //读1302数据
- hz_display(0x80+0*4,3,6); //时十位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[3]>>4))*4,3,6); //时十位
- yx=0;
- }
-
- if(next==7) //小时个位调节标志
- {
- buf[3]&=0xf0; //清空时个位,变成0000
- if((9>=key_scan())&yx) //输入值和输入有效都为1
- {
- buf[3]|=key; //键盘返回值或上数组
- next=8; //调节标志位到分十位
- if(buf[3]>=0x24)next=6; //如果输入的数值大于24,返回时十位重新输入
- }
- write_ad_dat(wds1302_hr,buf[3]); //写时数据
- read1302display(); //读1302中数据
- hz_display(0x80+0*4,3,7); //时个位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[3]&0x0f))*4,3,7); //时个位
- yx=0; //清除键盘输入有效标志位
- }
- if(next==8) //分十位调节标志
- {
- buf[4]&=0x0f; //清空分十位,变成0000
- if((5>=key_scan())&yx) //输入值小于等于5和键盘输入都有效
- {
- buf[4]|=key<<4; //键盘返回值左移4位变高位或上数组高位
- next=9; //调节标志位到分个位
- }
- write_ad_dat(wds1302_min,buf[4]); //写分数据
- read1302display(); //读1302中数据
- hz_display(0x80+0*4,3,9); //分十位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[4]>>4))*4,3,9); //分十位
- yx=0; //清除键盘输入有效标志位
- }
- if(next==9) //分个位调节标志
- {
- buf[4]&=0xf0; //清空分个位,变成0000
- if((9>=key_scan())&yx) //输入值小于等于9和输入标志都有效
- {
- buf[4]|=key; //键盘返回值或上数组
- next=10; //调节标志位到秒十位
- }
- write_ad_dat(wds1302_min,buf[4]); //写分数据
- read1302display(); //读1302中数据
- hz_display(0x80+0*4,3,10); //分个位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[4]&0x0f))*4,3,10); //分个位
- yx=0; //清除键盘输入有效标志位
- }
- if(next==10) //秒十位调节标志
- {
- buf[5]&=0x0f; //清空秒十位,变成0000
- if((5>=key_scan())&yx) //输入值小于等于5和输入有效都为1
- {
- buf[5]|=key<<4; //键盘返回值左移4位变高位或上数组高位
- next=11; //调节标志位到秒个位
- }
- write_ad_dat(wds1302_sec,buf[5]); //写秒数据
- read1302display(); //读1302中数据
- hz_display(0x80+0*4,3,12); //秒十位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[5]>>4))*4,3,12); //秒十位
- yx=0; //清除键盘输入有效标志位
- }
- if(next==11) //秒个位调节标志
- {
- buf[5]&=0xf0; //清空秒个位,变成0000
- if((9>=key_scan())&yx) //输入值小于等于9和输入有效都为1
- {
- buf[5]|=key; //键盘返回值或上数组
- next=0; //使调节标志位到年十位,为下一次调节做准备
- flag=0; //清除调节模式,回到正常显示状态
- write_ad_dat(ds1302_control,0x80); //开1302写保护
- }
- write_ad_dat(wds1302_sec,buf[5]); //写分数据
- read1302display(); //读出1302中数据
- hz_display(0x80+0*4,3,13); //分个位黑点
- delay(200); //延时
- hz_display(0x80+(11-1+(buf[5]&0x0f))*4,3,13); //分个位
- yx=0; //清除键盘输入有效标志
- }
- }
- }
- /****************123123****读出1302数据并显示**************************************/
- void read1302display()
- { uchar h; //定义变量
- write_ad_dat(0x8e,0x00); //开1302写保护
- buf[0]=read_add_dat(rds1302_year); //读年
- buf[1]=read_add_dat(rds1302_month); //读月
- buf[2]=read_add_dat(rds1302_date); //读日
- buf[3]=read_add_dat(rds1302_hr); //读小时
- buf[4]=read_add_dat(rds1302_min); //读分钟
- buf[5]=read_add_dat(rds1302_sec); //读秒
- hz_display(0x80+(11-1+(buf[0]>>4))*4,2,5); //年十位
- hz_display(0x80+(11-1+(buf[0]&0x0f))*4,2,6); //年个位
- hz_display(0x80+(11-1+(buf[1]>>4))*4,2,8); //月十位
- hz_display(0x80+(11-1+(buf[1]&0x0f))*4,2,9); //月个位
- hz_display(0x80+(11-1+(buf[2]>>4))*4,2,11); //日十位
- hz_display(0x80+(11-1+(buf[2]&0x0f))*4,2,12); //日个位
- hz_display(0x80+(11-1+(buf[3]>>4))*4,3,6); //小时十位
- hz_display(0x80+(11-1+(buf[3]&0x0f))*4,3,7); //小时个位
- hz_display(0x80+(21-1)*4,3,8); //:
- hz_display(0x80+(11-1+(buf[4]>>4))*4,3,9); //分十位
- hz_display(0x80+(11-1+(buf[4]&0x0f))*4,3,10); //分个位
- hz_display(0x80+(11-1+(buf[5]>>4))*4,3,12); //秒十位
- hz_display(0x80+(11-1+(buf[5]&0x0f))*4,3,13); //秒个位
- }
- /***************************主程序*******************************************************/
- void main()
- {
- uchar i; //定义变量
- init(); //初屏显示
- display1(); //显示汉字画面
- for(i=0;i<8;i++) //把原始数据给显示数组
- {
- buf[i]=time_buf1[i]; //常量数组数据赋给变量数组
- }
- write1302(); //写入年,月日时,时间数据
- while(1)
- {
- key_scan(); // 键盘扫描
- time_tz(); // 时间调整
- read1302display(); //读1302数据并显示
- }
- }
复制代码
|