找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1961|回复: 0
打印 上一主题 下一主题
收起左侧

基于单片机1602温度计实验源码

[复制链接]
跳转到指定楼层
楼主
ID:242426 发表于 2017-10-24 14:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这时我做的关于1602显示其 的相关实验。可以通过单片机读取相关的温度以及序码。
一个是关于温度显示的源代码,一个是可以切换的实验结果。

单片机源程序如下:
  1. /**********************BST-V51实验开发板例程************************

  2. *  平台:BST-V51 + Keil U3 + STC89C52
  3. *  名称:18B20实时温度计1602显示
  4. *  晶振:11.0592MHZ
  5. *  说明:免费开源,不提供源代码分析.

  6. ******************************************************************/


  7. #include <reg52.H>
  8. #include <intrins.H>
  9. #include <math.H>

  10. #define uchar unsigned char
  11. #define uint unsigned int
  12. #define  GPIO_KEY P3  //独立键盘用P1口

  13. sbit dula = P2^6;
  14. sbit wela = P2^7;
  15. sbit RW = P1^1;
  16. sbit RS = P1^0;  
  17. sbit LCD2 = P1^2;
  18. sbit LCDEN = P2^5;
  19. sbit DQ = P2^2;  //定义DS18B20端口DQ  
  20. sbit BEEP=P2^3 ; //蜂鸣器驱动线
  21. bit  presence ;
  22.         sbit K1 = P3^4;
  23.         sbit K2 = P3^5;
  24.         sbit K3 = P3^6;
  25.         sbit K4 = P3^7;
  26. uchar code  cdis1[ ] = {"   DS18B20 OK   "};
  27. uchar code  cdis2[ ] = {"                "};
  28. uchar code  cdis3[ ] = {" DS18B20  ERR0R "};
  29. uchar code  cdis4[ ] = {"  PLEASE CHECK  "};
  30. uchar code  cdis5[ ] = {"  xianzaiwendu:  "};

  31. unsigned char data  display[2] = {0x00,0x00};
  32.                                     
  33. unsigned char data  RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

  34. unsigned char Temp;
  35. unsigned char  crc;

  36. void beep();

  37. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

  38. /*******************************************************************/
  39. /*                                                                 */
  40. /*us级延时函数                                                     */
  41. /*                                                                 */
  42. /*******************************************************************/

  43. void Delay(unsigned int num)
  44. {
  45.   while( --num );
  46. }
  47.        
  48. void delayUs()
  49. {
  50.     _nop_();
  51. }

  52. void delayMs(uint a)
  53. {
  54.     uint i, j;
  55.     for(i = a; i > 0; i--)
  56.         for(j = 100; j > 0; j--);
  57. }


  58. /******************************************************************/
  59. /*                                                                */
  60. /*检查LCD忙状态                                                   */
  61. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。     */
  62. /*                                                                */
  63. /******************************************************************/

  64. bit lcd_busy()
  65. {                          
  66.     bit result;
  67.     RS = 0;
  68. //    LCD1 = 1;
  69.     LCDEN = 1;
  70.     delayNOP();
  71.     result = (bit)(P0&0x80);
  72.     LCDEN = 0;
  73.     return(result);
  74. }

  75. void writeComm(uchar comm)
  76. {
  77.      RS = 0;   
  78.     P0 = comm;
  79.     LCDEN = 1;
  80.      delayUs();
  81.     LCDEN = 0;
  82.     delayMs(1);
  83. }

  84. //写数据:RS=1, RW=0;
  85. void writeData(uchar dat)
  86. {
  87.      RS = 1;
  88.      P0 = dat;
  89.      LCDEN = 1;
  90.     delayUs();
  91.     LCDEN = 0;
  92.     delayMs(1);
  93. }

  94. /*******************************************************************/
  95. /*                                                                 */
  96. /*  LCD初始化设定                                                  */
  97. /*                                                                 */
  98. /*******************************************************************/

  99. void lcd_init()
  100. {
  101.      RW = 0;
  102.     delayMs(15);   
  103.     writeComm(0x01);      //清除LCD的显示内容
  104.             
  105.     writeComm(0x38);      //16*2显示,5*7点阵,8位数据
  106.     delayMs(5);
  107.     writeComm(0x38);         
  108.     delayMs(5);
  109.     writeComm(0x38);         
  110.     delayMs(5);

  111.     writeComm(0x0c);      //显示开,关光标
  112.     delayMs(5);
  113.     writeComm(0x06);      //移动光标
  114.     delayMs(5);
  115.     writeComm(0x01);      //清除LCD的显示内容
  116.     delayMs(5);
  117. }




  118. void init()
  119. {
  120.      RW = 0;
  121.      dula = wela = 0;
  122.     writeComm(0x38);
  123.    writeComm(0x0c);
  124.     writeComm(0x06);
  125.     writeComm(0x01);
  126. }

  127. Init_DS18B20(void)
  128. {  
  129.      DQ = 1;      //DQ复位
  130.      Delay(8);    //稍做延时

  131.      DQ = 0;      //将DQ拉低
  132.      Delay(90);   //精确延时 大于 480us

  133.      DQ = 1;       //拉高总线
  134.      Delay(8);

  135.      presence = DQ;    //读取存在信号
  136.      Delay(100);
  137.      DQ = 1;
  138.      
  139.      return(presence); //返回信号,0=presence,1= no presence
  140. }
  141. void writeString(uchar * str, uchar length)
  142. {
  143.      uchar i;
  144.     for(i = 0; i < length; i++)
  145.     {
  146.          writeData(str[i]);
  147.      }
  148. }

  149. /*******************************************************************/
  150. /*                                                                 */
  151. /*  设定显示位置                                                   */
  152. /*                                                                 */
  153. /*******************************************************************/

  154. void lcd_pos(uchar pos)
  155. {                          
  156.   writeComm(pos | 0x80);  //数据指针=80+地址变量
  157. }

  158. /**//*****************************DS18B20*******************************/
  159. void dsInit()
  160. {
  161.    
  162.     unsigned int i;  
  163.     DQ = 0;
  164.     i = 100;  
  165.      while(i>0) i--;
  166.     DQ = 1;   
  167.     i = 4;
  168.      while(i>0) i--;
  169. }

  170. void dsWait()
  171. {
  172.       unsigned int i;
  173.       while(DQ);  
  174.       while(~DQ);
  175.       i = 4;
  176.       while(i > 0) i--;
  177. }


  178. bit readBit()
  179. {
  180.     unsigned int i;
  181.     bit b;
  182.     DQ = 0;
  183.     i++;   
  184.     DQ = 1;
  185.    i++; i++;  
  186.     b = DQ;
  187.     i = 8;
  188.     while(i>0) i--;
  189.     return b;
  190. }

  191. unsigned char readByte()
  192. {
  193.     unsigned int i;
  194.     unsigned char j, dat;
  195.    dat = 0;
  196.     for(i=0; i<8; i++)
  197.     {
  198.         j = readBit();
  199.       
  200.         dat = (j << 7) | (dat >> 1);
  201.     }
  202.     return dat;
  203. }

  204. void writebit(char bitval) {
  205. DQ = 0;                                        // 将DQ 拉低开始写时间隙
  206. if(bitval==1) DQ =1;          // 如果写1,DQ 返回高电平
  207. Delay(5);                                       // 在时间隙内保持电平值,
  208. DQ = 1;                      // Delay函数每次循环延时16μs,因此delay(5) = 104μs
  209. }       

  210. void writeByte(unsigned char dat)
  211. {
  212.     unsigned int i;
  213.     unsigned char j;
  214.     bit b;
  215.     for(j = 0; j < 8; j++)
  216.     {
  217.         b = dat & 0x01;
  218.         dat >>= 1;
  219.    
  220.         if(b)   
  221.         {
  222.            DQ = 0;          i++; i++;  
  223.             DQ = 1;   
  224.             i = 8; while(i>0) i--;  
  225.         }
  226.         else  
  227.         {
  228.             DQ = 0;
  229.           i = 8; while(i>0) i--;  
  230.             DQ = 1;
  231.            i++; i++;
  232.         }
  233.    }
  234. }


  235. void sendChangeCmd()
  236. {
  237.     dsInit();   
  238.     dsWait();   
  239.     delayMs(1);   
  240.     writeByte(0xcc);
  241.     writeByte(0x44);
  242. }

  243. void sendReadCmd()
  244. {
  245.     dsInit();
  246.     dsWait();
  247.     delayMs(1);
  248.     writeByte(0xcc);
  249.     writeByte(0xbe);
  250. }


  251. int getTmpValue()
  252. {
  253.     unsigned int tmpvalue;
  254.     int value;
  255.     float t;
  256.     unsigned char low, high;
  257.     sendReadCmd();
  258.    
  259.     low = readByte();
  260.     high = readByte();
  261.    
  262.     tmpvalue = high;
  263.     tmpvalue <<= 8;
  264.     tmpvalue |= low;
  265.     value = tmpvalue;
  266.    
  267.   \
  268.     t = value * 0.0625;
  269.     \
  270.     value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
  271.     return value;
  272. }

  273. void dis(int v)
  274. {
  275.     unsigned char count;
  276.     unsigned char datas[] = {0, 0, 0, 0, 0};
  277.     unsigned int tmp = abs(v);
  278.     datas[0] = tmp / 10000;
  279.     datas[1] = tmp % 10000 / 1000;
  280.     datas[2] = tmp % 1000 / 100;
  281.     datas[3] = tmp % 100 / 10;
  282.     datas[4] = tmp % 10;
  283.     writeComm(0xc0+3);
  284.     if(v < 0)
  285.     {
  286.         writeString("- ", 2);
  287.    }
  288.     else
  289.     {
  290.        writeString("+ ", 2);
  291.     }
  292.     if(datas[0] != 0)
  293.     {
  294.         writeData('0'+datas[0]);
  295.     }
  296.     for(count = 1; count != 5; count++)
  297.     {
  298.         writeData('0'+datas[count]);
  299.         if(count == 2)
  300.         {
  301.             writeData('.');
  302.         }
  303.     }
  304. }
  305. /**//*****************************XULEIMA*******************************/
  306. void beep()
  307.   {
  308.     unsigned char y;
  309.     for (y=0;y<100;y++)
  310.     {
  311.       Delay(60);
  312.       BEEP=!BEEP;                //BEEP取反
  313.     }
  314.     BEEP=1;                      //关闭蜂鸣器
  315.         Delay(40000);
  316.   }
  317. /*******************************************************************/
  318. /*                                                                 */
  319. /* 读取64位序列码                                                  */
  320. /*                                                                 */
  321. /*******************************************************************/
  322. Read_RomCord(void)
  323. {
  324.      unsigned char j;
  325.      Init_DS18B20();
  326.   
  327.      writeByte(0x33);  // 读序列码的操作
  328.      for (j = 0; j < 8; j++)
  329.          {
  330.           RomCode[j] = readByte() ;
  331.          }
  332. }

  333. /*******************************************************************/
  334. /*                                                                 */
  335. /*DS18B20的CRC8校验程序                                            */
  336. /*                                                                 */
  337. /*******************************************************************/
  338. uchar CRC8()
  339. {
  340.    uchar i,x; uchar crcbuff;
  341.    
  342.    crc=0;
  343.    for(x = 0; x <8; x++)
  344.    {
  345.     crcbuff=RomCode[x];
  346.     for(i = 0; i < 8; i++)
  347.      {
  348.       if(((crc ^ crcbuff)&0x01)==0)
  349.       crc >>= 1;
  350.        else {
  351.               crc ^= 0x18;   //CRC=X8+X5+X4+1
  352.               crc >>= 1;
  353.               crc |= 0x80;
  354.             }         
  355.       crcbuff >>= 1;      
  356.          }
  357.    }
  358.      return crc;       
  359. }

  360. /*******************************************************************/
  361. /*                                                                 */
  362. /* 数据转换与显示                                                  */
  363. /*                                                                 */
  364. /*******************************************************************/

  365. Disp_RomCode()
  366. {
  367.    uchar j;
  368.    uchar H_num=0x40;       //LCD第二行初始位置

  369.    for(j=0;j<8;j++)
  370.    {
  371.     Temp = RomCode[j];

  372.     display[0]=((Temp&0xf0)>>4);
  373.     if(display[0]>9)
  374.      { display[0]=display[0]+0x37;}
  375.     else{display[0]=display[0]+0x30;}

  376.     lcd_pos(H_num);            
  377.     writeData(display[0]);        //高位数显示

  378.     H_num++;
  379.     display[1]=(Temp&0x0f);
  380.     if(display[1]>9)
  381.      {display[1]=display[1]+0x37;}
  382.     else {display[1]=display[1]+0x30;}

  383.     lcd_pos(H_num);            
  384.     writeData(display[1]);        //低位数显示
  385.     H_num++;
  386.    }
  387. }         

  388. /*******************************************************************/
  389. /*                                                                 */
  390. /* DS18B20 OK 显示菜单                                             */
  391. /*                                                                 */
  392. /*******************************************************************/
  393. void  Ok_Menu ()
  394. {
  395.     uchar  m;
  396.     lcd_init();                //初始化LCD
  397.             
  398.     lcd_pos(0);                //设置显示位置为第一行的第1个字符
  399.      m = 0;
  400.     while(cdis1[m] != '\0')
  401.      {                         //显示字符
  402.        writeData(cdis1[m]);
  403.        m++;
  404.      }

  405.     lcd_pos(0x40);             //设置显示位置为第二行第1个字符
  406.      m = 0;
  407.     while(cdis2[m] != '\0')
  408.      {
  409.        writeData(cdis2[m]);      //显示字符
  410.        m++;
  411.      }
  412. }

  413. /*******************************************************************/
  414. /*                                                                 */
  415. /* DS18B20 ERROR 显示菜单                                          */
  416. /*                                                                 */
  417. /*******************************************************************/
  418. void  Error_Menu ()
  419. {
  420.      uchar  m;
  421.      lcd_init();                //初始化LCD
  422.        
  423.            lcd_pos(0);                //设置显示位置为第一行的第1个字符
  424.      m = 0;
  425.      while(cdis3[m] != '\0')
  426.      {                         //显示字符
  427.        writeData(cdis3[m]);
  428.        m++;
  429.      }

  430.      lcd_pos(0x40);             //设置显示位置为第二行第1个字符
  431.      m = 0;
  432.      while(cdis4[m] != '\0')
  433.      {
  434.        writeData(cdis4[m]);      //显示字符
  435.        m++;
  436.      }
  437. }


  438. /**//*****************************DS18B20*******************************/
  439. void display64()
  440. {
  441.         P0 = 0xff;
  442.   P2 = 0xff;

  443.    //while(1)
  444.   //{
  445.      Ok_Menu ();
  446.      Read_RomCord();    //读取64位序列码
  447.      CRC8();            //CRC效验
  448.      if(crc==0)         //CRC效验正确
  449.          {
  450.           Disp_RomCode();        //显示64位序列码
  451.    }
  452.      
  453.   //}
  454. }


  455. void main()
  456. {
  457.         int max;
  458.        
  459.    while(1)
  460.         {
  461.          if(K4==0)
  462.         {
  463.                 delayMs(10);
  464.                 if(K4==0)
  465.                 {
  466.                         writeComm(0x01);
  467.                         display64();
  468.                        
  469.                 }
  470.   }       
  471.                 if(K1==0)
  472.         {
  473.                 delayMs(10);
  474.                 if(K1==0)
  475.                 {
  476.                         writeComm(0x01);
  477.                         while(K4!=0)
  478.                        
  479.       {
  480.                                 init();
  481.                                 writeString(cdis5, 16);
  482.                                 delayMs(1000); //温度转换时间需要750ms以上
  483.         writeComm(0xc0);
  484.         dis(getTmpValue());
  485.                               if(max>2800)
  486.                                 {
  487. ……………………

  488. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
实验.rar (112.22 KB, 下载次数: 7)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表