51单片机+DS18B20+LCD1602显示+Proteus仿真
51单片机+DS18B20+LCD1602显示+Proteus仿真
- Proteus仿真

实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| #include "reg51.h" sbit RS=P3^0; sbit RW=P3^1; sbit E=P3^2; sbit DQ=P3^3; int readtemp=0; unsigned char str[]={"0123456789"}; unsigned char s[]={"Temperature:"};
void delay\_18B20(unsigned int i)//延时函数 { for(;i>0;i--); }
void Init\_DS18B20(void) //初始化 { unsigned char x=0; DQ = 1; //DQ拉高, delay\_18B20(8); //稍作延时 DQ = 0; //DQ拉低, 将总线拉低,持续时间为480us到960us之间 delay\_18B20(80); //延时大于480us DQ = 1; //拉高总线,将总线拉高 delay\_18B20(14); x=DQ; //若x=0初始化成功,若x=1初始化失败 delay\_18B20(20);//等待DS18B20的应答,若初始化成功,会在15-60us之后产生一个低电平信号,该信号会持续60us到240us } //之后DS18B20会主动释放总线,总线电平会被拉高
unsigned char ReadOneChar(void)//读时序分为读“0”时序和读“1”时序两个过程。 { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; // 拉低总线,当要读取DS18B20的数据时,我们需要将总线拉低,并保持1us的时间, dat>>=1;//每读取移位向右移移位 DQ = 1; //拉高总线,然后将总线拉高,此时需尽快读取。 if(DQ) dat|=0x80; delay\_18B20(4);//从拉低到读取引脚状态的时间不能超过15us。 } return(dat); } void WriteOneChar(unsigned char dat)//写时序分为写“0”时序和写“1”时序两个过程。DS18B20写“0”时序和写“1”时序的要求不同, { unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; if(DQ){delay\_18B20(1);DQ=1;}//当要写“0”时,单总线要被拉低至少60?s,以保证DS18B20能够在15?s到45?s之间,正确地采样I/O总线上的“0”电平 else{delay\_18B20(5);DQ = 1;}//当要写“1”时,单总线被拉低之后,在15?s之内就得释放单总线。 dat>>=1; } }
unsigned char ReadTemperature(void)//读温度 { unsigned char a=0,b=0; unsigned int temp=0; Init\_DS18B20(); WriteOneChar(0xCC); // 跳过读序列号操作 WriteOneChar(0x44); // 启动温度转换 delay\_18B20(100); // Init\_DS18B20(); WriteOneChar(0xCC); //跳过读序列号操作 WriteOneChar(0xBE); //读取温度寄存器 delay\_18B20(100); a=ReadOneChar(); //读温度低位 b=ReadOneChar(); //读温度高位 temp=((b\*256+a)>>4); //当前采集温度除16得到实际温度 return(temp); }
void delay(unsigned int n)//延时函数 { unsigned int i=0,j=0; for(i=0;i<n;i++) { for(j=0;j<120;j++); } }
void writedat(unsigned char dat)//写数据函数,LCD1602的函数 { RS=1; // RS:数据/命令选择端 RW=0; // R/W :读/写选择端 E=0; // 使能端:下降沿有效 P1=dat; delay(5); E=1; E=0; }
void writecom(unsigned char com)//写命令函数 { RS=0; // RS:数据/命令选择端 RW=0; // R/W :读/写选择端 E=0; //使能端:下降沿有效 P1=com; delay(5); E=1; E=0; }
void initlcd()//初始化LCD1602 { writecom(0x38); //0x38;设置16×2显示 writecom(0x0c); //0x0C:设置开显示,不显示光标 writecom(0x06); //0x06:写一个字符后地址指针加1 writecom(0x01); //0x01:显示清0,数据指针清0 }
void display()//显示函数 { unsigned int temp0=0,temp1=0,temp2=0,i=0; temp0=readtemp/100; temp1=(readtemp%100)/10; temp2=readtemp%10; writecom(0x80); //0x80:LCD第一行的起始地址 delay(5); // 延时 while(s[i]!='\0') { writedat(s[i]); delay(5); i++; } writecom(0x80+0x40+5); //0x80+0x40:LCD第2行的起始地址 delay(5); writedat(str[temp0]); delay(5); //延时 writedat(str[temp1]); delay(5); //延时 writedat(str[temp2]); delay(5); //延时 writedat(0xDF); delay(5); //延时 writedat('C'); delay(5); //延时 }
void main() { initlcd(); while(1) { readtemp=ReadTemperature(); display(); } }
|
仿真资源和源码下载
1 2 3 4
| 链接:https://pan.baidu.com/s/1A9g7vmShDewtDTh2HZaYZQ 提取码:ri8m
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!