C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 1 C51 COMPILER V8.02, COMPILATION OF MODULE 0 OBJECT MODULE PLACED IN 0.OBJ COMPILER INVOKED BY: D:\处理软件\keil\C51\BIN\C51.EXE 0.c BROWSE DEBUG OBJECTEXTEND line level source 1 /*******************************************************************/ 2 /* */ 3 /* TX-51STAR单片机开发系统演示程序 - DS18B20-64位序列码读取程序 */ 4 /* * 5 * LCD1602显示 * 6 * * 7 * 工作芯片:STC89C516 晶振频率:11.0592MHz * 8 * * 9 * 版本: V1.0 (2009/1/2) * 10 * 作者: 郭天祥 (Email: txmcu@163.com) * 11 * 网站: www.tx-power.com(天祥电子) * 12 * 邮箱: txmcu@163.com * 13 * * 14 *【版权】Copyright(C)天祥电子 www.tx-power.com All Rights Reserved * 15 *【声明】此程序仅用于学习与参考,引用请注明版权和作者信息! * 16 * * 17 /*******************************************************************/ 18 /*读取DS18B20的64位序列码并显示在1602液晶上,如果读取正确结果,则在 19 液晶第一行显示DS18B20 OK,第二行显示序列码,如果读取失败,则在液晶上 20 显示DS18B20 ERR0R PLEASE CHECK ,用户可通过更改18B20接口自己外接。 */ 21 #include 22 #include 23 24 #define uchar unsigned char 25 #define uint unsigned int 26 27 sbit DQ = P2^2; //定义DS18B20端口DQ 28 sbit BEEP=P2^3 ; //蜂鸣器驱动线 29 30 bit presence ; 31 32 sbit LCD_RS = P3^5; 33 //sbit LCD_RW = P2^1; 34 sbit LCD_EN = P3^4; 35 36 uchar code cdis1[ ] = {" DS18B20 OK "}; 37 uchar code cdis2[ ] = {" "}; 38 uchar code cdis3[ ] = {" DS18B20 ERR0R "}; 39 uchar code cdis4[ ] = {" PLEASE CHECK "}; 40 41 unsigned char data display[2] = {0x00,0x00}; 42 43 unsigned char data RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 44 45 unsigned char Temp; 46 unsigned char crc; 47 48 void beep(); 49 50 #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; 51 52 /*******************************************************************/ 53 void delay1(int ms) 54 { 55 1 unsigned char y; C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 2 56 1 while(ms--) 57 1 { 58 2 for(y = 0; y<250; y++) 59 2 { 60 3 _nop_(); 61 3 _nop_(); 62 3 _nop_(); 63 3 _nop_(); 64 3 } 65 2 } 66 1 } 67 68 /******************************************************************/ 69 /* */ 70 /*检查LCD忙状态 */ 71 /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */ 72 /* */ 73 /******************************************************************/ 74 75 bit lcd_busy() 76 { 77 1 bit result; 78 1 LCD_RS = 0; 79 1 // LCD_RW = 1; 80 1 LCD_EN = 1; 81 1 delayNOP(); 82 1 result = (bit)(P0&0x80); 83 1 LCD_EN = 0; 84 1 return(result); 85 1 } 86 87 /*******************************************************************/ 88 /* */ 89 /*写指令数据到LCD */ 90 /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */ 91 /* */ 92 /*******************************************************************/ 93 94 void lcd_wcmd(uchar cmd) 95 96 { 97 1 // while(lcd_busy()); 98 1 LCD_RS = 0; 99 1 // LCD_RW = 0; 100 1 LCD_EN = 0; 101 1 _nop_(); 102 1 _nop_(); 103 1 P0 = cmd; 104 1 delayNOP(); 105 1 LCD_EN = 1; 106 1 delayNOP(); 107 1 LCD_EN = 0; 108 1 delay1(5); 109 1 } 110 111 /*******************************************************************/ 112 /* */ 113 /*写显示数据到LCD */ 114 /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */ 115 /* */ 116 /*******************************************************************/ 117 C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 3 118 void lcd_wdat(uchar dat) 119 { 120 1 // while(lcd_busy()); 121 1 LCD_RS = 1; 122 1 // LCD_RW = 0; 123 1 LCD_EN = 0; 124 1 P0 = dat; 125 1 delayNOP(); 126 1 LCD_EN = 1; 127 1 delayNOP(); 128 1 LCD_EN = 0; 129 1 delay1(5); 130 1 } 131 132 /*******************************************************************/ 133 /* */ 134 /* LCD初始化设定 */ 135 /* */ 136 /*******************************************************************/ 137 138 void lcd_init() 139 { 140 1 delay1(15); 141 1 lcd_wcmd(0x01); //清除LCD的显示内容 142 1 143 1 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 144 1 delay1(5); 145 1 lcd_wcmd(0x38); 146 1 delay1(5); 147 1 lcd_wcmd(0x38); 148 1 delay1(5); 149 1 150 1 lcd_wcmd(0x0c); //显示开,关光标 151 1 delay1(5); 152 1 lcd_wcmd(0x06); //移动光标 153 1 delay1(5); 154 1 lcd_wcmd(0x01); //清除LCD的显示内容 155 1 delay1(5); 156 1 } 157 158 /*******************************************************************/ 159 /* */ 160 /* 设定显示位置 */ 161 /* */ 162 /*******************************************************************/ 163 164 void lcd_pos(uchar pos) 165 { 166 1 lcd_wcmd(pos | 0x80); //数据指针=80+地址变量 167 1 } 168 169 /*******************************************************************/ 170 /* */ 171 /*us级延时函数 */ 172 /* */ 173 /*******************************************************************/ 174 175 void Delay(unsigned int num) 176 { 177 1 while( --num ); 178 1 } 179 C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 4 180 /*******************************************************************/ 181 /* */ 182 /*初始化ds1820 */ 183 /* */ 184 /*******************************************************************/ 185 Init_DS18B20(void) 186 { 187 1 DQ = 1; //DQ复位 188 1 Delay(8); //稍做延时 189 1 190 1 DQ = 0; //将DQ拉低 191 1 Delay(90); //精确延时 大于 480us 192 1 193 1 DQ = 1; //拉高总线 194 1 Delay(8); 195 1 196 1 presence = DQ; //读取存在信号 197 1 Delay(100); 198 1 DQ = 1; 199 1 200 1 return(presence); //返回信号,0=presence,1= no presence 201 1 } 202 203 /*******************************************************************/ 204 /* */ 205 /* 读一位(bit) */ 206 /* */ 207 /*******************************************************************/ 208 uchar read_bit(void) 209 { 210 1 unsigned char i; 211 1 DQ = 0; //将DQ 拉低开始读时间隙 212 1 DQ = 1; // then return high 213 1 for (i=0; i<3; i++); // 延时15μs 214 1 return(DQ); // 返回 DQ 线上的电平值 215 1 } 216 217 /*******************************************************************/ 218 /* */ 219 /* 读一个字节 */ 220 /* */ 221 /*******************************************************************/ 222 ReadOneChar(void) 223 { 224 1 unsigned char i = 0; 225 1 unsigned char dat = 0; 226 1 227 1 //for (i = 8; i > 0; i--) 228 1 // { 229 1 // read_bit(); 230 1 // DQ = 0; // 给脉冲信号 231 1 // dat >>= 1; 232 1 // DQ = 1; // 给脉冲信号 233 1 for (i=0;i<8;i++) 234 1 { // 读取字节,每次读取一个字节 235 2 if(read_bit()) dat|=0x01< 0; i--) 267 1 // { 268 1 for (i=0; i<8; i++) // 写入字节, 每次写入一位 269 1 { 270 2 // DQ = 0; 271 2 // DQ = dat&0x01; 272 2 // Delay(5); 273 2 274 2 // DQ = 1; 275 2 temp = dat>>i; 276 2 temp &= 0x01; 277 2 write_bit(temp); 278 2 // dat>>=1; 279 2 280 2 } 281 1 Delay(5); 282 1 } 283 284 /*******************************************************************/ 285 /* */ 286 /* 读取64位序列码 */ 287 /* */ 288 /*******************************************************************/ 289 Read_RomCord(void) 290 { 291 1 unsigned char j; 292 1 Init_DS18B20(); 293 1 294 1 WriteOneChar(0x33); // 读序列码的操作 295 1 for (j = 0; j < 8; j++) 296 1 { 297 2 RomCode[j] = ReadOneChar() ; 298 2 } 299 1 } 300 301 /*******************************************************************/ 302 /* */ 303 /*DS18B20的CRC8校验程序 */ C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 6 304 /* */ 305 /*******************************************************************/ 306 uchar CRC8() 307 { 308 1 uchar i,x; uchar crcbuff; 309 1 310 1 crc=0; 311 1 for(x = 0; x <8; x++) 312 1 { 313 2 crcbuff=RomCode[x]; 314 2 for(i = 0; i < 8; i++) 315 2 { 316 3 if(((crc ^ crcbuff)&0x01)==0) 317 3 crc >>= 1; 318 3 else { 319 4 crc ^= 0x18; //CRC=X8+X5+X4+1 320 4 crc >>= 1; 321 4 crc |= 0x80; 322 4 } 323 3 crcbuff >>= 1; 324 3 } 325 2 } 326 1 return crc; 327 1 } 328 /*******************************************************************/ 329 /* */ 330 /* 数据转换与显示 */ 331 /* */ 332 /*******************************************************************/ 333 334 Disp_RomCode() 335 { 336 1 uchar j; 337 1 uchar H_num=0x40; //LCD第二行初始位置 338 1 339 1 for(j=0;j<8;j++) 340 1 { 341 2 Temp = RomCode[j]; 342 2 343 2 display[0]=((Temp&0xf0)>>4); 344 2 if(display[0]>9) 345 2 { display[0]=display[0]+0x37;} 346 2 else{display[0]=display[0]+0x30;} 347 2 348 2 lcd_pos(H_num); 349 2 lcd_wdat(display[0]); //高位数显示 350 2 351 2 H_num++; 352 2 display[1]=(Temp&0x0f); 353 2 if(display[1]>9) 354 2 {display[1]=display[1]+0x37;} 355 2 else {display[1]=display[1]+0x30;} 356 2 357 2 lcd_pos(H_num); 358 2 lcd_wdat(display[1]); //低位数显示 359 2 H_num++; 360 2 } 361 1 } 362 363 /*******************************************************************/ 364 /* */ 365 /* 蜂鸣器响一声 */ C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 7 366 /* */ 367 /*******************************************************************/ 368 void beep() 369 { 370 1 unsigned char y; 371 1 for (y=0;y<100;y++) 372 1 { 373 2 Delay(60); 374 2 BEEP=!BEEP; //BEEP取反 375 2 } 376 1 BEEP=1; //关闭蜂鸣器 377 1 Delay(40000); 378 1 } 379 380 /*******************************************************************/ 381 /* */ 382 /* DS18B20 OK 显示菜单 */ 383 /* */ 384 /*******************************************************************/ 385 void Ok_Menu () 386 { 387 1 uchar m; 388 1 lcd_init(); //初始化LCD 389 1 390 1 lcd_pos(0); //设置显示位置为第一行的第1个字符 391 1 m = 0; 392 1 while(cdis1[m] != '\0') 393 1 { //显示字符 394 2 lcd_wdat(cdis1[m]); 395 2 m++; 396 2 } 397 1 398 1 lcd_pos(0x40); //设置显示位置为第二行第1个字符 399 1 m = 0; 400 1 while(cdis2[m] != '\0') 401 1 { 402 2 lcd_wdat(cdis2[m]); //显示字符 403 2 m++; 404 2 } 405 1 } 406 407 /*******************************************************************/ 408 /* */ 409 /* DS18B20 ERROR 显示菜单 */ 410 /* */ 411 /*******************************************************************/ 412 void Error_Menu () 413 { 414 1 uchar m; 415 1 lcd_init(); //初始化LCD 416 1 417 1 lcd_pos(0); //设置显示位置为第一行的第1个字符 418 1 m = 0; 419 1 while(cdis3[m] != '\0') 420 1 { //显示字符 421 2 lcd_wdat(cdis3[m]); 422 2 m++; 423 2 } 424 1 425 1 lcd_pos(0x40); //设置显示位置为第二行第1个字符 426 1 m = 0; 427 1 while(cdis4[m] != '\0') C51 COMPILER V8.02 0 06/29/2010 15:15:13 PAGE 8 428 1 { 429 2 lcd_wdat(cdis4[m]); //显示字符 430 2 m++; 431 2 } 432 1 } 433 434 /*******************************************************************/ 435 /* */ 436 /* 主函数 */ 437 /* */ 438 /*******************************************************************/ 439 void main() 440 { 441 1 P0 = 0xff; 442 1 P2 = 0xff; 443 1 444 1 while(1) 445 1 { 446 2 Ok_Menu (); 447 2 Read_RomCord(); //读取64位序列码 448 2 CRC8(); //CRC效验 449 2 if(crc==0) //CRC效验正确 450 2 { 451 3 Disp_RomCode(); //显示64位序列码 452 3 beep(); 453 3 } 454 2 while(!presence) 455 2 { 456 3 Init_DS18B20(); 457 3 delay1(1000); 458 3 } 459 2 460 2 Error_Menu (); 461 2 do 462 2 { 463 3 Init_DS18B20(); 464 3 beep(); 465 3 } 466 2 while(presence); 467 2 } 468 1 } 469 470 /*******************************************************************/ MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 639 ---- CONSTANT SIZE = 68 ---- XDATA SIZE = ---- ---- PDATA SIZE = ---- ---- DATA SIZE = 12 ---- IDATA SIZE = ---- ---- BIT SIZE = 1 1 END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)