单片机源程序如下:
- #include <reg51.h>
- #include <word.h>
- #include <NumDisplay.h>
- #include <12864.h>
- sbit ds=P3^7; //18b20信号线
- unsigned char data disdata[5];
- unsigned int temp; //定义整形的温度数据
- float f_temp; //定义浮点型的温度数据
- unsigned char tflag;//温度正负标志
- void dsreset(void) //DS18B20初始化函数
- {
- unsigned int i;
- ds=0;
- i=103;
- while(i>0)i--;
- ds=1;
- i=4;
- while(i>0)i--;
- }
- bit tempreadbit(void) //读1位数据函数
- {
- unsigned int i;
- bit dat;
- ds=0;
- i++;
- ds=1;
- i++;i++;
- dat=ds;
- i=8;while(i>0)i--;
- return(dat);
- }
- unsigned char tempread(void)
- {
- unsigned char i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tempreadbit();
- dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在dat里
- }
- return(dat);
- }
- void tempwritebyte(unsigned char dat)
- {
- unsigned int i;
- unsigned char j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //写1
- {
- ds=0;
- i++;i++;
- ds=1;
- i=8;while(i>0)i--;
- }
- else
- {
- ds=0;
- i=8;while(i>0)i--;
- ds=1;
- i++;i++;
- }
- }
- }
- void tempchange(void) //DS18B20开始获取温度并转换
- {
- dsreset();
- delay(1);
- tempwritebyte(0xcc);//写跳过读ROM指令
- tempwritebyte(0x44);//写温度转换指令
- }
- /*DS18B20温度测量*/
- unsigned int get_temp()
- {
- unsigned char a,b;
- dsreset();
- delay(1);
- tempwritebyte(0xcc);
- tempwritebyte(0xbe);
- a=tempread();//读低8位
- b=tempread();//读高8位
- temp=b;
- temp<<=8;//两个字节组合为1个字
- temp=temp|a;
- if(temp<0x0fff)
- tflag=0;
- else
- {
- temp=~temp+1;
- tflag=1;
- }
- f_temp=temp*0.0625; //温度在寄存器中位12位,分辨率为0.0625
- temp=f_temp*10+0.5; //乘以10表示小数点后面只取一位,加入0.5是四舍五入
- f_temp=f_temp+0.05;
- return temp;//temp是整型
- }
-
- void dis_temp(unsigned int tvalue)
- {
- disdata[0]=tvalue/1000+0x30;//百位数 加上0x30就是要显示数字字符
- disdata[1]=tvalue%1000/100+0x30;//十位数
- disdata[2]=tvalue%100/10+0x30;//个位数
- disdata[3]=tvalue%10+0x30;//小数位
-
- if(tflag==0)
- vShowOneChar(0,40,uca_zheng);
- else
- vShowOneChar(0,40,uca_fu);
- trans(0,disdata[0],48);
- trans(0,disdata[1],56);
- trans(0,disdata[2],64);
- vShowOneChar(0,72,uca_dian); //小数点
- trans(0,disdata[3],80);
- }
复制代码 上面DS18B20的结果能在12864上面正常显示,但是下面DHT11的值一直不显示
- #include <reg51.h>
- #include <word.h>
- #include <NumDisplay.h>
- #include <12864.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit Data = P3^6;//定义数据线
- unsigned char data dis1[4]; //用于显示的接收数据数组
- uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
-
- /*------------------------------------------------
- DHT11延时函数
- ------------------------------------------------*/
- void DHT11_delay_us(uchar n)
- {
- while(--n);
- }
-
- void DHT11_delay_ms(uint z)
- {
- uint i,j;
- for(i=z;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*------------------------------------------------
- DHT11开始信号
- ------------------------------------------------*/
- void DHT11_start()
- {
- Data=1;
- DHT11_delay_us(2);
- Data=0;
- DHT11_delay_ms(20); //延时18ms以上
- Data=1;
- DHT11_delay_us(30);
- }
- /*------------------------------------------------
- 接收八位二进制
- ------------------------------------------------*/
- uchar DHT11_rec_byte() //接收一个字节
- {
- uchar i,dat=0;
- for(i=0;i<8;i++) //从高到低依次接收8位数据
- {
- while(!Data); ////等待50us低电平过去
- DHT11_delay_us(8); //延时60us,如果还为高则数据为1,否则为0
- dat<<=1; //移位使正确接收8位数据,数据为0时直接移位
- if(Data==1) //数据为1时,使dat加1来接收数据1
- dat+=1;
- while(Data); //等待数据线拉低
- }
- return dat;
- }
- /*------------------------------------------------
- 接收40bit数据
- ------------------------------------------------*/
- void DHT11_receive() //接收40位的数据
- {
- DHT11_start();
-
- if(Data==0)
- {
-
- while(Data==0); //等待拉高
-
- DHT11_delay_us(40); //拉高后延时80us
- R_H=DHT11_rec_byte(); //接收湿度高八位
- R_L=DHT11_rec_byte(); //接收湿度低八位
- T_H=DHT11_rec_byte(); //接收温度高八位
- T_L=DHT11_rec_byte(); //接收温度低八位
- revise=DHT11_rec_byte(); //接收校正位
-
- DHT11_delay_us(25); //结束
-
- if((R_H+R_L+T_H+T_L)==revise) //校正
- {
- RH=R_H;
- RL=R_L;
- TH=T_H;
- TL=T_L;
- }
- }
- }
- void display()
- {
-
- dis1[0]=RH/10%10+0x30;
- dis1[1]=RH%10+0x30;
- //dis1[2]=TH/10%10+0x30;
- //dis1[3]=TH%10+0x30;
- trans(2,dis1[0],48);
- trans(2,dis1[1],56);
- vShowOneChar(2,64,uca_bfh); //小数点
- }
复制代码- //这是12864的代码
- #include <reg51.h>
- #define LCDLCDDisp_Off 0x3e
- #define LCDLCDDisp_On 0x3f
- #define Page_Add 0xb8//页地址
- #define LCDCol_Add 0x40//列地址
- #define Start_Line 0xC0//行地址
- /*****液晶显示器的端口定义*****/
- #define data_ora P0 /*液晶数据总线*/
- sbit CS1=P2^4 ; /*片选1*/
- sbit CS2=P2^3 ; /*片选2*/
- sbit RESET=P2^3 ; /*复位信号*/
- sbit LCDDi=P2^2 ; /*数据/指令 选择*/
- sbit LCDRW=P2^1 ; /*读/写 选择*/
- sbit LCDEnable=P2^0 ; /*读/写 使能*/
- /****************************************************************************
- 函数功能:延时程序
- 入口参数:t
- 出口参数:
- ****************************************************************************/
- void delay(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++);
- for(j=0;j<10;j++);
- }
- /****************************************************************************
- 状态检查,LCD是否忙
- *****************************************************************************/
- void CheckState()
- {
- unsigned char dat,DATA;//状态信息(判断是否忙)
- LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据
- LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0
- do
- {
- DATA=0x00;
- LCDEnable=1; //EN下降源
- delay(2);//延时
- dat=DATA;
- LCDEnable=0;
- dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
- }
- while(!(dat==0x00));
- }
- /*****************************************************************************
- 函数功能:写命令到LCD程序,RS(DI)=L,RW=L,EN=H,即来一个脉冲写一次
- 入口参数:cmdcode
- 出口参数:
- *****************************************************************************/
- void write_com(unsigned char cmdcode)
- {
- CheckState();//检测LCD是否忙
- LCDDi=0;
- LCDRW=0;
- P0=cmdcode;
- delay(2);
- LCDEnable=1;
- delay(2);
- LCDEnable=0;
- }
- /*****************************************************************************
- 函数功能:LCD初始化程序
- 入口参数:
- 出口参数:
- *****************************************************************************/
- void init_lcd()
- {
- delay(100);
- CS1=1;//刚开始关闭两屏
- CS2=1;
- delay(100);
- write_com(LCDLCDDisp_Off); //写初始化命令
- write_com(Page_Add+0);
- write_com(Start_Line+0);
- write_com(LCDCol_Add+0);
- write_com(LCDLCDDisp_On);
- }
- /*****************************************************************************
- 函数功能:写数据到LCD程序,RS(DI)=H,RW=L,EN=H,即来一个脉冲写一次
- 入口参数:LCDDispdata
- 出口参数:
- *****************************************************************************/
- void write_data(unsigned char LCDDispdata)
- {
- CheckState();//检测LCD是否忙
- LCDDi=1;
- LCDRW=0;
- P0=LCDDispdata;
- delay(2);
- LCDEnable=1;
- delay(2);
- LCDEnable=0;
- }
- /*****************************************************************************
- 函数功能:清除LCD内存程序
- 入口参数:pag,col,hzk
- 出口参数:
- *****************************************************************************/
- void Clr_Scr()
- {
- unsigned char j,k;
- CS1=0; //左、右屏均开显示
- CS2=0;
- write_com(Page_Add+0);
- write_com(LCDCol_Add+0);
- for(k=0;k<8;k++)//控制页数0-7,共8页
- {
- write_com(Page_Add+k); //每页每页进行写
- for(j=0;j<64;j++) //每页最多可写32个中文文字或64个ASCII字符
- {
- write_com(LCDCol_Add+j);
- write_data(0x00);//控制列数0-63,共64列,写点内容,列地址自动加1
- }
- }
- }
- //显示自定义行
- //在8×128的格子里显示自定义长度的一行
- void vShowCustomRow(unsigned char ucPage,unsigned char ucLine,unsigned char ucWidth,unsigned char *ucaRow)
- {
- unsigned char ucCount; //取值范围:ucPage:0~7;ucLine:0~127;
- if(ucLine<64) //ucWidth:0~127;ucLine+ucWidth<1128。
- {
- CS1=0; //左半屏
- CS2=1;
- write_com(Page_Add+ucPage);
- write_com(LCDCol_Add+ucLine);
- if((ucLine+ucWidth)<=64)
- {
- for(ucCount=0;ucCount<ucWidth;ucCount++)
- write_data(*(ucaRow+ucCount));
- }
- }
- else
- {
- CS1=1;
- CS2=0;
- write_com(Page_Add+ucPage);
- write_com(LCDCol_Add+ucLine-64);
- for(ucCount=0;ucCount<ucWidth;ucCount++)
- write_data(*(ucaRow+ucCount));
- }
- }
- //汉字显示函数
- //此函数将16×16汉字显示在8×128的格子里。
- void vShowOneChin(unsigned char ucPage,unsigned char ucLine,unsigned char *ucaChinMap)
- {
- vShowCustomRow(ucPage,ucLine,16,ucaChinMap);
- vShowCustomRow(ucPage+1,ucLine,16,ucaChinMap+16);
- }
- //字符显示函数
- //此函数将8×16字符显示在8×128的格子里。
- void vShowOneChar(unsigned char ucPage,unsigned char ucLine,unsigned char *ucaCharMap)
- {
- vShowCustomRow(ucPage,ucLine,8,ucaCharMap);
- vShowCustomRow(ucPage+1,ucLine,8,ucaCharMap+8);
- }
复制代码- #include <reg51.h>
- #include <12864.h>
- #include <word.h>
- //根据输入的tem在12864的第1行的pos位置显示相应的0~9
- void trans(unsigned char hang,unsigned char tem,unsigned int pos)
- {
- switch(tem)
- {
- case '0':vShowOneChar(hang,pos,uca_0);break;
- case '1':vShowOneChar(hang,pos,uca_1);break;
- case '2':vShowOneChar(hang,pos,uca_2);break;
- case '3':vShowOneChar(hang,pos,uca_3);break;
- case '4':vShowOneChar(hang,pos,uca_4);break;
- case '5':vShowOneChar(hang,pos,uca_5);break;
- case '6':vShowOneChar(hang,pos,uca_6);break;
- case '7':vShowOneChar(hang,pos,uca_7);break;
- case '8':vShowOneChar(hang,pos,uca_8);break;
- case '9':vShowOneChar(hang,pos,uca_9);break;
- default: vShowOneChin(hang,pos,uca_du);break;
- }
- }
复制代码 全部资料51hei下载地址:
温湿度测量.rar
(117.93 KB, 下载次数: 11)
|