×
单片机 > 单片机程序设计 > 详情

PIC16F877A 温度DS18B20

发布时间:2020-06-16 发布时间:
|
  1. #include  
  2. #define uchar unsigned char  
  3. #define uint unsigned int  
  4. #define rs_h (PORTC|=0x01)  
  5. #define rs_l (PORTC&=0xfe)  
  6. #define rs_o (TRISC&=0xfe)  
  7. #define rw_h (PORTC|=0x02)  
  8. #define rw_l (PORTC&=0xfd)  
  9. #define rw_o (TRISC&=0xfd)  
  10. #define en_h (PORTC|=0x04)   
  11. #define en_l (PORTC&=0xfb)  
  12. #define en_o (TRISC&=0xfb)  
  13. #define temp_h (PORTC|=0x08)   
  14. #define temp_l (PORTC&=0xf7)   
  15. #define temp_o (TRISC&=0xf7)  
  16. #define temp_i (TRISC|=0x08)  
  17. #define led_o (TRISC&=0xef)  
  18. #define led_l (PORTC&=0xef)  
  19. #define led_h (PORTC|=0x10)  
  20. #define LCD PORTB  
  21. uchar dat1,dat2;//保存读出的温度z  
  22. unsigned long int dat;  
  23. void delayms(uint x) //4M晶振下,延时1ms  
  24. {  
  25.     uint y,z;  
  26.     for(y=x;y>0;y--)  
  27.         for(z=110;z>0;z--);  
  28. }  
  29. void Ds18b20_reset(void)//DS18B20初始化  
  30. {  
  31.     uint count;  
  32.     uchar i,flag=1;  
  33.     temp_o;  
  34.     temp_l;  
  35.     for(count=60;count>0;count--);//延时480us  
  36.     temp_i;  
  37.     while(flag)  
  38.     {  
  39.         if(RC3)  
  40.             flag=1;  
  41.         else  
  42.             flag=0;   
  43.     }  
  44.     led_o;  
  45.     led_l;//开指示灯  
  46.     for(count=60;count>0;count--);//延时480us  
  47. }  
  48. void Ds18b20_write(uchar datt)//向DS18B20写一个字节  
  49. {  
  50.     uchar count;  
  51.     uchar i;  
  52.     temp_o;  
  53.     for(i=8;i>0;i--)  
  54.     {  
  55.         temp_o;  
  56.         temp_l;  
  57.         for(count=1;count>0;count--);  
  58.         if(datt&0x01==0x01)  
  59.             temp_i;  
  60.         else  
  61.         {     
  62.             temp_o;  
  63.             temp_l;  
  64.         }  
  65.         for(count=23;count>0;count--);//延时60us  
  66.         temp_i;  
  67.         for(count=1;count>0;count--);  
  68.         datt>>=1;   
  69.     }     
  70. }  
  71. uchar Ds18b20_read(void) //从DS18B20读一个字节  
  72. {  
  73.     uchar i,datt;  
  74.     uchar count;  
  75.     for(i=8;i>0;i--)  
  76.     {  
  77.         datt>>=1;  
  78.         temp_o;  
  79.         temp_l;  
  80.         for(count=1;count>0;count--);  
  81.         temp_i;//改为输入方向时,上拉电阻把数据线拉高,释放总线,此语句必须有,参考datasheet的P15  
  82.         for(count=1;count>0;count--);  
  83.         if(RC3)  
  84.             datt|=0x80;  
  85.         for(count=23;count>0;count--);//延时60us     
  86.     }  
  87.     return datt;  
  88. }  
  89. void lcd_com(uchar com)//向LCD1602写命令  
  90. {  
  91.     rs_o;  
  92.     rw_o;  
  93.     en_o;  
  94.     TRISB=0x00;//配置RB为输出方向  
  95.     rs_l;     
  96.     rw_l;  
  97.     LCD=com;  
  98.     delayms(1);  
  99.     en_h;  
  100.     delayms(1);   
  101.     en_l;  
  102.     delayms(1);       
  103. }  
  104. void lcd_dat(uchar dat)//向LCD1602写数据  
  105. {  
  106.     rs_o;  
  107.     rw_o;  
  108.     TRISB=0x00;//配置RB为输出方向  
  109.     en_o;  
  110.     rs_h;     
  111.     rw_l;  
  112.     LCD=dat;  
  113.     delayms(1);  
  114.     en_h;  
  115.     delayms(1);  
  116.     en_l;  
  117.     delayms(1);   
  118. }  
  119. void lcd_write(uchar c,uchar r,uchar dat)//向LCD1602指定行、指定列、写数据  
  120. {  
  121.     lcd_com(0x80+0x40*c+r);  
  122.     lcd_dat(dat);  
  123.     delayms(1);  
  124. }  
  125. void lcd_init(void)//LCD1602初始化,初始化后第一行显示temperature:,第二行显示.C  
  126. {  
  127.     lcd_com(0x38);  
  128.     lcd_com(0x0c);  
  129.     lcd_com(0x06);  
  130.     lcd_write(0,2,0x54);  
  131.     lcd_write(0,3,0x65);  
  132.     lcd_write(0,4,0x6d);  
  133.     lcd_write(0,5,0x70);  
  134.     lcd_write(0,6,0x65);  
  135.     lcd_write(0,7,0x72);  
  136.     lcd_write(0,8,0x61);  
  137.     lcd_write(0,9,0x74);  
  138.     lcd_write(0,10,0x75);  
  139.     lcd_write(0,11,0x72);  
  140.     lcd_write(0,12,0x65);  
  141.     lcd_write(0,13,0x3a);  
  142.     lcd_write(1,11,0xdf);  
  143.     lcd_write(1,12,0x43);  
  144. }  
  145. void show(void)//把温度值送LCD1602显示  
  146. {  
  147.     uchar flag;  
  148.     uchar t[4];  
  149.     uint temp;  
  150.     if(dat2>=240)  
  151.     {  
  152.         dat= (~(dat2*256+dat1)+1)*(0.0625*10);//取反加一,保留一位小数  
  153.         flag=1;  
  154.     }  
  155.     else  
  156.     {  
  157.         dat=(dat2*256+dat1)*(0.0625*10);  
  158.         flag=0;  
  159.     };  
  160.     temp=dat%10;  
  161.     t[0]=(0x30+temp);  
  162.     temp=dat%100;  
  163.     temp=temp/10;  
  164.     t[1]=(0x30+temp);  
  165.     temp=dat%1000;  
  166.     temp=temp/100;  
  167.     t[2]=(0x30+temp);  
  168.     temp=dat/1000;  
  169.     t[3]=(0x30+temp);  
  170.     if(flag==1)//负温度显示  
  171.     {  
  172.         lcd_write(1,10,t[0]);  
  173.         lcd_write(1,9,0xa5);  
  174.         lcd_write(1,8,t[1]);  
  175.         lcd_write(1,7,t[2]);  
  176.         lcd_write(1,6,t[3]);  
  177.         lcd_write(1,5,0x2d);  
  178.     }  
  179.     if(flag==0)//正温度显示  
  180.     {  
  181.         lcd_write(1,10,t[0]);  
  182.         lcd_write(1,9,0xa5);  
  183.         lcd_write(1,8,t[1]);  
  184.         lcd_write(1,7,t[2]);  
  185.         lcd_write(1,6,t[3]);  
  186.         lcd_write(1,5,0x20);//显示空格,刷掉负号  
  187.     }  
  188. }  
  189. void main(void)  
  190. {  
  191.     lcd_init();  
  192.     while(1)  
  193.     {  
  194.         Ds18b20_reset();  
  195.         Ds18b20_write(0xcc);  
  196.         Ds18b20_write(0x44);//发送温度转换命令  
  197.         delayms(1000);//延时1s,等待温度转换完成  
  198.         Ds18b20_reset();  
  199.         Ds18b20_write(0xcc);  
  200.         Ds18b20_write(0xbe);//发送读温度寄存器命令  
  201.         dat1=Ds18b20_read();  
  202.         dat2=Ds18b20_read();  
  203.         show();  
  204.         led_h;//关指示灯  
  205.         delayms(2000);  
  206.     }  
  207. }  
  208. //调试总结:  
  209. //某IO口8位未全使用时,对整个IO口读取进行位运算无效  
关键字:PIC16F877A  温度DS18B20 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机RAM使用