1、时钟可调+温度+LCD1602显示/* 河南工业大学电气工程学院 测控1001刘欣 如有错误欢迎致电hellohaut共同学习 共同进步*/* 程序名称: LCD1602显示时间 显示当前温度 */* | 0 | 1 | 2 | 3 | | - | 4 | 5 | 6 | 7 | | - | 8 | 9 | U | E | | - | S | | | 按键说明: 0-9为数字0-9输入 S为 设置时间键,初次按下为设置时间,第二次按下为退出时间,时间不保存 E为 时间保存键,按下后时间执行当前时间 键为可以调节设置的状态 U 或 D 键为数据加1或减1*/*头文件*/#include #inc
2、lude #define uint unsigned int#define uchar unsigned char#define nop() _nop_()sbit system_led_port = P30;#define scan_key_port P1 /*定义矩阵按键端口*/sbit DQ =P36; /定义DS18B20通信端口sbit lcd_rs_port = P27; /*定义LCD控制端口*/sbit lcd_rw_port = P26; /*定义LCD控制端口*/sbit lcd_en_port = P25; /*定义LCD控制端口*/#define lcd_data_po
3、rt P0 /*定义LCD控制端口*/sbit T_CLK = P12; /*实时时钟时钟线引脚 */sbit T_IO = P13; /*实时时钟数据线引脚 */sbit T_RST = P35; /*实时时钟复位线引脚 */sbit ACC0 = ACC0;sbit ACC7 = ACC7;uchar code mun_to_char = 0123456789ABCDEF; /*定义数字跟ASCII码的关系*/uchar data time_data_buff7;/*格式为: 秒 分 时 日 月 星期 年 */uchar time_temp13; /*格式为: 年 月 日 星期 时 分 秒
4、*/uchar code time_reset_buff7=0x00,0x00,0x09,0x01,0x01,0x04,0x09;/*格式为: 秒 分 时 日 月 星期 年 */uchar data lcd1602_line1= 2000/00/00 000 ;uchar data lcd1602_line2= 00:00:00 00.0C;uchar code Weeks3=SUN,MON,TUE,WED,THU,FRI,SAT,SUN;uchar data menu_bit=0; /*时间设置位 0退出设置时间 1十年 2年 3十月 4月 5十日 6日 7星期 8十时 9时 10十分 11
5、分 12十秒 13秒*/uchar data menu_count=0,menu_lighten_bit=0;uint temp; /*温度值*/uchar data system_count=0;/*定义按键对应的按键值*/#define mun0_key 0x18#define mun1_key 0x28#define mun2_key 0x48#define mun3_key 0x88#define mun4_key 0x14#define mun5_key 0x24#define mun6_key 0x44#define mun7_key 0x84#define mun8_key 0x
6、12#define mun9_key 0x22#define up_key 0x42#define enter_key 0x82#define set_time_key 0x11#define left_key 0x21#define down_key 0x41#define right_key 0x81uchar code month_table=0,31,28,31,30,31,30,31,31,30,31,30,31; /*一年12月对应的天数*/* 函 数 名:W1302() 功 能:往DS1302写入数据 说 明:先写地址,后写命令/数据 (内部函数) 入口参数:ucAddr: DS
7、1302地址, ucData: 要写的数据 返 回 值:无*/void W1302(uchar ucAddr, uchar ucDa) uchar i; /写地址 T_RST=0; T_CLK=0;/增加 T_RST=1; ACC=ucAddr; for(i=8;i0;i-) /修改了 T_IO=ACC0; /修改了,这里不能用ACC0,要在前面定义 T_CLK=1; T_CLK=0; ACC=ACC1; /写数据 ACC=ucDa; for(i=8;i0;i-) /修改了 T_IO=ACC0; /修改了,这里不能用ACC0,要在前面定义 T_CLK=1; T_CLK=0; ACC=ACC1;
8、 T_CLK=1; T_RST=0; /* 函 数 名:R1302() 功 能:读取DS1302某地址的数据 说 明:先写地址,后读命令/数据 (内部函数) 入口参数:ucAddr: DS1302地址 返 回 值:ACC: 读取的数据*/uchar R1302(uchar ucAddr) uchar i; ACC=ucAddr; T_RST=0; T_CLK=0; T_RST=1; for(i=8;i0;i-) /修改了 T_IO=ACC0; /修改了,这里不能用ACC0,要在前面定义 T_CLK=1; T_CLK=0; ACC=ACC1; for(i=8;i0;i-) /修改了 ACC=AC
9、C1; ACC7=T_IO; T_CLK=1; T_CLK=0; /修改了 T_CLK=1; T_RST=0; return(ACC);/* 函 数 名:Set1302() 功 能:设置初始时间 说 明:先写地址,后读命令/数据(寄存器多字节方式) 调 用:W1302() 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 返 回 值:无*/void Set1302(uchar *pClock) uchar i; uchar ucAddr = 0x80; EA = 0; W1302(0x8e,0x
10、00); /* 控制命令,WP=0,写操作?*/ for(i =7; i0; i-) W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ pClock+; ucAddr +=2; W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/ EA = 1;/* 函 数 名:Get1302() 功 能:读取DS1302当前时间 说 明: 调 用:R1302() 入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 返 回 值:无*/vo
11、id Get1302(uchar ucCurtime) uchar i; uchar ucAddr = 0x81; EA = 0; for (i=0; i0;i-) DQ = 0; / 给脉冲信号 dat=1; DQ = 1; / 给脉冲信号 if(DQ) dat|=0x80; delay(4); return(dat);/DS18B20写一个字节void WriteOneChar(unsigned char dat) unsigned char i=0; for (i=8; i0; i-) DQ = 0; DQ = dat&0x01; delay(5); DQ = 1; dat=1; /DS
12、18B20读取温度uint ReadTemperature(void) unsigned char a=0; unsigned char b=0; unsigned int t=0; float tt=0; Init_DS18B20(); WriteOneChar(0xCC); / 跳过读序号列号的操作 WriteOneChar(0x44); / 启动温度转换 Init_DS18B20(); WriteOneChar(0xCC); /跳过读序号列号的操作 WriteOneChar(0xBE); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度 a=ReadOneChar(); b=Rea
13、dOneChar(); t=b; t=8; t=t|a; tt=t*0.0625; /将温度的高位与低位合并 t= tt*10+0.5; /对结果进行4舍5入 return(t);/-void lcd_delay(uchar ms) /*LCD1602 延时*/ uchar j; while(ms-) for(j=0;j250;j+) ; void lcd_busy_wait() /*LCD1602 忙等待*/ lcd_rs_port = 0; lcd_rw_port = 1; lcd_en_port = 1; lcd_data_port = 0xff; while (lcd_data_por
14、t&0x80); lcd_en_port = 0; void lcd_command_write(uchar command) /*LCD1602 命令字写入*/ lcd_busy_wait(); lcd_rs_port = 0; lcd_rw_port = 0; lcd_en_port = 0; lcd_data_port = command; lcd_en_port = 1; lcd_en_port = 0; void lcd_system_reset() /*LCD1602 初始化*/ lcd_delay(20); lcd_command_write(0x38); lcd_delay(1
15、00); lcd_command_write(0x38); lcd_delay(50); lcd_command_write(0x38); lcd_delay(10); lcd_command_write(0x08); lcd_command_write(0x01); lcd_command_write(0x06); lcd_command_write(0x0c); lcd_data_port = 0xff; /*释放数据端口*/void lcd_char_write(uchar x_pos,y_pos,lcd_dat) /*LCD1602 字符写入*/ x_pos &= 0x0f; /* X
16、位置范围 015 */ y_pos &= 0x01; /* Y位置范围 0 1 */ if(y_pos=1) x_pos += 0x40; x_pos += 0x80; lcd_command_write(x_pos); lcd_busy_wait(); lcd_rs_port = 1; lcd_rw_port = 0; lcd_en_port = 0; lcd_data_port = lcd_dat; lcd_en_port = 1; lcd_en_port = 0; lcd_data_port = 0xff; /*释放数据端口*/*1MS为单位的延时程序*/void delay_1ms(u
17、char x) uchar j; while(x-) for(j=0;j125;j+) ; uchar key_scan() uchar sccode,recode; scan_key_port=0xf0; /* 发全 0 的行扫描码,列线输入 */ if(scan_key_port&0xf0)!=0xf0) /* 若有键按下 */ delay_1ms(2); /*延时去抖动*/ if(scan_key_port&0xf0)!=0xf0) /* 若有键按下 */ sccode=0xfe; /*逐行扫描初值*/ while(sccode&0x10)!=0) scan_key_port=sccod
18、e; /* 输出行扫描码 */ if(scan_key_port&0xf0)!=0xf0) /* 本行有键按下 */ recode=(scan_key_port&0xf0)|0x0f; scan_key_port=0xf0; /while(scan_key_port&0xf0)!=0xf0); scan_key_port = 0xff; /*释放按键扫描端口*/ return(sccode)+(recode);/* 返回特征码 */ else sccode=(sccode1)|0x01; /* 行扫描左移一位 */ scan_key_port = 0xff; /*释放按键扫描端口*/ retu
19、rn(0); /* 无键按下,返回值为0 */void MENU_Disp() interrupt 1 using 3 uchar i,k; TH0 = (65536-50000)/256; TL0 = (65536-50000)/256; k = scan_key_port; /*将按键端口当前状态保存*/ scan_key_port = 0xff; /*释放按键端口,避免跟LCD显示有冲突*/ /*刷新显示*/ lcd1602_line13 = mun_to_chartime_temp0/10; lcd1602_line14 = mun_to_chartime_temp0%10; /*年*
20、/ lcd1602_line16 = mun_to_chartime_temp1/10; lcd1602_line17 = mun_to_chartime_temp1%10; /*月*/ lcd1602_line19 = mun_to_chartime_temp2/10; lcd1602_line110 = mun_to_chartime_temp2%10; /*日*/ for(i=0;i3;i+) lcd1602_line1i+12=Weekstime_temp3i; /*星期*/ lcd1602_line22 = mun_to_chartime_temp4/10; lcd1602_line
21、23 = mun_to_chartime_temp4%10; /*时*/ lcd1602_line25 = mun_to_chartime_temp5/10; lcd1602_line26 = mun_to_chartime_temp5%10; /*分*/ lcd1602_line28 = mun_to_chartime_temp6/10; lcd1602_line29 = mun_to_chartime_temp6%10; /*秒*/ /- lcd1602_line211 = mun_to_chartemp/100; lcd1602_line212 = mun_to_chartemp%100
22、/10; lcd1602_line214 = mun_to_chartemp%10; /*温度*/ /-根据情况是否要闪烁显示设置的时间- if(menu_lighten_bit = 1) /*闪烁显示*/ switch (menu_bit) case 1: lcd1602_line13 = _;break; /*年*/ case 2: lcd1602_line14 = _;break; case 3: lcd1602_line16 = _;break; /*月*/ case 4: lcd1602_line17 = _;break; case 5: lcd1602_line19 = _;bre
23、ak; /*日*/ case 6: lcd1602_line110= _;break; case 7: lcd1602_line112= ;lcd1602_line113=mun_to_chartime_temp3;lcd1602_line114= ;break; case 8: lcd1602_line22 = _;break; /*时*/ case 9: lcd1602_line23 = _;break; case 10: lcd1602_line25 = _;break; /*分*/ case 11: lcd1602_line26 = _;break; case 12: lcd1602_line28 = _;break; /*秒*/ case 13: lcd1602_line29 = _;break; for(i=0;i16;i+) lcd_char_write(i,0,lcd1602_line1i); for(i=0;i16;i+) lcd_char_write(i,1,lcd1602_line2i); menu_
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1