简易电子温度计
用极少的元件 做一个温度计
不需要外部晶振 可以用两个3V纽扣电池驱动
温度传感器采用LM75数字式 体积小 功耗低
对于初学者很适合制作
电路图
液晶引脚图
单片机源程序如下:
- /*********************************************************************************************
- 程序名:电子温度计源程序
- 1-201006062315 驱动了模块并加入时间设置程序,用超级终端显示并设置。
- 2-201007080143 完成常显示省电方式的温度计功能,采用空闲方式。每1分钟更新一次温度。
- /*********************************************************************************************
- 说明:
- 模块接口定义在VIIC_C51.C文件里面修改。修改接口时需要注意把相应I/O接口设置为推挽方式。
- 否则就需要在I2C总线上各加2.2K欧上拉电阻。
- - 每1分钟左右更新一次温度数据
- - 采用单片机空闲模式,LM75掉电模式。
- ----------------------------------------
- /*********************************************************************************************/
- #include <STC12C5A60S2.H> //STC头文件
- #include <string.h>
- #include <intrins.h> //51基本运算(包括_nop_空函数)
- bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
- bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
- bit LM75_N;//温度值的符号(0正1负)
- unsigned char LM75_T,LM75_P;//温度值的整数,小数值(十进制,小数值2位,精度0.125中的前两位)
- unsigned char d1=0,d2=0,d3=0;
- bit m;
- unsigned int cou;
- unsigned char menu=0;
- /*********************************************************************************************/
- //“程序开发调试设置项”
- #define LM75A_ADD 0x9E // LM75A的I2C地址(1001 A2 A1 A0 W/R)(模块专用地址,禁止修改)
- sbit DY_LCD_COM =P1 ^ 4; //设置LCD连接的I/O口(LCD公共端)
- sbit DY_LCD1_L1 =P0 ^ 5; //设置LCD连接的I/O口a
- sbit DY_LCD1_L2 =P0 ^ 6; //设置LCD连接的I/O口b
- sbit DY_LCD1_L3 =P1 ^ 7; //设置LCD连接的I/O口c
- sbit DY_LCD1_L4 =P1 ^ 6; //设置LCD连接的I/O口d
- sbit DY_LCD1_L5 =P1 ^ 5; //设置LCD连接的I/O口e
- sbit DY_LCD1_L6 =P0 ^ 4; //设置LCD连接的I/O口f
- sbit DY_LCD1_L7 =P0 ^ 3; //设置LCD连接的I/O口g
- sbit DY_LCD1_L8 =P4 ^ 7; //设置LCD连接的I/O口dp
- sbit DY_LCD2_L1 =P4 ^ 5; //设置LCD连接的I/O口a
- sbit DY_LCD2_L2 =P4 ^ 4; //设置LCD连接的I/O口b
- sbit DY_LCD2_L3 =P3 ^ 2; //设置LCD连接的I/O口c
- sbit DY_LCD2_L4 =P3 ^ 1; //设置LCD连接的I/O口d
- sbit DY_LCD2_L5 =P3 ^ 0; //设置LCD连接的I/O口e
- sbit DY_LCD2_L6 =P4 ^ 6; //设置LCD连接的I/O口f
- sbit DY_LCD2_L7 =P0 ^ 7; //设置LCD连接的I/O口g
- sbit DY_LCD2_L8 =P3 ^ 3; //设置LCD连接的I/O口dp
- sbit DY_LCD3_L1 =P2 ^ 5; //设置LCD连接的I/O口a
- sbit DY_LCD3_L2 =P2 ^ 4; //设置LCD连接的I/O口b
- sbit DY_LCD3_L3 =P3 ^ 6; //设置LCD连接的I/O口c
- sbit DY_LCD3_L4 =P3 ^ 5; //设置LCD连接的I/O口d
- sbit DY_LCD3_L5 =P3 ^ 4; //设置LCD连接的I/O口e
- sbit DY_LCD3_L6 =P2 ^ 6; //设置LCD连接的I/O口f
- sbit DY_LCD3_L7 =P2 ^ 7; //设置LCD连接的I/O口g
- unsigned char code disdata[]={
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00//无小数点数码管段码表(0~9,无)
- };
- /*********************************************************************************************/
- void DELAY_MS (unsigned int a){ // 1ms延时程序(12MHz 10倍于51单片机速度时)
- unsigned int i;
- while( --a != 0){
- for(i = 0; i < 600; i++);
- }
- }
- /*********************************************************************************************/
- void display_LCD (){ //LCD液晶片交流驱动程序
- unsigned char i;
- m = ~m;//产生交流驱动
- DY_LCD_COM = ~m;//将交流状态给COM
- i = d1 & 0x01;if(i == 0x01){DY_LCD1_L1 = m;}else{DY_LCD1_L1 = ~m;}
- i = d1 & 0x02;if(i == 0x02){DY_LCD1_L2 = m;}else{DY_LCD1_L2 = ~m;}
- i = d1 & 0x04;if(i == 0x04){DY_LCD1_L3 = m;}else{DY_LCD1_L3 = ~m;}
- i = d1 & 0x08;if(i == 0x08){DY_LCD1_L4 = m;}else{DY_LCD1_L4 = ~m;}
- i = d1 & 0x10;if(i == 0x10){DY_LCD1_L5 = m;}else{DY_LCD1_L5 = ~m;}
- i = d1 & 0x20;if(i == 0x20){DY_LCD1_L6 = m;}else{DY_LCD1_L6 = ~m;}
- i = d1 & 0x40;if(i == 0x40){DY_LCD1_L7 = m;}else{DY_LCD1_L7 = ~m;}
- i = d1 & 0x80;if(i == 0x80){DY_LCD1_L8 = m;}else{DY_LCD1_L8 = ~m;}
- i = d2 & 0x01;if(i == 0x01){DY_LCD2_L1 = m;}else{DY_LCD2_L1 = ~m;}
- i = d2 & 0x02;if(i == 0x02){DY_LCD2_L2 = m;}else{DY_LCD2_L2 = ~m;}
- i = d2 & 0x04;if(i == 0x04){DY_LCD2_L3 = m;}else{DY_LCD2_L3 = ~m;}
- i = d2 & 0x08;if(i == 0x08){DY_LCD2_L4 = m;}else{DY_LCD2_L4 = ~m;}
- i = d2 & 0x10;if(i == 0x10){DY_LCD2_L5 = m;}else{DY_LCD2_L5 = ~m;}
- i = d2 & 0x20;if(i == 0x20){DY_LCD2_L6 = m;}else{DY_LCD2_L6 = ~m;}
- i = d2 & 0x40;if(i == 0x40){DY_LCD2_L7 = m;}else{DY_LCD2_L7 = ~m;}
- i = d2 & 0x80;if(i == 0x80){DY_LCD2_L8 = m;}else{DY_LCD2_L8 = ~m;}
- i = d3 & 0x01;if(i == 0x01){DY_LCD3_L1 = m;}else{DY_LCD3_L1 = ~m;}
- i = d3 & 0x02;if(i == 0x02){DY_LCD3_L2 = m;}else{DY_LCD3_L2 = ~m;}
- i = d3 & 0x04;if(i == 0x04){DY_LCD3_L3 = m;}else{DY_LCD3_L3 = ~m;}
- i = d3 & 0x08;if(i == 0x08){DY_LCD3_L4 = m;}else{DY_LCD3_L4 = ~m;}
- i = d3 & 0x10;if(i == 0x10){DY_LCD3_L5 = m;}else{DY_LCD3_L5 = ~m;}
- i = d3 & 0x20;if(i == 0x20){DY_LCD3_L6 = m;}else{DY_LCD3_L6 = ~m;}
- i = d3 & 0x40;if(i == 0x40){DY_LCD3_L7 = m;}else{DY_LCD3_L7 = ~m;}
- //i = d3 & 0x80;if(i == 0x80){DY_LCD3_L8 = m;}else{DY_LCD3_L8 = ~m;}
- //DELAY_MS(10);
- }
- /*********************************************************************************************
- 函数名:读出LM75A的温度值(-55~125摄氏度)
- 调 用:LM75A_GetTemp();
- 参 数:无
- 返回值:无
- 结 果:将温度数据写入3个LM75的全局变量
- 备 注:需要3个全局变量(bit LM75_N;//0正1负 unsigned char LM75_T,LM75_P;//整数,小数值十进制)
- /**********************************************************************************************/
- void LM75A_GetTemp(void){
- unsigned char buf[2]; //温度值储存
- unsigned char t=0,a=0;
- IRcvStr(LM75A_ADD,0x00,buf,2); //读出温度值(器件地址,子地址,数据储存器,字节数)
- t = buf[0]; //处理温度整数部分,0~125度
- LM75_N = 0; //温度值为正值
- if(t & 0x80){ //判断温度是否是负极(MSB表示温度符号)
- LM75_N = 1; //温度值为负值
- t = ~t; t++; //计算补码(原码取反后加1)
- }
- if(t & 0x01){ a=a+1; } //从高到低按位加入温度积加值(0~125)
- if(t & 0x02){ a=a+2; }
- if(t & 0x04){ a=a+4; }
- if(t & 0x08){ a=a+8; }
- if(t & 0x10){ a=a+16; }
- if(t & 0x20){ a=a+32; }
- if(t & 0x40){ a=a+64; }
- LM75_T = a;
- a = 0;
- t = buf[1]; //处理小数部分,取0.125精度的前2位(12、25、37、50、62、75、87)
- if(t & 0x20){ a=a+12; }
- if(t & 0x40){ a=a+25; }
- if(t & 0x80){ a=a+50; }
- LM75_P = a;
- }
- /**********************************************************************************************/
- /*********************************************************************************************
- 函数名:定时/计数器初始化函数
- 调 用:T_C_init();
- 参 数:无
- 返回值:无
- 结 果:设置SFR中T/C1和(或)T/C0相关参数
- 备 注:本函数控制T/C1和T/C0,不需要使用的部分可用//屏蔽
- /**********************************************************************************************/
- void T_C_init (void){
- TMOD = 0x11; //高4位控制T/C1 [ GATE,C/T,M1,M0,GATE,C/T,M1,M0 ]
- EA = 1; //中断总开关
- TH0 = 0; //16位计数寄存器T0高8位
- TL0 = 0; //16位计数寄存器T0低8位
- ET0 = 1; //T/C0中断开关
- TR0 = 1; //T/C0启动开关
- }
- /**********************************************************************************************/
- /**********************************************************************************************/
- void UD (void){ //数据刷新程序
- LM75A_GetTemp();//读温度
- if(LM75_N == 0){//当温度为正值时
- d1 = disdata[LM75_T/10];
- d2 = disdata[LM75_T%10]+0x80;//0x80为显示小数点
- d3 = disdata[LM75_P/10];
- }else{
- d1 = 0x40;//显示负号
- d2 = disdata[LM75_T/10];
- d3 = disdata[LM75_T%10];
- }
- }
- /**********************************************************************************************/
- void LM75_ON (void){//LM75芯片进入工作模式
- unsigned char a;
- unsigned char c[] = {0x00}; //温度值储存
- a=ISendStr(LM75A_ADD,0x01,c,1); //(器件地址,子地址,数据储存器,字节数)
- }
- /**********************************************************************************************/
- void LM75_OFF (void){//LM75芯片进入掉电模式
- unsigned char a;
- unsigned char b[] = {0x01}; //温度值储存
- a=ISendStr(LM75A_ADD,0x01,b,1); //(器件地址,子地址,数据储存器,字节数)
- }
- /**********************************************************************************************/
- void main (void){ //主程序
- P4SW = 0xFF;
- P0M0 = 0x00;//强推输出
- P2M0 = 0x0e;//强推输出 0000 1110
- P1M0 = 0x00;//强推输出//修改IIC总线接口时需要注意把相应I/O接口设置为推挽方式。
- P0 = 0xff;
- P1 = 0xff;
- P2 = 0xfe;//P2.0应为0,LM75的负极
- P3 = 0xff;
- P4 = 0xff;
- DELAY_MS(200);//LM75上电转换需要100mS
- T_C_init();//定时时初始
- UD();//更新一次温度数据
- while (1){
- if(menu == 0){//进入掉电模式程序块
- if(cou == 990){//提前一段时间打开LM75电源
- LM75_ON();//
- }
- PCON = 0x01;//进入空闲模式
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- }
- if(menu == 1){//每分钟一次温度读取程序块
- UD();//更新温度数据
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
附件.rar
(4.92 KB, 下载次数: 54)
|