001#include
002#include
003#define uchar unsigned char // 宏定义uchar 为无符号字符
004#define uint unsigned int
005
006
007***it DQ=P2^3;
008***it alarm =P3^4; //温度告警标志位
009***it test = P1^0;
010
011unsigned long temp; //温度值
012uchar tempH,tempL,tempSign; //ds18b20 读取的温度高位 和低8位 ,最高上限温度和最低下限温度,温度符号
013
014signed long setMax=10;
015signed long setMin=-10;
016float precision=0.0625; //温度精度(默认12位)
017uchar seg[8]={0}; // eg. -100.0625
018
019// 延时函数
020void delay(uint t) //最大65ms 2^16
021{
022 /*TMOD = 0x01; //启用T0 计时器 工作方式1
023 TH0 = (65536 - t )/256;
024 TL0 = (65536 - t )%256;
025 EA = 0; //禁止中断
026 TR0 = 1; //开始T0计数
027 while( TF0 == 0);
028 TF0 = 0; // 清除T0 溢出标志位
029 TR0 = 0; //关闭T0计数*/
030 while(t--);
031}
032
033
034// ds18b20 初始化函数
035uchar init(void)
036{
037 uchar feedback;
038
039 DQ = 0 ;
040 delay(100);
041 DQ = 1;
042
043 /*while(DQ); //用于获取反馈信号,返回0为成功,返回1为初始化失败
044 feedback = DQ;*/
045
046 delay(25);
047
048 //return feedback; //返回0复位成功,返回1复位失败
049
050}
051
052
053// 写函数
054
055void write(uchar var) //先输出低位,再输出高位
056{
057 uchar i;
058 for(i=8;i>0;i--)
059 {
060 DQ = 0;
061 DQ = var&0x01; // 获取最后一位数据写入数据线
062 delay(5);
063 //(DQ == 1)? delay(10):delay(70); //延时保证ds18b20 采样。写入为 1 15us 内需释放数据线;写入为 0 至少延时 60us;
064 DQ = 1;
065 var >>= 1; //右移一位
066 }
067 //delay(5);
068}
069
070// 读函数
071uchar read( void )
072{ //先读取低位,再读取高位
073 uchar feedback = 0;
074 uchar i;
075 for(i=8;i>0;i--)
076 {
077
078 DQ = 0;
079 feedback >>= 1; // 右移
080 DQ = 1; // 数据线拉低15us内 释放数据线
081 //delay(1);
082 if(DQ){ feedback |= 0x80;} //在feedback 在高位写入1 等待右移处理
083 delay(5);
084 }
085
086 return feedback;
087}
088
089
090// 配置ds18b20 参数说明:(最高温度,最低温度)
091//暂不可用
092void setConfig(char th,char tl)
093{
094
095 uchar precision;
096
097 init();
098 write(0xcc);
099 write(0x4e);
100 write(th); //默认最高温度为+125
101 write(tl);//默认最低温度为-55
102
103}
104
105
106// 温度超限报警处理
107void warning()
108{
109 uchar maxSign=0,minSign=0; //最高温度和最低温度符号
110
111 if(setMax > 0)
112 {
113 maxSign = 1;
114 }
115 if(setMin > 0)
116 {
117 minSign = 1;
118 }
119
120 if( temp < labs(setMin)*10000 && tempSign <= minSign ) //小于下限温度
121 {
122 alarm=0;
123 delay(100);
124 alarm=1;
125 delay(100);
126 }else{
127 alarm =0;
128 }
129
130 if( temp > setMax*10000 && tempSign >=maxSign ) //大于上限温度
131 {
132 alarm=0;
133 delay(100);
134 alarm=1;
135 delay(100);
136
137 }else{
138 alarm =0;
139 }
140
141
142
143
144}
145
146// 温度显示处理,转换 tampH 和 tempL ,写入数组 seg[8], 得出十进制 温度 temp
147void convert()
148{
149 uint tempC; //补码温度
150 uchar seg7; //温度符号位
151
152 tempC = tempH*256.0 + tempL;
153
154 //tempC=tempH<<8;
155 //tempC|=tempL;
156
157
158 if(tempC > 0x0800)
159 {
160 seg7 = 0x40; //温度为负温度
161 tempSign = 0;
162 temp = (~tempC + 1); // 补码求原码,取反加一
163 temp=temp*precision;
164
165
166 }else{
167 tempSign = 1;
168 seg7 = 0x00; // 温度为正
169 temp = tempC ;
170 temp=temp*precision*10000; //放大10000倍,用于取余获取各位数值
171 }
172
173 //temp = 1234567;
174 seg[7] = seg7;
175 seg[6] = temp/1000000;
176 seg[5] = temp%1000000/100000;
177 seg[4] = temp%1000000%100000/10000;
178 seg[3] = temp%1000000%100000%10000/1000;
179 seg[2] = temp%1000000%100000%10000%1000/100;
180 seg[1] = temp%1000000%100000%10000%1000%100/10;
181 seg[0] = temp%1000000%100000%10000%1000%100%10;
182}
183
184
185
186//数码管动态显示 ,读取数组seg[8]
187void ledShow()
188{
189
190 uchar i=0,m,led;
191
192 uchar tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管 0-9
193
194 uchar tabPoint[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //共阴数码管 0-9 带小数点
195
196 do{
197 m=seg[i];
198
199 if( i == 4 ) //数码管第四位包含小数点 单片机开发板 数码管和proteus 仿真不同
200 {
201 led = tabPoint[m];
202 }else if( i==7 ){ //符号位跳过译码
203 led = seg[7];
204 }else{
205 led = tab[m];
206 }
207
208
209 P2 = i ; //送位码 单片机开发板 数码管和proteus 仿真不同
210 P0 = led; //送段码
211
212 delay(100);
213
214 i++;
215
216 warning();
217 }while(i<8);
218
219}
220
221
222//从ds18b20 获取温度,获取 tempH 和 tempL
223void getTemp()
224{
225
226 init();
227 write(0xCC); //跳过rom搜索
228 write(0x44); //启动温度转换
229 delay(100); //温度转换最多750ms
230
231 init();
232 write(0xCC);
233 write(0xBE); //读出ds18b20 内部RAM 9直接内容
234 delay(100);
235 tempL = read(); //读出温度低字节
236 tempH = read(); //读出温度高字节
237
238 //tempMax = read(); //读取高温触发器
239 //tempMin = read(); //读取低温触发器
240}
241
242
243void main()
244{
245 while(1){
246 getTemp();
247 convert();
248 ledShow();
249
250 }
251}
|