找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机89c51+18B20+1602LCD源代码

[复制链接]
跳转到指定楼层
楼主
电路



主程序
  1. #include < reg51.h >
  2. #include < intrins.h >
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. sbit DQ = P3^3 ;  //定义DS18B20端口DQ  
  6. sbit BEEP=P3^6  ; //蜂鸣器驱动线
  7. bit presence  ;          //检测18b20是否插好
  8. sbit LCD_RS = P2^0 ;            
  9. sbit LCD_RW = P2^1 ;
  10. sbit LCD_EN = P2^2 ;
  11. uchar code  cdis1[ ] = {" Zhu Ban Wen Du "} ;
  12. uchar code  cdis2[ ] = {" WENDU:    .  C "} ;
  13. uchar code  cdis3[ ] = {" DS18B20  ERR0R "} ;
  14. uchar code  cdis4[ ] = {"  PLEASE CHECK  "} ;

  15. unsigned char data  temp_data[2] = {0x00,0x00} ;
  16. unsigned char data  display[5] =   {0x00,0x00,0x00,0x00,0x00} ;
  17. unsigned char code  ditab[16] =    {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
  18.                                                         0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} ;
  19. void beep() ;
  20. unsigned char code  mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ;

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

  22. /*******************************************************************/
  23. void delay1(int ms)
  24. {
  25. unsigned char y ;
  26.   while(ms--)
  27. {
  28.   for(y = 0 ; y<250 ; y++)
  29.   {
  30.    _nop_() ;
  31.    _nop_() ;
  32.    _nop_() ;
  33.    _nop_() ;
  34.   }
  35. }
  36. }

  37. /******************************************************************/
  38. /*检查LCD忙状态                                                   */
  39. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。   */
  40. /******************************************************************/
  41. bit lcd_busy()
  42. {                          
  43.     bit result ;
  44.     LCD_RS = 0 ;
  45.     LCD_RW = 1 ;
  46.     LCD_EN = 1 ;
  47.     delayNOP() ;
  48.     result = (bit)(P0&0x80) ;
  49.     LCD_EN = 0 ;
  50.     return(result) ;
  51. }

  52. /*写指令数据到LCD                                                  */
  53. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。          */
  54. /*******************************************************************/
  55. void lcd_wcmd(uchar cmd)
  56. {                          
  57.    while(lcd_busy()) ;
  58.     LCD_RS = 0 ;
  59.     LCD_RW = 0 ;
  60.     LCD_EN = 0 ;
  61.     _nop_() ;
  62.     _nop_() ;
  63.     P0 = cmd ;
  64.     delayNOP() ;
  65.     LCD_EN = 1 ;
  66.     delayNOP() ;
  67.     LCD_EN = 0 ;  
  68. }

  69. /*******************************************************************/
  70. /*写显示数据到LCD                            */
  71. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。       */
  72. /*******************************************************************/
  73. void lcd_wdat(uchar dat)
  74. {                          
  75.    while(lcd_busy()) ;
  76.     LCD_RS = 1 ;
  77.     LCD_RW = 0 ;
  78.     LCD_EN = 0 ;
  79.     P0 = dat ;
  80.     delayNOP() ;
  81.     LCD_EN = 1 ;
  82.     delayNOP() ;
  83.     LCD_EN = 0 ;
  84. }


  85. /*  LCD初始化设定                                                  */
  86. /*******************************************************************/
  87. void lcd_init()
  88. {
  89.     delay1(15) ;   
  90.     lcd_wcmd(0x01) ;      //清除LCD的显示内容            
  91.     lcd_wcmd(0x38) ;      //16*2显示,5*7点阵,8位数据
  92.     delay1(5) ;
  93.     lcd_wcmd(0x38) ;         
  94.     delay1(5) ;
  95.     lcd_wcmd(0x38) ;         
  96.     delay1(5) ;

  97.     lcd_wcmd(0x0c) ;      //显示开,关光标
  98.     delay1(5) ;
  99.     lcd_wcmd(0x06) ;      //移动光标
  100.     delay1(5) ;
  101.     lcd_wcmd(0x01) ;      //清除LCD的显示内容
  102.     delay1(5) ;
  103. }

  104. /*  设定显示位置                                    */
  105. /*******************************************************************/
  106. void lcd_pos(uchar pos)
  107. {                          
  108.   lcd_wcmd(pos | 0x80) ;  //数据指针=80+地址变量
  109. }

  110. /*自定义字符写入CGRAM                                   */
  111. /*******************************************************************/
  112. void  writetab()  
  113. {  
  114.     unsigned char i ;
  115.     lcd_wcmd(0x40) ;            //写CGRAM
  116.     for (i = 0 ; i< 8 ; i++)      
  117.     lcd_wdat(mytab[ i ]) ;        
  118. }

  119. /*us级延时函数                                        */
  120. /*******************************************************************/

  121. void Delay(unsigned int num)
  122. {
  123.   while( --num ) ;
  124. }

  125. /*初始化ds1820                                      */
  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 ;    //如果=0则初始化成功 =1则初始化失败
  136.      Delay(100) ;
  137.      DQ = 1 ;
  138.      
  139.      return(presence) ; //返回信号,0=presence,1= no presence
  140. }


  141. /* 读一个字节                     */
  142. /*******************************************************************/
  143. ReadOneChar(void)
  144. {
  145. unsigned char i = 0 ;
  146. unsigned char dat = 0 ;

  147. for (i = 8 ; i > 0 ; i--)
  148.   {
  149.     DQ = 0 ; // 给脉冲信号
  150.     dat >>= 1 ;
  151.     DQ = 1 ; // 给脉冲信号

  152.     if(DQ)
  153.      dat |= 0x80 ;
  154.     Delay(4) ;
  155.   }

  156.     return (dat) ;
  157. }

  158. /* 写一个字节                                         */
  159. /*******************************************************************/
  160. WriteOneChar(unsigned char dat)
  161. {
  162.   unsigned char i = 0 ;
  163.   for (i = 8 ; i > 0 ; i--)
  164.   {
  165.     DQ = 0 ;
  166.     DQ = dat&0x01 ;
  167.     Delay(5) ;

  168.     DQ = 1 ;
  169.     dat>>=1 ;
  170.   }
  171. }

  172. /* 读取温度                            */
  173. /*******************************************************************/
  174. Read_Temperature(void)
  175. {
  176.      Init_DS18B20() ;
  177.   
  178.      WriteOneChar(0xCC) ;  // 跳过读序号列号的操作
  179.      WriteOneChar(0x44) ;  // 启动温度转换

  180.      Init_DS18B20() ;
  181.      WriteOneChar(0xCC) ;  //跳过读序号列号的操作
  182.      WriteOneChar(0xBE) ;  //读取温度寄存器

  183.      temp_data[0] = ReadOneChar() ;   //温度低8位
  184.      temp_data[1] = ReadOneChar() ;   //温度高8位
  185. }

  186. /* 数据转换与温度显示                                              */
  187. /*******************************************************************/
  188. Disp_Temperature()
  189. {
  190.   display[4]=temp_data[0]&0x0f ;
  191.   display[0]=ditab[display[4]]+0x30 ;//查表得小数位的值
  192.   
  193.   display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) ;
  194.   display[3]=display[4]/100+0x30 ;
  195.   display[1]=display[4]%100 ;
  196.   display[2]=display[1]/10+0x30 ;
  197.   display[1]=display[1]%10+0x30 ;

  198.     if(display[3]==0x30)        //高位为0,不显示
  199.    {
  200.      display[3]=0x20 ;              
  201.      if(display[2]==0x30)      //次高位为0,不显示
  202.      display[2]=0x20 ;
  203.    }

  204.      lcd_pos(0x48) ;            
  205.      lcd_wdat(display[3]) ;        //百位数显示
  206.      lcd_pos(0x49) ;            
  207.      lcd_wdat(display[2]) ;        //十位数显示
  208.   lcd_pos(0x4a) ;            
  209.      lcd_wdat(display[1]) ;        //个位数显示
  210.   lcd_pos(0x4c) ;            
  211.      lcd_wdat(display[0]) ;        //小数位数显示
  212. }  

  213. /*******************************************************************/
  214. /* 蜂鸣器响一声                 */
  215. /*******************************************************************/
  216. void beep()
  217.   {
  218.     unsigned char y ;
  219.     for (y=0 ;y<100 ;y++)
  220.     {
  221.       Delay(60) ;
  222.       BEEP=!BEEP ;                //BEEP取反
  223.     }
  224.     BEEP=1 ;                      //关闭蜂鸣器
  225. Delay(40000) ;
  226.   }

  227. /* DS18B20 OK 显示菜单                                             */
  228. /*******************************************************************/
  229. void  Ok_Menu ()
  230. {
  231.     uchar  m ;
  232.     lcd_init() ;                //初始化LCD
  233.             
  234.     lcd_pos(0) ;                //设置显示位置为第一行的第1个字符
  235.      m = 0 ;
  236.     while(cdis1[m] != '\0')
  237.      {                         //显示字符
  238.        lcd_wdat(cdis1[m]) ;
  239.        m++ ;
  240.      }

  241.     lcd_pos(0x40) ;             //设置显示位置为第二行第1个字符
  242.      m = 0 ;
  243.     while(cdis2[m] != '\0')
  244.      {
  245.        lcd_wdat(cdis2[m]) ;      //显示字符
  246.        m++ ;
  247.      }

  248.      writetab() ;               //自定义字符写入CGRAM
  249.      delay1(5) ;
  250.      lcd_pos(0x4d) ;
  251.      lcd_wdat(0x00) ;          //显示自定义字符
  252. }


  253. /* DS18B20 ERROR 显示菜单                             */
  254. /*******************************************************************/
  255. void  Error_Menu ()
  256. {
  257.      uchar  m ;
  258.      lcd_init() ;                //初始化LCD

  259.     lcd_pos(0) ;                //设置显示位置为第一行的第1个字符
  260.      m = 0 ;
  261.      while(cdis3[m] != '\0')
  262.      {                         //显示字符
  263.        lcd_wdat(cdis3[m]) ;
  264.        m++ ;
  265.      }

  266.      lcd_pos(0x40) ;             //设置显示位置为第二行第1个字符
  267.      m = 0 ;
  268.      while(cdis4[m] != '\0')
  269.      {
  270.        lcd_wdat(cdis4[m]) ;      //显示字符
  271.        m++ ;
  272.      }
  273. }


  274. /* 主函数     */
  275. /************************************/
  276. void main()
  277. {
  278.      Ok_Menu () ;

  279. do
  280.   {
  281.     Read_Temperature() ; //读取温度
  282.    Disp_Temperature() ;         //显示温度
  283.      }
  284.     while(!presence)  ;

  285.      Error_Menu () ;

  286. do
  287.   {  
  288.     Init_DS18B20() ;
  289.     beep() ;
  290.      }
  291. while(presence) ;
  292. }

