单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1015|回复: 4
收起左侧

单片机+LM75简易电子温度计源程序

[复制链接]
zhouwei0815 发表于 2018-12-3 14:55 | 显示全部楼层 |阅读模式
简易电子温度计
用极少的元件 做一个温度计
不需要外部晶振  可以用两个3V纽扣电池驱动
温度传感器采用LM75数字式 体积小 功耗低
对于初学者很适合制作

电路图

电路图

液晶引脚图

液晶引脚图


单片机源程序如下:
  1. /*********************************************************************************************
  2. 程序名:电子温度计源程序

  3. 1-201006062315 驱动了模块并加入时间设置程序,用超级终端显示并设置。
  4. 2-201007080143 完成常显示省电方式的温度计功能,采用空闲方式。每1分钟更新一次温度。
  5. /*********************************************************************************************
  6. 说明:
  7. 模块接口定义在VIIC_C51.C文件里面修改。修改接口时需要注意把相应I/O接口设置为推挽方式。
  8. 否则就需要在I2C总线上各加2.2K欧上拉电阻。
  9. - 每1分钟左右更新一次温度数据
  10. - 采用单片机空闲模式,LM75掉电模式。
  11. ----------------------------------------
  12. /*********************************************************************************************/
  13. #include <STC12C5A60S2.H> //STC头文件
  14. #include <string.h>
  15. #include <intrins.h>        //51基本运算(包括_nop_空函数)
  16. bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
  17. bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
  18. bit LM75_N;//温度值的符号(0正1负)
  19. unsigned char LM75_T,LM75_P;//温度值的整数,小数值(十进制,小数值2位,精度0.125中的前两位)
  20. unsigned char d1=0,d2=0,d3=0;
  21. bit m;
  22. unsigned int cou;
  23. unsigned char menu=0;
  24. /*********************************************************************************************/
  25. //“程序开发调试设置项”
  26. #define LM75A_ADD                 0x9E  // LM75A的I2C地址(1001 A2 A1 A0 W/R)(模块专用地址,禁止修改)

  27. sbit        DY_LCD_COM        =P1 ^ 4; //设置LCD连接的I/O口(LCD公共端)
  28. sbit        DY_LCD1_L1        =P0 ^ 5; //设置LCD连接的I/O口a
  29. sbit        DY_LCD1_L2        =P0 ^ 6; //设置LCD连接的I/O口b
  30. sbit        DY_LCD1_L3        =P1 ^ 7; //设置LCD连接的I/O口c
  31. sbit        DY_LCD1_L4        =P1 ^ 6; //设置LCD连接的I/O口d
  32. sbit        DY_LCD1_L5        =P1 ^ 5; //设置LCD连接的I/O口e
  33. sbit        DY_LCD1_L6        =P0 ^ 4; //设置LCD连接的I/O口f
  34. sbit        DY_LCD1_L7        =P0 ^ 3; //设置LCD连接的I/O口g
  35. sbit        DY_LCD1_L8        =P4 ^ 7; //设置LCD连接的I/O口dp
  36. sbit        DY_LCD2_L1        =P4 ^ 5; //设置LCD连接的I/O口a
  37. sbit        DY_LCD2_L2        =P4 ^ 4; //设置LCD连接的I/O口b
  38. sbit        DY_LCD2_L3        =P3 ^ 2; //设置LCD连接的I/O口c
  39. sbit        DY_LCD2_L4        =P3 ^ 1; //设置LCD连接的I/O口d
  40. sbit        DY_LCD2_L5        =P3 ^ 0; //设置LCD连接的I/O口e
  41. sbit        DY_LCD2_L6        =P4 ^ 6; //设置LCD连接的I/O口f
  42. sbit        DY_LCD2_L7        =P0 ^ 7; //设置LCD连接的I/O口g
  43. sbit        DY_LCD2_L8        =P3 ^ 3; //设置LCD连接的I/O口dp
  44. sbit        DY_LCD3_L1        =P2 ^ 5; //设置LCD连接的I/O口a
  45. sbit        DY_LCD3_L2        =P2 ^ 4; //设置LCD连接的I/O口b
  46. sbit        DY_LCD3_L3        =P3 ^ 6; //设置LCD连接的I/O口c
  47. sbit        DY_LCD3_L4        =P3 ^ 5; //设置LCD连接的I/O口d
  48. sbit        DY_LCD3_L5        =P3 ^ 4; //设置LCD连接的I/O口e
  49. sbit        DY_LCD3_L6        =P2 ^ 6; //设置LCD连接的I/O口f
  50. sbit        DY_LCD3_L7        =P2 ^ 7; //设置LCD连接的I/O口g
  51. unsigned char code disdata[]={
  52. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00//无小数点数码管段码表(0~9,无)
  53. };
  54. /*********************************************************************************************/
  55. void DELAY_MS (unsigned int a){ // 1ms延时程序(12MHz 10倍于51单片机速度时)
  56.         unsigned int i;
  57.         while( --a != 0){
  58.                 for(i = 0; i < 600; i++);
  59.         }                                     
  60. }
  61. /*********************************************************************************************/
  62. void display_LCD (){ //LCD液晶片交流驱动程序
  63.         unsigned char i;
  64.         m = ~m;//产生交流驱动
  65.         DY_LCD_COM = ~m;//将交流状态给COM
  66.         i = d1 & 0x01;if(i == 0x01){DY_LCD1_L1 = m;}else{DY_LCD1_L1 = ~m;}
  67.         i = d1 & 0x02;if(i == 0x02){DY_LCD1_L2 = m;}else{DY_LCD1_L2 = ~m;}
  68.         i = d1 & 0x04;if(i == 0x04){DY_LCD1_L3 = m;}else{DY_LCD1_L3 = ~m;}
  69.         i = d1 & 0x08;if(i == 0x08){DY_LCD1_L4 = m;}else{DY_LCD1_L4 = ~m;}
  70.         i = d1 & 0x10;if(i == 0x10){DY_LCD1_L5 = m;}else{DY_LCD1_L5 = ~m;}
  71.         i = d1 & 0x20;if(i == 0x20){DY_LCD1_L6 = m;}else{DY_LCD1_L6 = ~m;}
  72.         i = d1 & 0x40;if(i == 0x40){DY_LCD1_L7 = m;}else{DY_LCD1_L7 = ~m;}
  73.         i = d1 & 0x80;if(i == 0x80){DY_LCD1_L8 = m;}else{DY_LCD1_L8 = ~m;}

  74.         i = d2 & 0x01;if(i == 0x01){DY_LCD2_L1 = m;}else{DY_LCD2_L1 = ~m;}
  75.         i = d2 & 0x02;if(i == 0x02){DY_LCD2_L2 = m;}else{DY_LCD2_L2 = ~m;}
  76.         i = d2 & 0x04;if(i == 0x04){DY_LCD2_L3 = m;}else{DY_LCD2_L3 = ~m;}
  77.         i = d2 & 0x08;if(i == 0x08){DY_LCD2_L4 = m;}else{DY_LCD2_L4 = ~m;}
  78.         i = d2 & 0x10;if(i == 0x10){DY_LCD2_L5 = m;}else{DY_LCD2_L5 = ~m;}
  79.         i = d2 & 0x20;if(i == 0x20){DY_LCD2_L6 = m;}else{DY_LCD2_L6 = ~m;}
  80.         i = d2 & 0x40;if(i == 0x40){DY_LCD2_L7 = m;}else{DY_LCD2_L7 = ~m;}
  81.         i = d2 & 0x80;if(i == 0x80){DY_LCD2_L8 = m;}else{DY_LCD2_L8 = ~m;}

  82.         i = d3 & 0x01;if(i == 0x01){DY_LCD3_L1 = m;}else{DY_LCD3_L1 = ~m;}
  83.         i = d3 & 0x02;if(i == 0x02){DY_LCD3_L2 = m;}else{DY_LCD3_L2 = ~m;}
  84.         i = d3 & 0x04;if(i == 0x04){DY_LCD3_L3 = m;}else{DY_LCD3_L3 = ~m;}
  85.         i = d3 & 0x08;if(i == 0x08){DY_LCD3_L4 = m;}else{DY_LCD3_L4 = ~m;}
  86.         i = d3 & 0x10;if(i == 0x10){DY_LCD3_L5 = m;}else{DY_LCD3_L5 = ~m;}
  87.         i = d3 & 0x20;if(i == 0x20){DY_LCD3_L6 = m;}else{DY_LCD3_L6 = ~m;}
  88.         i = d3 & 0x40;if(i == 0x40){DY_LCD3_L7 = m;}else{DY_LCD3_L7 = ~m;}
  89.         //i = d3 & 0x80;if(i == 0x80){DY_LCD3_L8 = m;}else{DY_LCD3_L8 = ~m;}
  90.         //DELAY_MS(10);
  91. }
  92. /*********************************************************************************************
  93. 函数名:读出LM75A的温度值(-55~125摄氏度)
  94. 调  用:LM75A_GetTemp();
  95. 参  数:无
  96. 返回值:无
  97. 结  果:将温度数据写入3个LM75的全局变量
  98. 备  注:需要3个全局变量(bit LM75_N;//0正1负 unsigned char LM75_T,LM75_P;//整数,小数值十进制)
  99. /**********************************************************************************************/
  100. void LM75A_GetTemp(void){   
  101.     unsigned char buf[2]; //温度值储存   
  102.     unsigned char t=0,a=0;   
  103.     IRcvStr(LM75A_ADD,0x00,buf,2); //读出温度值(器件地址,子地址,数据储存器,字节数)
  104.         t = buf[0]; //处理温度整数部分,0~125度
  105.         LM75_N = 0; //温度值为正值
  106.         if(t & 0x80){ //判断温度是否是负极(MSB表示温度符号)
  107.                 LM75_N = 1; //温度值为负值
  108.                 t = ~t; t++; //计算补码(原码取反后加1)
  109.         }
  110.         if(t & 0x01){ a=a+1; } //从高到低按位加入温度积加值(0~125)
  111.         if(t & 0x02){ a=a+2; }
  112.         if(t & 0x04){ a=a+4; }
  113.         if(t & 0x08){ a=a+8; }
  114.         if(t & 0x10){ a=a+16; }
  115.         if(t & 0x20){ a=a+32; }
  116.         if(t & 0x40){ a=a+64; }
  117.         LM75_T = a;
  118.         a = 0;
  119.         t = buf[1]; //处理小数部分,取0.125精度的前2位(12、25、37、50、62、75、87)
  120.         if(t & 0x20){ a=a+12; }
  121.         if(t & 0x40){ a=a+25; }
  122.         if(t & 0x80){ a=a+50; }
  123.         LM75_P = a;   
  124. }
  125. /**********************************************************************************************/
  126. /*********************************************************************************************
  127. 函数名:定时/计数器初始化函数
  128. 调  用:T_C_init();
  129. 参  数:无
  130. 返回值:无
  131. 结  果:设置SFR中T/C1和(或)T/C0相关参数
  132. 备  注:本函数控制T/C1和T/C0,不需要使用的部分可用//屏蔽
  133. /**********************************************************************************************/
  134. void T_C_init (void){
  135.         TMOD = 0x11; //高4位控制T/C1 [ GATE,C/T,M1,M0,GATE,C/T,M1,M0 ]
  136.         EA = 1;        //中断总开关
  137.         TH0 = 0; //16位计数寄存器T0高8位
  138.         TL0 = 0; //16位计数寄存器T0低8位
  139.         ET0 = 1; //T/C0中断开关
  140.         TR0 = 1; //T/C0启动开关
  141. }
  142. /**********************************************************************************************/
  143. /**********************************************************************************************/
  144. void UD (void){        //数据刷新程序
  145.         LM75A_GetTemp();//读温度
  146.         if(LM75_N == 0){//当温度为正值时
  147.                 d1 = disdata[LM75_T/10];
  148.                 d2 = disdata[LM75_T%10]+0x80;//0x80为显示小数点
  149.                 d3 = disdata[LM75_P/10];
  150.         }else{
  151.                 d1 = 0x40;//显示负号
  152.                 d2 = disdata[LM75_T/10];
  153.                 d3 = disdata[LM75_T%10];
  154.         }
  155. }
  156. /**********************************************************************************************/
  157. void LM75_ON (void){//LM75芯片进入工作模式
  158.         unsigned char a;
  159.         unsigned char c[] = {0x00}; //温度值储存  
  160.         a=ISendStr(LM75A_ADD,0x01,c,1); //(器件地址,子地址,数据储存器,字节数)
  161. }
  162. /**********************************************************************************************/
  163. void LM75_OFF (void){//LM75芯片进入掉电模式
  164.         unsigned char a;
  165.         unsigned char b[] = {0x01}; //温度值储存  
  166.         a=ISendStr(LM75A_ADD,0x01,b,1); //(器件地址,子地址,数据储存器,字节数)
  167. }
  168. /**********************************************************************************************/       
  169. void main (void){ //主程序
  170.         P4SW = 0xFF;
  171.         P0M0 = 0x00;//强推输出
  172.         P2M0 = 0x0e;//强推输出 0000 1110
  173.         P1M0 = 0x00;//强推输出//修改IIC总线接口时需要注意把相应I/O接口设置为推挽方式。
  174.         P0 = 0xff;
  175.         P1 = 0xff;
  176.         P2 = 0xfe;//P2.0应为0,LM75的负极
  177.         P3 = 0xff;
  178.         P4 = 0xff;
  179.         DELAY_MS(200);//LM75上电转换需要100mS
  180.         T_C_init();//定时时初始
  181.         UD();//更新一次温度数据
  182.         while (1){
  183.                 if(menu == 0){//进入掉电模式程序块
  184.                         if(cou == 990){//提前一段时间打开LM75电源
  185.                                 LM75_ON();//
  186.                         }
  187.                         PCON = 0x01;//进入空闲模式
  188.                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  189.                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  190.                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  191.                 }
  192.                 if(menu == 1){//每分钟一次温度读取程序块                       
  193.                         UD();//更新温度数据
  194. ……………………

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

所有资料51hei提供下载:
附件.rar (4.92 KB, 下载次数: 10)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ljl132 发表于 2019-5-19 21:10 | 显示全部楼层
请问有原理图之类的吗
回复

使用道具 举报

ljl132 发表于 2019-5-19 21:10 | 显示全部楼层
有原理图么
回复

使用道具 举报

 楼主| zhouwei0815 发表于 2019-5-22 10:55 | 显示全部楼层
ljl132 发表于 2019-5-19 21:10
请问有原理图之类的吗

第一张图就是原理图  看引脚就可以了
回复

使用道具 举报

 楼主| zhouwei0815 发表于 2019-5-22 10:56 | 显示全部楼层

第一张图  看引脚 把线连上就出来了
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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