液晶屏+ds1302自动显示
单片机源程序如下:
- /*头文件*/
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- /*引脚端口定义*/
- sbit lcd_psb=P3^7;
- sbit LCD12864_RS_PORT=P3^5; /*LCD12864引脚定义*/
- sbit LCD12864_RW_PORT=P3^6;
- sbit LCD12864_E_PORT=P3^4;
- #define LCD12864_DA_PORT P0
- sbit dula=P2^6; //数码管的段选信号
- sbit DQ=P2^2; //定义DS18B20通信端口
- sbit Beep=P2^3; //蜂鸣器通信端口
- sbit T_CLK=P1^7; /*ds1302实时时钟时钟线引脚 */
- sbit T_IO=P2^4; /*ds1302实时时钟数据线引脚 */
- sbit T_RST=P1^6; /*ds1302实时时钟复位线引脚 */
- sbit ACC0=ACC^0; /*ds1302位寻址寄存器*/
- sbit ACC7=ACC^7;
-
- uchar code num_to_char[]={"0123456789"};/*数字转换为ASCII字符码*/
- uchar code Week1_to_char[]={"一"};
- uchar code Week2_to_char[]={"二"};
- uchar code Week3_to_char[]={"三"};
- uchar code Week4_to_char[]={"四"};
- uchar code Week5_to_char[]={"五"};
- uchar code Week6_to_char[]={"六"}; /*星期数字转换为汉字的ASCII码*/
- uchar code Week7_to_char[]={"日"};
- uchar hanzi_buff1[]={" 年 月 日 "};//0-15
- uchar hanzi_buff2[]={" 星期 "};
- uchar hanzi_buff3[]={" : : "};
- uchar hanzi_buff4[]={"当前温度: . 度"};
- uchar data time_data_buff[7]={0x00,0x00,0x12,0x01,0x12,0x06,0x17};/*格式为: 秒 分 时 日 月 星期 年 */
- /*1MS为单位的延时程序*/
- void delay_1ms(uchar x)
- {
- uchar j;
- while(x--){
- for(j=0;j<125;j++)
- {;}
- }
- }
- void beep()
- {
- Beep=0;
- delay_1ms(2000);
- Beep=1;
- }
- ////////////////////以下是时钟读取程序/////////////////
- /********************************************************************
- 函 数 名:InputByte()
- 功 能:实时时钟写入一字节
- 说 明:往DS1302写入1Byte数据 (内部函数)
- 入口参数:d 写入的数据
- 返 回 值:无
- ***********************************************************************/
- void InputByte(uchar d)
- {
- uchar i;
- ACC=d;
- for(i=8;i>0;i--)
- {
- T_IO=ACC0; /*相当于汇编中的 RRC */
- T_CLK=1;
- T_CLK=0;
- ACC=ACC>>1;
- }
- }
- /********************************************************************
- 函 数 名:OutputByte()
- 功 能:实时时钟读取一字节
- 说 明:从DS1302读取1Byte数据 (内部函数)
- 入口参数:无
- 返 回 值:ACC
- ***********************************************************************/
- uchar OutputByte()
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- ACC=ACC>>1; /*相当于汇编中的 RRC */
- ACC7=T_IO;
- T_CLK=1;
- T_CLK=0;
- }
- return(ACC);
- }
- /********************************************************************
- 函 数 名:W1302()
- 功 能:往DS1302写入数据
- 说 明:先写地址,后写命令/数据 (内部函数)
- 调 用:RTInputByte() , RTOutputByte()
- 入口参数:ucAddr: DS1302地址, ucData: 要写的数据
- 返 回 值:无
- ***********************************************************************/
- void W1302(uchar ucAddr, uchar ucDa)//先写命令字,再写数据
- {
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- InputByte(ucAddr); /* 地址,命令 */
- InputByte(ucDa); /* 写1Byte数据*/
- T_CLK=1;
- T_RST=0;
- }
- /********************************************************************
- 函 数 名:Set1302()
- 功 能:设置初始时间
- 说 明:先写地址,后读命令/数据(寄存器多字节方式)
- 调 用:W1302()
- 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
- 7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
- 返 回 值:无
- ***********************************************************************/
- void Set1302(uchar *pClock) //指针指向time_data_buff数组
- {
- uchar i;
- uchar ucAddr=0x80;
- //EA=0;
- W1302(0x8e,0x00);/*对写保护寄存器操作,0x8e写保护寄存器写命令字,0x00使该寄存器最高位WP=0时间日历寄存器可进行写操作*/
- //W1302(0x90,0xa6);
- for(i=7;i>0;i--)
- {
- W1302(ucAddr,*pClock); //秒 分 时 日 月 星期 年 ucAddr先为0x80,此地址为秒寄存器写控制命令字
- pClock++;
- ucAddr+=2; //每次加2分别进入分、时、日。。。年写命令字
- }
- W1302(0x8e,0x80); /* 控制命令,WP=1,写保护,此后时钟寄存器不断变化*/
- //EA = 1;
- }
- /********************************************************************
- 函 数 名:R1302()
- 功 能:读取DS1302某地址的数据
- 说 明:先写地址,后读命令/数据 (内部函数)
- 调 用:RTInputByte() , RTOutputByte()
- 入口参数:ucAddr: DS1302地址
- 返 回 值:ucData :读取的数据
- ***********************************************************************/
- uchar R1302(uchar ucAddr)//先写命令字,再读数据
- {
- uchar ucData;
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- InputByte(ucAddr); /* 地址,命令 */
- ucData=OutputByte(); /* 读1Byte数据 */
- T_CLK=1;
- T_RST=0;
- return(ucData);
- }
- /********************************************************************
- 函 数 名:Now1302()
- 功 能:读取DS1302当前时间
- 说 明:
- 调 用:R1302()
- 入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
- 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
- 返 回 值:无
- ***********************************************************************/
- void Now1302(uchar ucCurtime[])
- {
- uchar i;
- uchar ucAddr=0x81;
- //EA=0;
- for (i=0;i<7;i++)
- {
- ucCurtime[i]=R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
- ucAddr+=2;
- }
- //EA=1;//考虑保持总中断开启
- }
- void delay(uint i)
- {
- while(i--);
- }
- //////////////////以下是DS18B20驱动程序////////////////
- void Init_DS18B20()//初始化函数
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- delay(8); //稍做延时
- DQ = 0; //单片机将DQ拉低
- delay(80); //精确延时 大于 480us
- DQ = 1; //拉高总线
- delay(14);
- x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
- DQ=1;
- }
- uchar ReadOneChar()//读一个字节
- {
- uchar i;
- uchar dat=0;
- for(i=8;i>0;i--)
- {
- DQ=0; // 给脉冲信号
- dat>>=1;
- DQ=1; // 给脉冲信号
- if(DQ)
- dat|=0x80; //利用0x80将温度数据赋给dat
- delay(4);
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)//写一个字节
- {
- uchar i=0;
- for (i=8;i>0;i--){
- DQ=0;
- DQ=dat&0x01;
- delay(5);
- DQ=1;
- dat>>=1;
- }
- }
- uint ReadTemperature()//读取温度,注意返回值为16bit
- {
- uchar a=0;
- uchar b=0;
- uint t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳过读序号列号的操作
- WriteOneChar(0x44); // 启动温度转换
- Init_DS18B20();
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- a=ReadOneChar();
- b=ReadOneChar();
- t=b;
- t<<=8;
- t=t|a; //将温度的高位与低位合并
- tt=t*0.0625;
- t=tt*10+0.5; //对结果进行4舍5入
- return(t);
- }
- //////////////////以下是LCD12864驱动程序////////////////
- void LCD12864_WaitIdle()
- //LCD12864 忙 信号检测
- {
- LCD12864_DA_PORT = 0xff;
- LCD12864_RS_PORT = 0;
- LCD12864_RW_PORT = 1;
- LCD12864_E_PORT = 1;
- while((LCD12864_DA_PORT&0x80)==1); /*等待BF 不为1*/
- LCD12864_E_PORT = 0;
- }
- void LCD12864_COM_Write( uchar com_da) /* 检测忙信号写入命令字 com_da 为待写入的命令字*/
- {
- LCD12864_WaitIdle();
- LCD12864_RS_PORT = 0;
- LCD12864_RW_PORT = 0;
- LCD12864_DA_PORT = com_da;
- LCD12864_E_PORT = 1;
- delay_1ms(1);
- LCD12864_E_PORT = 0;
- }
- void LCD12864_NoWaitIdle_COM_Write(uchar com) /*不检测忙信号写入命令字,com_da 为待写入的命令字*/
- {
- LCD12864_RS_PORT=0; //0写命令
- LCD12864_RW_PORT=0;
- LCD12864_E_PORT=0;
- LCD12864_DA_PORT=com;
- delay_1ms(1);
- LCD12864_E_PORT=1;
- delay_1ms(1);
- LCD12864_E_PORT=0;
- }
- void LCD12864_Data_Write(uchar da) /*数据写入 da为待写入8位数据*/
- {
- LCD12864_WaitIdle(); /*检测忙信号*/
- LCD12864_RS_PORT = 1; //写数据
- LCD12864_RW_PORT = 0;
- LCD12864_DA_PORT = da;
- LCD12864_E_PORT = 1;
- delay_1ms(1);
- LCD12864_E_PORT = 0;
- }
- void LCD12864_init() /*LCD12864初始化*/
- {
- lcd_psb=1;
- LCD12864_NoWaitIdle_COM_Write(0x30); /*基本指令操作*/
- delay_1ms(10);
- LCD12864_NoWaitIdle_COM_Write(0x0c); /*显示开及光标设置*/
- delay_1ms(10);
- LCD12864_NoWaitIdle_COM_Write(0x01); /*显示清屏*/
- delay_1ms(10);
- LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址计数器(AC)加1*/
- delay_1ms(10);
- }
- void LCD12864_HAIZI_WRITE(uchar x,uchar y,uchar daH,uchar daL) //汉字16bit写入 x写入的X位置 y写入的Y位置 daH写入汉字高八位 daL写入汉字低八位
- {
- uchar xy;
- if((x>=8)||(y>=4)) return; /*X位置超出显示范围退出*/
- if(y==0) xy=0x80+x;
- else if(y==1) xy=0x90+x; /*计算转换地址*/
- else if(y==2) xy=0x88+x;
- else if(y==3) xy=0x98+x;
- LCD12864_COM_Write(xy); /*写地址*/
- delay_1ms(1);
- LCD12864_Data_Write(daH); /*写高八位数据*/
- delay_1ms(1);
- LCD12864_Data_Write(daL); /*写低八位数据*/
- delay_1ms(1);
- }
- //键盘扫描函数,低电位按下
- /*void keyscan()
- {
- int s1num;
- rd=0;
- if(key1==0)
- {
- delay_1ms(5);
- if(key1==0)
- {
- Set1302(time_data_buff);
- W1302(0x8e,0x00);
- W1302(0x80,0x80);
- W1302(0x8e,0x80);
- s1num++;
- while(!key1);
- if(s1num==1)
- {
- //LCD12864_COM_Write(0x81);年
- if(key2==0)
- {
- delay_1ms(5);
- if(key2==0)
- {
- while(!key2);
- time_data_buff[6]++;
- }
- }
- }
- /*if(s1num==2)
- {
- LCD12864_COM_Write(0x83);//月
- }
- if(s1num==3)
- {
- LCD12864_COM_Write(0x85);//日
- }
- if(s1num==4)
- {
- LCD12864_COM_Write(0x8a);//时
- }
- if(s1num==5)
- {
- LCD12864_COM_Write(0x88+)/////////////////
- }
- if(s1num==6)
- {
- LCD12864_COM_Write(0x8d);//秒
- }*/
- /* if(s1num==2)
- {
- s1num=0;
- W1302(0x8e,0x00);
- W1302(0x80,0x00);
- W1302(0x8e,0x80);
- }
- //W1302(0x80,此处应为修改的秒值);
-
- }
- }
- }
- */
- void main()//主函数
- {
- uchar i;
- uint temp_buff;
- P0=0x00;//关掉数码管位选信号。阻止数码管受到P0口信号的影响。
- dula=1;
- delay_1ms(1);
- dula=0;
- delay_1ms(1);
-
- LCD12864_init(); /*LCD初始化*/
- LCD12864_DA_PORT = 0xff; /*释放P0端口*/
-
- Set1302(time_data_buff);
- while(1){
-
- // keyscan();
-
- Now1302(time_data_buff);
- hanzi_buff1[2] = num_to_char[time_data_buff[6]/0x10];
- hanzi_buff1[3] = num_to_char[time_data_buff[6]%0x10]; /*年*/
- hanzi_buff1[6] = num_to_char[time_data_buff[4]/0x10];
- hanzi_buff1[7] = num_to_char[time_data_buff[4]%0x10]; /*月*/
- hanzi_buff1[10] = num_to_char[time_data_buff[3]/0x10];
- hanzi_buff1[11] = num_to_char[time_data_buff[3]%0x10]; /*日*/
- hanzi_buff3[4] = num_to_char[time_data_buff[2]/0x10];
- hanzi_buff3[5] = num_to_char[time_data_buff[2]%0x10]; /*时*/
- hanzi_buff3[7] = num_to_char[time_data_buff[1]/0x10];
- hanzi_buff3[8] = num_to_char[time_data_buff[1]%0x10]; /*分*/
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
test_2_3.zip
(40.99 KB, 下载次数: 28)
|