完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本人尝试将DHT11温湿度程序和ds1302时钟程序合并,实现两种功能 (程序分别运行是可行的,如后面图片) 合并后就出现图片的问题,什么都不显示。 请大神不吝赐教,谢谢。 这是我的代码: //DHT11.C文件 #include #include #define uint unsigned int #define uchar unsigned char /* 时钟 */ ***it key0 = P3^4;//功能键 ***it key1 = P3^6;//增大键 ***it key2 = P3^7;//减小键 ***it RST = P1^7; ***it SCLK = P1^5; ***it SDA = P1^6; ***it LCD_RS = P2^5; ***it RW = P2^6; ***it LCD_E = P2^7; #define DS1302_SECOND_WRITE 0x80 #define DS1302_MINUTE_WRITE 0x82 #define DS1302_HOUR_WRITE 0x84 #define DS1302_DAY_WRITE 0x86 #define DS1302_MON_WRITE 0x88 #define DS1302_YEAR_WRITE 0x8c #define DS1302_WEEK_WRITE 0x8a #define DS1302_CURRENT_WRITE 0x90 #define DS1302_SECOND_READ 0x81 #define DS1302_MINUTE_READ 0x83 #define DS1302_HOUR_READ 0x85 #define DS1302_DAY_READ 0x87 #define DS1302_MON_READ 0x89 #define DS1302_YEAR_READ 0x8d #define DS1302_WEEK_READ 0x8B #define WRITE_PROTECT 0x8e uchar sec,min,hour,day,mon,year,week,num,flag; unsigned char table[]="20 - - "; unsigned char table1[]=" : : "; /*****************************/ void Delay_us(unsigned char n); void write_cmd(uchar com) //写指令 { LCD_RS=0; RW=0; P0=com; Delay_us(5); LCD_E=1; Delay_us(5); LCD_E=0; } /********************/ void write_data(uchar dat) //写数据 { LCD_RS=1; RW=0; P0=dat; Delay_us(5); LCD_E=1; Delay_us(5); LCD_E=0; } /****************/ void write_sf(uchar add,uchar date) //时分秒函数,前一个是定义位置,后一个则是分离数据 { uchar ge,shi; shi=date/10; ge=date%10; write_cmd(0x80+add); //设置显示的位置 // Delay_us(10); write_data(0x30+shi); //给十位送数据 // Delay_us(10); write_data(0x30+ge); //给个位送数据 } /**********************************/ void lcd_write_week(uchar week)//写液晶星期显示函数 { write_cmd(0x80+11);//设置显示位置 switch(week) { case 1: write_data('M');Delay_us(5); write_data('O');Delay_us(5); write_data('N');break; case 2: write_data('T');Delay_us(5); write_data('U');Delay_us(5); write_data('E');break; case 3: write_data('W');Delay_us(5); write_data('E');Delay_us(5); write_data('D');break; case 4: write_data('T');Delay_us(5); write_data('H');Delay_us(5); write_data('U');break; case 5: write_data('F');Delay_us(5); write_data('R');Delay_us(5); write_data('I');break; case 6: write_data('S');Delay_us(5); write_data('A');Delay_us(5); write_data('T');break; case 7: write_data('S');Delay_us(5); write_data('U');Delay_us(5); write_data('N');break; } } /*************************/ void init() //1602初始化 { uchar i; LCD_E=0; write_cmd(0x38); //显示模式设置 write_cmd(0x0c); //开显示,光标不闪烁 write_cmd(0x06); // write_cmd(0x01); write_cmd(0x80); for(i=0;i<14;i++) { write_data(table); Delay_us(10); } write_cmd(0xc0); for(i=0;i<12;i++) { write_data(table1); Delay_us(10); //1602位置的初始化 } // while(1); } //以上便是液晶1602的初始化 /***********************************/ uchar DS1302ReadByte() //读一个字节 { uchar i,dat; Delay_us(2); for(i=0;i<8;i++) { dat>>=1;//要返回的数据左移一位 if(SDA==1)//当数据线为高时,证明该位数据为1 dat|=0x80;//要传输数据的当前值置为1,若不是,则为0 SCLK=1;//拉高时钟线 Delay_us(2); SCLK=0;//制造下降沿 Delay_us(2); } return dat;//返回读取出的数据 } /************************************************/ void DS1302WriteByte(uchar dat) //写一个字节 { uchar i; SCLK=0;//初始时钟线置为0 Delay_us(2); for(i=0;i<8;i++)//开始传输8个字节的数据 { SDA=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的 Delay_us(2); SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输 Delay_us(2); SCLK=0;//时钟线拉低,为下一个上升沿做准备 dat>>=1;//数据右移一位,准备传输下一位数据 } } /********************************/ uchar DS1302Read(uchar cmd) //读命令 { uchar dat; RST=0;//初始CE线置为0 SCLK=0;//初始时钟线置为0 RST=1;//初始CE置为1,传输开始 DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址 dat=DS1302ReadByte();//读取要得到的时间/日期 Delay_us(4); SCLK=1;//时钟线拉高 RST=0;//读取结束,CE置为0,结束数据的传输 dat = dat/16*10+dat%16; //分离十位和个位,将十六进制数转化为十进制数 return dat;//返回得到的时间/日期 } /*********** */ void DS1302Write(uchar cmd, uchar dat) //往1302中写数据 { RST=0; //初始CE线置为0 SCLK=0; //初始时钟线置为0 RST=1; //初始CE置为1,传输开始 DS1302WriteByte(cmd); //传输命令字,要写入的时间/日历地址 DS1302WriteByte(dat); //写入要修改的时间/日期 SCLK=1; //时钟线拉高 RST=0; //读取结束,CE置为0,结束数据的传输 } /***********************************/ void Init_DS1302() //1302初始化 { DS1302Write(0x8e,0x00);//写保护关 DS1302Write(0x8e,0x80); } /***************************/ void display() //主要是显示程序,从DS1302中读取数值 { day=DS1302Read(DS1302_DAY_READ); mon=DS1302Read(DS1302_MON_READ); year=DS1302Read(DS1302_YEAR_READ); week=DS1302Read(DS1302_WEEK_READ); sec=DS1302Read(DS1302_SECOND_READ); min=DS1302Read(DS1302_MINUTE_READ); hour=DS1302Read(DS1302_HOUR_READ); write_sf(8,day); write_sf(5,mon); write_sf(2,year); lcd_write_week(week); write_sf(0x40+4,hour); write_sf(0x40+7,min); write_sf(0x40+10,sec); } /***********************************/ void keyscan() //键盘扫描 { if(key0==0)//确认功能键按下 { Delay_us(20); if(key0==0)//功能键确实按下 { while(!key0);//释放 num++;//按下次数记录 switch(num) { case 1: flag=1;//修改时间,液晶禁止从DS1302读数据 write_cmd(0x0f);//光标开始闪烁 write_cmd(0x80+2);//第一次按下,光标定位到年位置 break; case 2: write_cmd(0x80+5);//第二次按下,光标定位到月位置 break; case 3: write_cmd(0x80+8);//第三次按下,光标定位到日位置 break; case 4: write_cmd(0x80+11);//第四次按下,光标定位到星期位置 break; case 5: write_cmd(0x80+0x40+4);//第五次按下,光标定位到时位置 break; case 6: write_cmd(0x80+0x40+7);//第六次按下,光标定位到分位置 break; case 7: write_cmd(0x80+0x40+10);//第七次按下,光标定位到秒位置 break; case 8: num=0;//第八次按下,记录清零 write_cmd(0x0c);//不显示光标 DS1302Write(WRITE_PROTECT,0x00);//禁止写保护 DS1302Write(0x80,(sec/10*16)+sec%10);//将调节后的秒写入DS1302 DS1302Write(0x82,(min/10*16)+min%10);//将调节后的分写入DS1302 DS1302Write(0x84,(hour/10*16)+hour%10);//将调节后的时写入DS1302 DS1302Write(0x8a,(week/10*16)+week%10);//将调节后的星期写入DS1302 DS1302Write(0x86,(day/10*16)+day%10);//将调节后的日写入DS1302 DS1302Write(0x88,(mon/10*16)+mon%10);//将调节后的月写入DS1302 DS1302Write(0x8c,(year/10*16)+year%10);//将调节后的年写入DS1302 DS1302Write(WRITE_PROTECT,0x80);//开写保护 flag=0;//时间修改完毕,允许液晶从DS1302读数据 break; } } } if(num!=0) { if(key1==0)//确认增大键按下 { Delay_us(20); if(key1==0)//增大键确实按下 { while(!key1); switch(num) { case 1: year++;//调节年 if(year==100)year=0; write_sf(2,year);//将调节后的年送入液晶显示 write_cmd(0x80+2);//光标回到指定处 break; case 2: mon++;//调节月 if(mon==13)mon=1; write_sf(5,mon);//将调节后的月送入液晶显示 write_cmd(0x80+5);//光标回到指定处 break; case 3: day++;//调节日 if(day==32)day=1; write_sf(8,day);//将调节后的日送入液晶显示 write_cmd(0x80+8);//光标回到指定处 break; case 4: week++; if(week==8)week=1; lcd_write_week(week);//将调节后的星期送入液晶显示 write_cmd(0x80+11);//光标回到指定处 break; case 5: hour++; if(hour==24)hour=0; write_sf(0x40+4,hour);//将调节后的小时送入液晶显示 write_cmd(0x80+0x40+4);//光标回到指定处 break; case 6: min++; if(min==60)min=0; write_sf(0x40+7,min);//将调节后的分送入液晶显示 write_cmd(0x80+0x40+7);//光标回到指定处 break; case 7: sec++; if(sec==60)sec=0; write_sf(0x40+10,sec);//将调节后的秒送入液晶显示 write_cmd(0x80+0x40+10);//光标回到指定处 break; default: break; } } } if(key2==0)//确认减小键按下 { Delay_us(10); if(key2==0)//减小键确实按下 { while(!key2); switch(num) { case 1: year--;//调节年 if(year==-1)year=99; write_sf(2,year); write_cmd(0x80+2); break; case 2: mon--;//调节月 if(mon==0)mon=12; write_sf(5,mon); write_cmd(0x80+5); break; case 3: day--;//调节日 if(day==0)day=31; write_sf(8,day); write_cmd(0x80+8); break; case 4: week--;//调节星期 if(week==0)week=7; lcd_write_week(week); write_cmd(0x80+11); break; case 5: hour--;//调节时 if(hour==-1)hour=23; write_sf(0x40+4,hour); write_cmd(0x80+0x40+4); break; case 6: min--;//调节分 if(min==-1)min=59; write_sf(0x40+7,min); write_cmd(0x80+0x40+7); break; case 7: sec--;//调节秒 if(sec==-1)sec=59; write_sf(0x40+10,sec); write_cmd(0x80+0x40+10); break; default:break; } } } } } //#include<timee_Delay.h> //The main only needs to call getDHT11() //then the temperature and huminity was geted in F16T,F16RH as float ***it bit11=P2^0; unsigned char U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata; float F16T,F16RH; //read 8 bits onice void Delay_us(unsigned char n); char COM(void) { char i,U8temp,U8comdata; for(i=0;i<8;i++) { while(!bit11);//表示读取的高电位延时大于20多us,则读取的是1,否则读取的是0 Delay_us(35); U8temp=0; if(bit11) U8temp=1; while(bit11); U8comdata<<=1; U8comdata|=U8temp; //0 }//rof return U8comdata; } //------------------------ //----温湿度读取子程序---- //------------------------ //----以下变量均为全局变量---- //----温度高8位==U8T_data_H---- //----温度低8位==U8T_data_L---- //----湿度高8位==U8RH_data_H---- //----湿度低8位==U8RH_data_L---- //----校验8位==U8checkdata---- //----调用相关子程序如下---- //----Delay();,Delay_10us();,COM(); //------------------------ void Delay_ms(unsigned int n); void getDHT11(void) { //主机拉低18ms GO1: bit11=0; Delay_ms(20); bit11=1; //总线由上拉电阻拉高 主机延时20us Delay_us(60); //主机设为输入 判断从机响应信号 // bit11=1 //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(!bit11) //T! { while(!bit11); //wait DHT goto high while(bit11); //数据接受状态 U8RH_data_H=COM(); U8RH_data_L=COM(); U8T_data_H=COM(); U8T_data_L=COM(); U8checkdata=COM(); bit11=1; //数据校验 if((U8T_data_H+U8T_data_L+U8RH_data_H+U8RH_data_L)!=U8checkdata) //if check wrong,read again goto GO1; }//fi F16T=U8T_data_H+(float)U8T_data_L/256; //change integer to float F16RH=U8RH_data_H+(float)U8RH_data_L/256; } //----LCD1602---- #include #include #include //#include //#include #define LCD_DATA P0 //LCD1602 data transfer define #define uint unsigned int #define uchar unsigned char /**** 只由主函数调用的有 Init_Lcd() LCD_write_str(uchar X,uchar Y,uchar *s) LCD_value(unsigned char x,unsigned char y,float f) ****/ //***it LCD_RS=P2^5; //1602 control define //***it RW=P2^6; //***it LCD_E=P2^7; /***************************************** #define LCD_SCREEN_ON 0x0C //显示开 #define LCD_SCREEN_OFF 0x08 //显示关 #define LCD_CURSOR_ON 0X0A //显示光标 #define LCD_CURSOR_OFF 0x0c //无光标 #define LCD_C_FLASH_ON 0x0f //有光标,光标闪动 #define LCD_C_FLASH_OFF 0x0c //有光标,光标不闪动 //进入模式设置指令 #define LCD_AC_UP 0x06 //新数据后光标右移 #define LCD_AC_DOWN 0x04 //新数据后光标左移 #define LCD_S_MOVE_ON 0X05 //画面可平移 #define LCD_S_MOVE_OFF 0x04 //画面不可平移 //设定显示屏或光标移动方向指令 #define LCD_C_LEFT 0x10 //光标左移1格,且AC值减1 #define LCD_C_RIGHT 0x11 //光标右移1格,且AC值加1 #define LCD_CHAR_LEFT 0x18 //显示器上字符全部左移1格,但光标不动 #define LCD_CHAR_RIGHT 0x1C //显示器上字符全部右移1格,但光标不动 *******************************************/ //注 有主函数调用的函数都已作说明 其他函数一般不由主函数调用 /********************************************* * 名 称:Init_Lcd() 主函数调用 * 功 能:Lcd 初始化 * 入口参数:无 * 出口参数:无 *范 例:在主函数中直接调用 **********************************************/ void LCD_write_char(uchar cd,uchar ab); void Init_Lcd() //LCD初始化 { LCD_write_char(0x38,0); Delay_ms(1); LCD_write_char(0x38,0); Delay_ms(1); LCD_write_char(0x38,0); Delay_ms(1); LCD_write_char(0x0c,0); Delay_ms(1); LCD_write_char(0x06,0); Delay_ms(1); LCD_write_char(0x0c,0); Delay_ms(1); } /****************************************************** *名 称:LCD_write_str(uchar X,uchar Y,uchar *s)主函数调用 *功 能:在指定地址写一个字符串 eg:Y=0,1,2,3,4,5,6,7,8,9,10...15。 X=0,1。 *入口参数:X:横坐标 Y:纵坐标 *s:字符串首地址 *出口参数:无 *范 例:LCD_write_str(1,1,uchar *s) *****************************************************/ void LCD_set_xy(uchar x,uchar y); void LCD_write_str(unsigned char X,unsigned char Y,unsigned char *s) { LCD_write_char(0,' '); LCD_set_xy(X,Y); //写地址 while(*s) //写显示字符 { LCD_write_char(0,*s); s++; } } /****************************************************** *名 称:LCD_set_xy(uchar x,uchar y) the optic sign flash? *功 能:指定一个地址 *入口参数:X:横坐标 Y:纵坐标 *出口参数:无 *范 例:LCD_set_xy(5,1) *****************************************************/ void LCD_set_xy(uchar x,uchar y) //写地址函数 { unsigned char address; if(y==0) address=0x80+x; else address=0xc0+x; LCD_write_char(address,0); } /******************************************************* *名 称:LCD_en_write(void) *功 能:液晶使能 *入口参数:无 *出口参数:无 *范 例:直接调用 ******************************************************/ void LCD_en_write(void) //液晶使能 { //_nop_(); LCD_E=1; //EN=1 //_nop_(); LCD_E=0; //EN=0 } //------------------------------------------------------ /************************************************ *名 称:LCD_write_char(uchar cd,uchar ab) *功 能:写指令或数据 当写ab时 应使cd=0 当cd不为0 且ab的赋值无效 *入口参数:cd:指令内容 ab:数据内容 指令常量已在上面定义 但一般不用 *出口参数:无 *范 例:LCD_write_char(0,'f') ***********************************************/ void LCD_byte(unsigned char abc); void LCD_write_char(uchar cd,uchar ab) //写数据 { Delay_us(20); if(cd==0) { LCD_RS=1; //RS=1,写显示内容 LCD_byte(ab); } else { LCD_RS=0; //RS=0,写命令 LCD_byte(cd); } } /************************************************* *名 称:LCD_byte(abc); *功 能:写一个字符到 or called one byte to LCD 中 *入口参数: *出口参数:无 *************************************************/ void LCD_byte(unsigned char abc) { RW=0; LCD_E=0; LCD_DATA=abc; LCD_en_write(); } //在液晶中显示浮点数函数 LCD_value(unsigned char x,unsigned char y,float f) { unsigned char str[15]; //不能定义为char *str,数组长度一定要大于浮点 //数的总位数 sprintf(str,"%.1f",f); //1表示小数位数 小数太多 自动四舍五入 LCD_write_str(x,y,str); return 0; } //主函数文件 #include #include //#include //#include //#include"DHT11.H" extern float F16T,F16RH; //全局变量声明 /* */ /**** 主 函 数 ****/ /* */ void main() { if(P3^3) { Init_Lcd(); LCD_write_str(0,1,"Bless You!"); //液晶预显示测试 LCD_value(0,0,2015.520); Delay_ms(2000); Init_Lcd(); while(1) { getDHT11(); LCD_write_str(0,0,"Tem="); LCD_value(5,0,F16T); LCD_write_str(8,0,""C"); //字符 " 应用转义格式 LCD_write_str(0,1,"Hum="); LCD_value(5,1,F16RH); LCD_write_str(9,1,"%"); Delay_ms(500); } } else { init(); Init_DS1302(); while(1) { keyscan(); if(flag==0) display(); } } } //延时函数文件 //以下为延时函数 this is fit to old C51 12MHz,12 devide frequency void Delay_ms(unsigned int n) //n毫秒延时 { unsigned char j; while(n--) { for(j=0;j<125;j++); } } void Delay_us(unsigned char n) //N us 延时函数 { n=n/2; while(--n); } |
|
相关推荐
15个回答
|
|
ADDRESS SPACE OVERFLOW啊 你的Keil和谐了没有? 你的全局变量或许太多了。,
最佳答案
|
|
|
|
这两个都是i2c的吧,你这里是怎么处理的
|
|
|
|
程序出现问题,什么都不显示,求解 是否与程序在keil中出现ADDRESS SPACE OVERFLOW有关? |
|
|
|
我现在在学习万年历的程序,还没有你这么难的,你懂了教教我哈
|
|
|
|
楼主弄完了展示展示呗
|
|
|
|
问题解决了,还想问问 I2C 这我不大懂求解释? |
|
|
|
I2C怎么了,你按它的协议走就没有问题啊,有好多协议的文章你可以找找 |
|
|
|
|
|
|
|
|
|
|
|
问题已解决
|
|
|
|
|
|
|
|
楼主能把完整的文件发给我吗,我也在做类似的,拜托了
|
|
|
|
楼楼有单独的DHT11和1602的代码吗,求分享啊
|
|
|
|
有原程序吗?求分享
|
|
|
|
大哥哥改好了吗?我真的需要这个程序,能发给我吗,万分感谢。。。。。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
727 浏览 0 评论
815 浏览 0 评论
850 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
823 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
1274 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11819 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 03:35 , Processed in 0.988064 second(s), Total 104, Slave 85 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号