完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
7 个讨论
|
|
付值了呀。温度可以显示变化,帮我看看,我看不出错了 /*头文件*/ //#include #include "STC89.h" #include "eeprom.h" #include #include "uart.h" #define uint unsigned int #define uchar unsigned char #define nop() _nop_() ***it DQ =P3^5; //定义DS18B20通信端口 ***it s1=P2^1; //功能键 ***it s2=P2^3; //增加键 ***it s3=P2^2; //减小键 ***it s4=P2^4; //状态键 ***it beep=P2^0; //蜂鸣器 ***it lcd_rs_port = P1^0; /*定义LCD控制端口*/ ***it lcd_rw_port = P1^1; ***it lcd_en_port = P1^2; #define lcd_data_port P0 ***it led_latch_port = P2^5; /*发光二极管寄存器LE引脚*/ ***it sled_latch_port = P3^6; /*数码管寄存器LE引脚*/ /*****************/ bit flag1,flag,flag_ri;//定义两个位变量 uchar miao,shi,fen,year,month,day,week,amiao=0,afen=59,ashi=23; uchar s1num,flag2,s2num,flag3,t0_num,num,num4,num5;//其它变量定义 uint datt; /******************/ ***it T_CLK = P1^4; /*实时时钟时钟线引脚 */ ***it T_IO = P1^5; /*实时时钟数据线引脚 */ ***it T_RST = P1^6; /*实时时钟复位线引脚 */ //***it ACC0 = ACC^0; //***it ACC7 = ACC^7; uchar code mun_to_char[] = {"0123456789ABCDEF"}; /*定义数字跟ASCII码的关系*/ uchar data time_data_buff[7]={0x00,0x27,0x19,0x14,0x04,0x02,0x15};/*格式为: 秒 分 时 日 月 星期 年 */ uchar data lcd1602_line1[]={" 2000-00-00 000 "}; uchar data lcd1602_line2[]={" 00:00:00 T:00.0"}; uchar code Weeks[][3]={{"SUN"},{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}}; void delay_ms(uint ms) // 延时函数ms毫秒 { uchar i,j; for(i=ms;i>0;i--) for(j=114;j>0;j--); } void delay_us(uint us) // 延时函数ms毫秒 { uchar t; for(t=us;t>0;t--); } /******************************************************************** 函 数 名:RTInputByte() 功 能:实时时钟写入一字节 说 明:往DS1302写入1Byte数据 (内部函数) 入口参数:d 写入的数据 返 回 值:无 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/ void RTInputByte(uchar d) { uchar i; ACC = d; for(i=8; i>0; i--) { T_IO = ACC0; /*相当于汇编中的 RRC */ T_CLK = 1; // delay_us(5); T_CLK = 0; ACC = ACC >> 1; } } /******************************************************************** 函 数 名:RTOutputByte() 功 能:实时时钟读取一字节 说 明:从DS1302读取1Byte数据 (内部函数) 入口参数:无 返 回 值:ACC 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/ uchar RTOutputByte(void) { uchar i; for(i=8; i>0; i--) { ACC = ACC >>1; /*相当于汇编中的 RRC */ ACC7 = T_IO; T_CLK = 1; // delay_us(5); T_CLK = 0; } return(ACC); } /******************************************************************** 函 数 名:W1302() 功 能:往DS1302写入数据 说 明:先写地址,后写命令/数据 (内部函数) 调 用:RTInputByte() , RTOutputByte() 入口参数:ucAddr: DS1302地址, ucData: 要写的数据 返 回 值:无 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/ void W1302(uchar ucAddr, uchar ucDa) { T_RST = 0; T_CLK = 0; T_RST = 1; RTInputByte(ucAddr); /* 地址,命令 */ RTInputByte(ucDa); /* 写1Byte数据*/ T_CLK = 1; T_RST = 0; } /******************************************************************** 函 数 名:R1302() 功 能:读取DS1302某地址的数据 说 明:先写地址,后读命令/数据 (内部函数) 调 用:RTInputByte() , RTOutputByte() 入口参数:ucAddr: DS1302地址 返 回 值:ucData :读取的数据 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/ uchar R1302(uchar ucAddr) { uchar ucData; T_RST = 0; T_CLK = 0; T_RST = 1; RTInputByte(ucAddr); /* 地址,命令 */ ucData = RTOutputByte(); /* 读1Byte数据 */ T_CLK = 1; T_RST = 0; return(ucData); } /******************************************************************** 函 数 名:Set1302() 功 能:设置初始时间 说 明:先写地址,后读命令/数据(寄存器多字节方式) 调 用:W1302() 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 返 回 值:无 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/ void Set1302(uchar *pClock) { uchar i; uchar ucAddr = 0x80; EA = 0; W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/ for(i =7; i>0; i--) { W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ pClock++; ucAddr +=2; delay_ms(5); } W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/ EA = 1; } /******************************************************************** 函 数 名:Get1302() 功 能:读取DS1302当前时间 说 明: 调 用:R1302() 入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 返 回 值:无 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期: ***********************************************************************/ void Get1302(uchar ucCurtime[]) { uchar i; uchar ucAddr = 0x81; EA = 0; for (i=0; i<7; i++) { ucCurtime = R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */ ucAddr += 2; } EA = 1; } //DS18B20延时函数 void delay(unsigned int i) { while(i--); } //DS18B20初始化函数 void Init_DS18B20(void) { 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则初始化失败 delay(20); } //DS18B20读一个字节 uchar ReadOneChar(void) { 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(4); } return(dat); } //DS18B20写一个字节 void WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=8; i>0; i--){ DQ = 0; DQ = dat&0x01; delay(5); DQ = 1; dat>>=1; } } //DS18B20读取温度 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=ReadOneChar(); 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;j<250;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_port&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; delay_ms(5); lcd_en_port = 1; delay_ms(5); lcd_en_port = 0; } void lcd_system_reset() /*LCD1602 初始化*/ { lcd_delay(20); lcd_command_write(0x38); lcd_delay(100); 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(0x0c); lcd_command_write(0x06); lcd_command_write(0x80); // lcd_data_port = 0xff; /*释放数据端口*/ } void lcd_char_write(uchar x_pos,y_pos,lcd_dat) /*LCD1602 字符写入*/ { x_pos &= 0x0f; /* X位置范围 0~15 */ 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; /*释放数据端口*/ } /************************************/ void lcd_write_com(uchar c) //写命令 { lcd_command_write(c); } void lcd_write_date(uchar date) {//写液晶数据函数 lcd_busy_wait(); lcd_rs_port = 1; lcd_rw_port = 0; lcd_en_port = 0; lcd_data_port =date; delay_ms(5); lcd_en_port = 1; delay_ms(5); lcd_en_port = 0; } /*******************************************/ void write_sfm(uchar add,char date) {//1602液晶刷新时分秒函数4为时,7为分,10为秒-1 char shi,ge; shi=date/10; ge=date%10; lcd_write_com(0x80+0x40+add-2); lcd_write_date(0x30+shi); lcd_write_date(0x30+ge); // lcd_char_write(1,add+0x06,shi+0x30); // lcd_char_write(1,add+0x05,ge+0x30); } void write_nyr(uchar add,char date) {//1602液晶刷新年月日函数3为年,6为月,9为日 +1 char shi,ge; shi=date/10; ge=date%10; lcd_write_com(0x80+add); lcd_write_date(0x30+shi); lcd_write_date(0x30+ge); // lcd_char_write(0,add-5,shi+0x30); // lcd_char_write(0,add-4,ge+0x30); } /*******************************************/ void write_week(char we) {//写液晶星期显示函数 lcd_write_com(0x80+12); switch(we) { case 1: lcd_write_date('M');delay_ms(5); lcd_write_date('O');delay_ms(5); lcd_write_date('N'); break; case 2: lcd_write_date('T');delay_ms(5); lcd_write_date('U');delay_ms(5); lcd_write_date('E'); break; case 3: lcd_write_date('W');delay_ms(5); lcd_write_date('E');delay_ms(5); lcd_write_date('D'); break; case 4: lcd_write_date('T');delay_ms(5); lcd_write_date('H');delay_ms(5); lcd_write_date('U'); break; case 5: lcd_write_date('F');delay_ms(5); lcd_write_date('R');delay_ms(5); lcd_write_date('I'); break; case 6: lcd_write_date('S');delay_ms(5); lcd_write_date('A');delay_ms(5); lcd_write_date('T'); break; case 7: lcd_write_date('S');delay_ms(5); lcd_write_date('U');delay_ms(5); lcd_write_date('N'); break; } } /*********************************************/ void di() //蜂鸣器报警声音 { beep=0; delay_ms(100); beep=1; } void keyscan() { if(flag_ri==1) {//这里用来取消闹钟报警,任一键取消报警 if((s1==0)||(s2==0)||(s3==0)||(s4==0)) { delay_ms(5); if((s1==0)||(s2==0)||(s3==0)||(s4==0)) { while(!(s1&&s2&&s3&&s4)); di(); flag_ri=0;//清除报警标志 } } } if(s1==0)//检测S1 { delay_ms(5); if(s1==0) { s1num++;//记录按下次数 if(flag1==1) if(s1num==4) s1num=1; flag=1; while(!s1);di(); switch(s1num) {//光标闪烁点定位 case 1: lcd_write_com(0x80+0x40+8); lcd_write_com(0x0f); if(flag1==0) { send(time_data_buff[6]); send(time_data_buff[4]); send(time_data_buff[3]); send(time_data_buff[5]); send(time_data_buff[2]); send(time_data_buff[1]); datt=(time_data_buff[6]>>4)*10; year=time_data_buff[6]&0x0f; year+=datt; send(datt); send(year); datt=(time_data_buff[4]>>4)*10 ; month=time_data_buff[4]&0x0f; month+=datt; send(datt); send(month); datt=(time_data_buff[3]>>4)*10; day=time_data_buff[3]&0x0f; day+=datt; send(datt); send(day); datt=(time_data_buff[5]>>4)*10; week=time_data_buff[5]&0x0f; week+=datt; send(datt); send(week); datt=(time_data_buff[2]>>4)*10 ; shi=time_data_buff[2]&0x0f; shi+=datt; send(datt); send(shi); datt=(time_data_buff[1]>>4)*10; fen=time_data_buff[1]&0x0f; fen+=datt; send(datt); send(fen); } /*send(year); send(month); send(day); send(week);send(shi); send(fen); */ break; case 2: /*格式为: 秒 分 时 日 月 星期 年 */ lcd_write_com(0x80+0x40+5); break; case 3: lcd_write_com(0x80+0x40+2); break; case 4: lcd_write_com(0x80+14); break; case 5: lcd_write_com(0x80+10); break; case 6: lcd_write_com(0x80+7); break; case 7: lcd_write_com(0x80+4); break; case 8: s1num=0; lcd_write_com(0x0c); flag=0; send(year); send(month); send(day); send(week);send(shi); send(fen); /*格式为: 秒 分 时 日 月 星期 年 */ datt=(year/10)*16; time_data_buff[6]=datt+year%10;//读取12C887数据 datt=(month/10)*16; time_data_buff[4]=datt+month%10; datt=(day/10)*16; time_data_buff[3]=datt+day%10; datt=(week/10)*16; time_data_buff[5]=datt+week%10; datt=(shi/10)*16; time_data_buff[2]=datt+shi%10; datt=(fen/10)*16; time_data_buff[1]=datt+fen%10; // time_data_buff[0]=miao; /* send(time_data_buff[6]); send(time_data_buff[4]); send(time_data_buff[3]); send(time_data_buff[5]);send(time_data_buff[2]); send(time_data_buff[1]);*/ Set1302(time_data_buff); /*设置时间*/ break; } } } if(s1num!=0)//只有当S1按下后,才检测S2和S3 { if(s2==0) { delay_ms(5); if(s2==0) { while(!s2);di(); switch(s1num) {//根据功能键次数调节相应数值 case 1: miao++; if(miao>=60) miao=0; write_sfm(9,miao); lcd_write_com(0x80+0x40+8); break; case 2: fen++; if(fen>=60) fen=0; write_sfm(6,fen); lcd_write_com(0x80+0x40+5); break; case 3: shi++; if(shi>=24) shi=0; write_sfm(3,shi); lcd_write_com(0x80+0x40+2); break; case 4: week++; if(week>=8) week=1; write_week(week); lcd_write_com(0x80+14); break; case 5: day++; if(day>=32) day=1; write_nyr(9,day); lcd_write_com(0x80+10); break; case 6: month++; if(month>=13) month=1; write_nyr(6,month); lcd_write_com(0x80+7); break; case 7: year++; if(year>=100) year=0; write_nyr(3,year); lcd_write_com(0x80+4); break; } } } if(s3==0) { delay_ms(5); if(s3==0) { while(!s3);di(); switch(s1num) {//根据功能键次数调节相应数值 case 1: miao--; if(miao>60) miao=59; write_sfm(9,miao); lcd_write_com(0x80+0x40+8); break; case 2: fen--; if(fen>60) fen=59; write_sfm(6,fen); lcd_write_com(0x80+0x40+5); break; case 3: shi--; if(shi>24) shi=23; write_sfm(3,shi); lcd_write_com(0x80+0x40+2); break; case 4: week--; if(week>7) week=7; write_week(week); lcd_write_com(0x80+14); break; case 5: day--; if(day>32) day=31; write_nyr(9,day); lcd_write_com(0x80+10); break; case 6: month--; if(month>12) month=12; write_nyr(6,month); lcd_write_com(0x80+7); break; case 7: year--; if(year>100) year=99; write_nyr(3,year); lcd_write_com(0x80+4); break; } } } } if(s4==0)//检测S4 { delay_ms(5); if(s4==0) { flag1=~flag1; while(!s4);di(); s1num=0; if(flag1==0) {//退出闹钟设置时保存数值 flag=0; lcd_write_com(0x80+0x40); lcd_write_date(' '); // lcd_write_date(' '); lcd_write_com(0x0c); amiao=miao;//重新赋值用以按键调节 afen=fen; ashi=shi; amiao=miao; EEPROMWrite (ashi,afen,amiao); //write_ds(1,miao); // write_ds(3,fen); // write_ds(5,shi); } else {//进入闹钟设置 // read_alarm();//读取原始数据 miao=amiao;//重新赋值用以按键调节 fen=afen; shi=ashi; // miao=amiao; lcd_write_com(0x0c); lcd_write_com(0x80+0x40); lcd_write_date('R');//显示标志 lcd_write_com(0x80+0x40+2); write_sfm(3,ashi);//送液晶显示闹钟时间 write_sfm(6,afen); write_sfm(9,amiao); } } } } /*****************************************************/ void main() { uchar i; uint temp,temp1; //温度值 lcd_system_reset(); /*LCD1602 初始化*/ lcd_data_port = 0xff; /*释放P0端口*/ init(); // led_latch_port = 0; // sled_latch_port = 0; // Set1302(time_data_buff); /*设置时间*/ send(0x00); send(0x11); send(0x22); send(0x33);send(0x44);send(0x55);send(0x66); // EEPROMWrite (0x5a,0xa5); EEPROMRead (&ashi,&afen,&amiao); send(ashi);send(afen);send(amiao); while(1){ keyscan();//按键扫描 if(flag_ri) { di(); delay_ms(100); di(); delay(500); } if(flag==0&&flag1==0)//正常工作时进入这里 { keyscan();//按键扫描 temp = ReadTemperature(); /*读取当前温度值*/ //temp=228; Get1302(time_data_buff); /*读取当前时间*/ // miao=time_data_buff[0]; /*刷新显示*/ lcd1602_line1[3] = mun_to_char[time_data_buff[6]/0x10]; lcd1602_line1[4] = mun_to_char[time_data_buff[6]%0x10]; /*年*/ lcd1602_line1[6] = mun_to_char[time_data_buff[4]/0x10]; lcd1602_line1[7] = mun_to_char[time_data_buff[4]%0x10]; /*月*/ lcd1602_line1[9] = mun_to_char[time_data_buff[3]/0x10]; lcd1602_line1[10] = mun_to_char[time_data_buff[3]%0x10]; /*日*/ for(i=0;i<3;i++) lcd1602_line1[i+12]=Weeks[time_data_buff[5]&0x07]; /*星期*/ lcd1602_line2[1] = mun_to_char[time_data_buff[2]/0x10]; lcd1602_line2[2] = mun_to_char[time_data_buff[2]%0x10]; /*时*/ lcd1602_line2[4] = mun_to_char[time_data_buff[1]/0x10]; lcd1602_line2[5] = mun_to_char[time_data_buff[1]%0x10]; /*分*/ lcd1602_line2[7] = mun_to_char[time_data_buff[0]/0x10]; lcd1602_line2[8] = mun_to_char[time_data_buff[0]%0x10]; /*秒*/ //------ lcd1602_line2[12] = mun_to_char[temp%1000/100]; lcd1602_line2[13] = mun_to_char[temp%100/10]; lcd1602_line2[15] = mun_to_char[temp%10]; /*温度*/ for(i=12;i<16;i++) lcd_char_write(i,1,lcd1602_line2); //------ for(i=0;i<16;i++) lcd_char_write(i,0,lcd1602_line1); for(i=0;i<16;i++) lcd_char_write(i,1,lcd1602_line2); datt=(time_data_buff[0]>>4)*10;; miao=time_data_buff[0]&0x0f; miao+=datt; if(miao==0) { datt=(time_data_buff[2]>>4)*10 ; shi=time_data_buff[2]&0x0f; shi+=datt; send(datt); send(shi); datt=(time_data_buff[1]>>4)*10; fen=time_data_buff[1]&0x0f; fen+=datt; send(datt); send(fen); if((ashi==shi)&&(afen==fen)) { flag_ri=1; send(ashi);send(shi);send(afen);send(fen); } } } else { temp1 = ReadTemperature(); /*读取当前温度值*/ if(temp1!=temp) { temp=temp1; lcd1602_line2[12] = mun_to_char[temp%1000/100]; lcd1602_line2[13] = mun_to_char[temp%100/10]; lcd1602_line2[15] = mun_to_char[temp%10]; /*温度*/ for(i=12;i<16;i++) lcd_char_write(i,1,lcd1602_line2); if(s1num!=0) switch(s1num) { case 1: /*格式为: 秒 分 时 日 月 星期 年 */ lcd_write_com(0x80+0x40+5); break; case 2: lcd_write_com(0x80+0x40+2); break; case 3: lcd_write_com(0x80+14); break; case 4: lcd_write_com(0x80+10); break; case 5: lcd_write_com(0x80+7); break; case 6: lcd_write_com(0x80+4); break; } } } } } |
|
|
|
|
|
缺少DS1302的时间初始化,也就是第一次用秒数位默认是80,最高位是1,晶振是停止工作的,需要给秒寄存器地址80H,写入一个0x00,就可以了。这是我的初始化程序。 参考一下
void Init_DS1302(void) { Write_DS1302(0x8e,0x00);//写保护位 Write_DS1302(0x80,0x00);//秒 Write_DS1302(0x82,0x00);//分 Write_DS1302(0x84,0x00);//时 Write_DS1302(0x86,0x01);//日 Write_DS1302(0x88,0x01);//月 Write_DS1302(0x8A,0x07);//星期 Write_DS1302(0x8C,0x00);//年 Write_DS1302(0x8e,0x80);//禁止写保护位 } |
|
|
|
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
852 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
592 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
705 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
926 浏览 2 评论
657 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11991 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 19:03 , Processed in 0.618122 second(s), Total 49, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号