复制代码
INTRINS.H
  1. /*--------------------------------------------------------------------------
  2. INTRINS.H

  3. Intrinsic functions for C51.
  4. Copyright (c) 1988-2010 Keil Elektronik GmbH and ARM Germany GmbH
  5. All rights reserved.
  6. --------------------------------------------------------------------------*/

  7. #ifndef __INTRINS_H__
  8. #define __INTRINS_H__

  9. #pragma SAVE

  10. #if defined (__CX2__)
  11. #pragma FUNCTIONS(STATIC)
  12. /* intrinsic functions are reentrant, but need static attribute */
  13. #endif

  14. extern void          _nop_     (void);
  15. extern bit           _testbit_ (bit);
  16. extern unsigned char _cror_    (unsigned char, unsigned char);
  17. extern unsigned int  _iror_    (unsigned int,  unsigned char);
  18. extern unsigned long _lror_    (unsigned long, unsigned char);
  19. extern unsigned char _crol_    (unsigned char, unsigned char);
  20. extern unsigned int  _irol_    (unsigned int,  unsigned char);
  21. extern unsigned long _lrol_    (unsigned long, unsigned char);
  22. extern unsigned char _chkfloat_(float);
  23. #if defined (__CX2__)
  24. extern int           abs       (int);
  25. extern void          _illop_   (void);
  26. #endif
  27. #if !defined (__CX2__)
  28. extern void          _push_    (unsigned char _sfr);
  29. extern void          _pop_     (unsigned char _sfr);
  30. #endif

  31. #pragma RESTORE

  32. #endif

复制代码

全部资料51hei下载地址:
18B20 1602LCD温度实验.zip (35.52 KB, 下载次数: 13)

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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