1、系统工作原理 TC72温度数字传感器能够读取从-55℃至+125℃范围内的温度,可用于连续温度转换模式或单次转换模式。连续温度转换模式每隔约150ms测量温度并将温度存储在温度寄存器中。相反,单次转换模式只进行单次温度测量,然后转换到节能的关断模式。该传感器具有的串行接口能够与主控制器或其它外设通信。TC72接口兼容SPI协议。TC72不需要额外的外部元器件。 本系统以MCS-51系列单片机为核心器件,组成一个温度传感器,采用数字温度传感器TC72为检测器件,进行单点温度检测,检测精度为±0.5摄氏度。温度显示采用LCD1602显示,两位整数,一位小数。 2、系统硬件原理图 图1.系统硬件原理图
3、程序流程图 采用AT89C51单片机作为控制核心对温度传感器TC72控制,读取温度信号并进行计算处理,并送到液晶显示器LCD1602显示。 按照系统设计功能的要求,确定系统由3个模块组成:主控制器、测温电路和显示电路。程序设计流程图如下:
图2.程序流程图 4、程序清单 系统程序主要包括主程序、读出温度子程序、温度转换子程序、计算温度子程序、显示程序、延时程序等等。主程序主要功能是完成TC72的初始化工作,并进行读温度,将温度转化成为字符型数据并在显示器上显示传感器所测得的实际温度。读出温度子程序的主要功能是读出RAM中的9字节,在读出时需要进行CRC校验,校验有错时不进行温度数据的改写。
5、Proteus仿真调试结果及分析
PROTEUS 是单片机课堂教学的先进助手。PROTEUS不仅可以将许多单片机实例功能形象化,也可将许多单片机实例运行过程形象化。前者可在相当程度上得到实物演示实验的效果,后者则是实物演示实验难以达到的效果。它的元器件、连接线路等却和传统的单片机实验硬件高度对应。这在相当程度上替代了传统的单片机实验教学的功能,例:元器件选择、电路连接、电路检测、电路修改、软件调试、运行结果等。 在PROTEUS绘制好原理图后,调入已编译好的目标代码文件:*.HEX,可以在PROTEUS的原理图中看到模拟的实物运行状态和过程。 SPI接口TC72温度传感器应用测试课题仿真调试结果如下: 第一步:编写C语言程序,编译成功0 error;0 warning;并生成HEX文件; 第二步:绘制仿真图,检查无误,导入HEX文件,运行结果:LCD亮但不显示TC72温度传感器温度; 第三步:检查源程序及仿真图,无法发现错误; 第四步:咨询老师,经检查缺少LCD1602液晶显示屏控制与显示程序; 第五步:修改程序即在已建工程中新建并编写LCD1602液晶显示屏控制与显示程序,编译成功,生成HEX文件,导入Proteus仿真图运行成功 第六步:送老师检查通过。 图3.仿真结果图 元件清单 - //-----------------------------------------------------------------
- // 名称: SPI接口温度传感器TC72应用测试
- //-----------------------------------------------------------------
- // 说明: 本例运行时,单片机将持续从TC72传感器读取温度数据并转换为
- // 浮点型字符串送LCD显示(内置SPI接口需要在实物电路测试)
- //
- //-----------------------------------------------------------------
- #include <REG51.H>
- #include <intrins.h>
- #include <stdio.h>
- #include <math.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- //SPI使能与禁用(注意TC72是高电平使能,低电平禁用)
- #define SPI_EN() P1 |= (1<<4)
- #define SPI_DI() P1 &= ~(1<<4)
- //TC72寄存器地址定义
- #define TC72_CTRL 0x80 //控制寄存器
- #define TC72_TEMP_LSB 0x01 //温度低字节
- #define TC72_TEMP_MSB 0x02 //温度高字节
- #define TC72_MANU_ID 0x03 //制造商ID
- //SPI接口引脚定义(模拟方式)
- sbit SCK = P3^4; //串行时钟
- sbit CE = P3^5; //片选
- sbit SDI = P3^6; //串行数据输入
- sbit SDO = P3^7; //串行数据输出
- //内置SPI寄存器及寄存器位定义
- //SPCON C3h SPI Control SPR2 SPEN SSDIS MSTR CPOL CPHA SPR1 SPR0
- //SPSTA C4h SPI Status SPIF WCOL SSERR MODF - - - -
- //SPDAT C5h SPI Data SPD7 SPD6 SPD5 SPD4 SPD3 SPD2 SPD1 SPD0
- sfr SPCON = 0xC3;
- sfr SPSTA = 0xC4;
- sfr SPDAT = 0xC5;
- extern void Initialize_LCD();
- extern void LCD_ShowString(INT8U r, INT8U c,INT8U *str);
- extern void delay_ms(INT16U x);
- INT8U T[2]; //两字节原始温度数据
- float TempX = 0.0; //浮点温度值
- //-----------------------------------------------------------------
- // SPI主机初始化
- //-----------------------------------------------------------------
- void SPI_MasterInit()
- {
- SPCON=0xD0;
- SPSTA=0xC0;
- }
-
- //-----------------------------------------------------------------
- // SPI数据传输
- //-----------------------------------------------------------------
- INT8U SPI_SendData(INT8U dat)
-
- {
- SPDAT=dat;
- while((SPSTA&0x80)==0x00);
- SPSTA=0xC0;
- return SPDAT;
- }
- //-----------------------------------------------------------------
- // 从当前地址读取一字节数据(模拟方式)
- //-----------------------------------------------------------------
- INT8U ReadByte()
- {
- INT8U i,d=0x00;
- for(i=0;i<8;i++)
- {
- SCK=1;SCK=0;d=(d<<1)|SDO;
- }
- return d;
- }
- //-----------------------------------------------------------------
- // 向当前地址写入一字节数据(模拟方式)
- //-----------------------------------------------------------------
- void WriteByte(INT8U dat)
- {
- INT8U i;
- for(i=0;i<8;i++)
- { dat<<=1;SDI=CY;
- SCK=0;SCK=1;
- }
- }
- //-----------------------------------------------------------------
- // 向TC72写入两字节(地址,数据)(模拟方式)
- //-----------------------------------------------------------------
- void Write_TC72(INT8U addr, INT8U dat)
- {
- CE=1;
- WriteByte(addr);
- WriteByte(dat);
- CE=0;
- }
- //-----------------------------------------------------------------
- // 写TC72配置数据
- //-----------------------------------------------------------------
- void Config_TC72()
- {
- Write_TC72(TC72_CTRL,0x15);
- }
- //-----------------------------------------------------------------
- // 从TC72读取两字节温度数据并转换为浮点温度值
- //-----------------------------------------------------------------
- void Read_TC72_Temperature()
- {
- Config_TC72();
- delay_ms(20);
- CE=1;
- WriteByte(TC72_TEMP_MSB);
- T[1]=ReadByte();
- T[0]=ReadByte();
- CE=0;
- TempX=(((int)((T[1]<<8)|T[0]))>>6)*0.25;
- }
- //-----------------------------------------------------------------
- // 主程序
- //-----------------------------------------------------------------
- void main()
- {
- char DisplayBuffer[17];
- Initialize_LCD();
- LCD_ShowString(0,0,"TC72 Sensor Test");
- while(1)
- { Config_TC72();
- Read_TC72_Temperature();
- sprintf(DisplayBuffer,"%TEMP:%6.1f\xDF\x43",TempX);
- LCD_ShowString(1,0,DisplayBuffer);
- }
- }
- //-----------------------------------------------------------------
- // 液晶控制与显示程序
- //-----------------------------------------------------------------
- #include <reg51rc2.h>
- #include <intrins.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- sbit RS = P2^0; //寄存器选择线
- sbit RW = P2^1; //读/写控制线
- sbit EN = P2^2; //使能控制线
- //-----------------------------------------------------------------
- // 延时
- //-----------------------------------------------------------------
- void delay_ms(INT16U ms)
- {
- INT8U i;
- while(ms--) for(i = 0; i < 120; i++);
- }
- //-----------------------------------------------------------------
- // 忙等待
- //-----------------------------------------------------------------
- void Busy_Wait()
- {
- INT8U LCD_Status; //液晶状态字节变量
- do
- { P0=0xff; //液晶屏端口初始置高电平
- EN=0;RS=0;RW=1; //LCD禁止,选择状态寄存器,准备读
- EN=1;LCD_Status=P0; //LCD使能,从P0端口读取液晶屏状态字节
- EN=0; //LCD禁止
- } while (LCD_Status & 0x80); //液晶忙继续循环
- }
- //-----------------------------------------------------------------
- // 写LCD命令
- //-----------------------------------------------------------------
- void Write_LCD_Command(INT8U cmd)
- {
- Busy_Wait();
- RS=0;
- RW=0;
- EN=0;
- P0=cmd;
- EN=1;
- delay_ms(1);
- EN=0;
- }
- //-----------------------------------------------------------------
- // 发送数据
- //-----------------------------------------------------------------
- void Write_LCD_Data(INT8U dat)
- {
- Busy_Wait();
- RS=1;
- RW=0;
- EN=0;
- P0=dat;
- EN=1;
- delay_ms(1);
- EN=0;
- }
- //-----------------------------------------------------------------
- // LCD初始化
- //-----------------------------------------------------------------
- void Initialize_LCD()
- {
- Write_LCD_Command(0x38); delay_ms(1); //置功能,8位,双行,5*7
- Write_LCD_Command(0x01); delay_ms(1); //清屏
- Write_LCD_Command(0x06); delay_ms(1); //字符进入模式:屏幕不动,字符后移
- Write_LCD_Command(0x0C); delay_ms(1); //显示开,关光标
- }
- //-----------------------------------------------------------------
- // 显示字符串
- //-----------------------------------------------------------------
- void LCD_ShowString(INT8U r, INT8U c,INT8U *str)
- {
- INT8U i = 0;
- code INT8U DDRAM[] = {0x80,0xC0}; //1602LCD两行的起始DDRAM地址
- Write_LCD_Command(DDRAM[r] | c); //设置显示起始位置
-
- for ( i = 0; str[i] && i < 16 ;i++) //输出字符串
- Write_LCD_Data(str[i]);
-
- for (i=0; i < 16; i++) //不足一行时用空格填充
- Write_LCD_Data(' ');
- }
复制代码
以上图文的Word格式文档下载(内容和本网页上的一模一样,方便大家保存):
|