基于FPGA的LM75A温度传感器(VHDL).
基于LM75A的多点温度监测系统设计
监测 系统。所设计的 多 路 温度监测 系统工作稳定, 测量精度高, 具有宽广的应用领域和应用价值。 关键词 : I c总线; L M 7 5 A; 温度 ; 单片机
中图分 类号 : T P 2 7 4 文献 标志 码 : B 文 章编 号 : 1 0 0 0— 0 6 8 2 ( 2 0 1 3 ) 0 2— 0 0 8 0— 0 2
:
杨新鹏 (
) , 毕业 于哈尔滨工程大学 自动化专业 ,
“ ~ “ 一 J
’ 工…
Ab s t r a c t : T he pa p e r d e s i g ns a mu l t i— — c h a n n e l s t e mpe r a t u r e mo n i t o r i n g s y s t e m ba s e d o n d i g i t a l i n t e l ・ ・ l e c t i v e t e mp e r a t u r e s e ns o r LM7 5 A.T he mo ni t o r i n g s y s t e m h a v e t h e c h a r a c t e r i s t i c s o f h i g h wo r ki n g s t a bi l i - t y a nd me a s u r e p r e c i s i o n. I t p o s s e s s wi d e a p p l i c a t i o n i f e l d s a n d wo r t h i n e s s . Ke y wor ds: 1 2 C b us ;LM75 A ;t e mp e r a t u r e;s i n g l e c h i p
基于cpldfpga的数字温度表设计课程设计正文 _大学论文
郑州轻工业学院可编程数字系统课程设计题目:基于FPGA的数字温度计的设计成绩:学生姓名:专业班级:学号:院(系):电子信息工程学院指导教师:完成时间:年月日基于FPGA的数字温度计的设计摘要微型计算机的出现使现代的科学研究得到了质的飞跃,而EDA技术的出现则是给现代工业控制以及日常生活带来了极大的方便,大规模可编程逻辑器件FPGA以成本低、周期短、可靠性高等特点,给设计人员进行产品开发方面带来了诸多方便。
本系统设计的数字温度表正是应用FPGA来实现数字温度表的各种相关功能。
本文主要介绍采用EDA技术自上而下的设计思路,从硬件和软件两个方面阐述了如何通过FPGA器件实现数字温度表系统功能,有效的克服了传统的数字温度计的缺点。
基于FPGA在Quartus II 9.0软件下应用VHDL语言编写程序,采用ALTRA公司Cyclone系列的EP2C5T144芯片进行了计算机仿真,并给出了相应的仿真结果。
此系统利用温度传感器AD590采集温度信号,产生的温度信号经过调零、放大处理后,利用A/D转换器ADC0804将模拟信号转换成数字信号,将数字信号送入EPF10K10LC84-4进行处理,最后送入显示电路,由数码管显示温度值。
该温度表具有结构简单,抗干扰能力强,功耗小,可靠性高,速度快反应时间短等优点。
关键词:数字温度表 CPLD/FPGA 温度传感器 A/D转换器目录摘要 (Ⅰ)1.前言 (1)1.1背景介绍 (1)1.2 数字测温系统 (1)2. 系统描述 (2)2.1可编程逻辑器件FPGA (2)2.2FPGA结构原理与特点 (2)2.3温度传感器AD590的介绍 (3)2.4 A/D转换器ADC0804 (4)2.5硬件描述语言VHDL (6)2.6数字开发工具QuartusⅡ (6)2.7 QuartusⅡ开发系统的特点 (6)2.8 QuartusⅡ的设计流程 (7)3.系统设计方案 (8)3.1数字温度表的工作原理 (8)3.2功能模块的设计 (8)3.2.1测温模块 (8)3.2.2温度信号处理模块 (9)3.2.3模数转换模块 (10)3.2.4进制转换模块 (13)3.2.5动态扫描模块 (14)3.3系统综合 (16)4.系统的仿真分析及器件下载 (17)4.1系统的仿真分析 (17)4.2系统的器件下载 (19)5. 结论 (20)心得与体会 (21)参考文献 (22)附录 (23)1. 前言1.1背景介绍检测是控制的基础和前提,而检测的精度必须高于控制的精确度,否则无从实现控制的精度要求。
lm75a 指标 -回复
lm75a 指标-回复在本篇文章中,我们将重点介绍关于LM75A的指标。
LM75A是一款数字温度传感器,以其高精度和可靠性而闻名。
它主要用于电子设备、工业自动化以及汽车行业中的温度监测和控制应用。
下面我们将逐步回答关于LM75A指标的问题,以帮助读者更好地了解该传感器。
1. LM75A的主要特点是什么?LM75A是一款数字温度传感器,它可以测量温度并通过I2C接口与微控制器进行通信。
其主要特点包括高精度输出、宽工作温度范围、低功耗以及多种电源供应模式。
这些特点使得LM75A成为一个优秀的温度传感器选择。
2. LM75A的测量精度如何?LM75A的测量精度非常高,其温度测量精度为±2。
这使得它可以满足许多精确温度监测和控制的应用需求。
3. LM75A的工作温度范围是多少?LM75A的工作温度范围非常广泛,从-55到+125。
这使得LM75A非常适用于各种环境和应用条件下的温度监测。
4. LM75A的供电电压是多少?LM75A可以使用广泛的供电电压范围,从2.7V到5.5V。
这意味着在不同的应用场景下,LM75A可以适应不同的电源供应要求。
5. LM75A的通信接口是什么?LM75A使用I2C总线作为其主要通信接口,这使得它能够与广泛的微控制器和其他数字设备进行连接。
6. LM75A有哪些电源供应模式?LM75A有两种电源供应模式可供选择:独立供电模式和总线供电模式。
独立供电模式下,LM75A使用来自外部电源的电压进行工作;而总线供电模式下,LM75A使用来自I2C总线的电源。
7. LM75A是否具有警报功能?是的,LM75A具有上限和下限警报功能。
用户可以通过设置阈值来触发警报,并通过I2C接口读取警报状态。
这使得LM75A能够及时报告异常温度条件,以便及时采取措施。
8. LM75A是否有温度补偿功能?是的,LM75A具有温度补偿功能。
它能够根据其自身温度进行自动补偿,以提供更加准确的温度测量结果。
基于FPGA智能温度传感器监控报警系统的设计
基于FPGA智能温度传感器监控报警系统的设计概述本文将详细介绍基于FPGA智能温度传感器监控报警系统的设计。
该系统由FPGA、温度传感器和报警器等组成,可以实时采集环境温度数据并进行处理,同时还可以根据设定的报警阈值进行温度报警。
该系统具有实时性、准确性和灵敏度高等优点,在工业、仓储等领域有广泛应用价值。
设计方案系统硬件设计智能温度传感器智能温度传感器采用DS18B20数字温度传感器,其精度高、体积小、响应速度快、使用方便等优点,能够满足系统的需要。
传感器输出数字量信号,可通过FPGA进行处理并转化为模拟量信号。
FPGAFPGA是本系统的核心部件,负责实现数字信号处理和温度阈值报警功能。
我们选用Xilinx Spartan-6系列FPGA,其具有高速、低功耗、可编程等特点,同时还有丰富的外设资源可以扩展。
报警器为了保证报警的及时和可靠性,我们使用了声光报警器,其能够在温度超出设定阈值时及时报警。
系统软件设计VHDL设计我们采用了VHDL语言对系统进行设计,通过其高级抽象、可移植性强等特点,实现了可适应性强、代码简洁的设计。
其中,数字信号处理主要包含数据的采集、过滤和频率变换等部分;温度阈值报警主要包含数据的计算和闸门控制等。
界面设计为了让用户更加便捷地使用该系统,我们设计了简洁明了的界面,包括温度值显示、报警阈值设置和报警状态等。
系统实现硬件实现按照上述设计方案,我们完成了硬件电路的设计,其中智能温度传感器采用了标准接口,与FPGA连接顺畅稳定。
报警器也能有良好的响应效果。
软件实现通过VHDL语言,我们完成了数字信号处理和温度报警部分的代码编写,在模拟器中进行了仿真和调试,并进行了综合和布局。
最终在FPGA平台上进行了验证,并与界面进行了充分交互。
结果分析经过系统实现,我们完成了一个基于FPGA智能温度传感器监控报警系统的设计。
在实际测试中,该系统具有所需的准确性、灵敏度和实时性等特点,能够实时采集环境温度并进行温度阈值报警。
I2C实践(一)-LM75A温度传感器_图文.
FPGA/CPLD开发套件实验教程—— PERI2-4DI 篇实验四、I 2C 实践(一)-LM75A 温度传感器实验目的:在这一课里,我们一起来学习I2C 协议,以及I2C 驱动的编写方法,并通过FPGA/CPLD来驱动LM75A 温度传感器,读出当前温度信息。
实验原理:(1 I2C串行总线概述采用串行总线技术可以使系统的硬件设计大大简化、系统的体积减小、可靠性提高。
同时,系统的更改和扩充极为容易。
常用的串行扩展总线有: I2C (Inter IC BUS )总线、单总线(1-WIRE BUS )、SPI (Serial Peripheral Interface )总线及Microwire/PLUS等。
本课仅讨论I2C 串行总线。
I2C 总线是PHLIPS 公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C 总线只有两根双向信号线。
一根是数据线SDA ,另一根是时钟线SCL 。
I2C 总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA 及SCL 都是线“与”关系。
每个接到I2C 总线上的器件都有唯一的地址。
主机与其它器件间的数据传送可以是由主机发送数据到其它器件,这时主FPGA/CPLD开发套件实验教程—— PERI2-4DI 篇机即为发送器,总线上接收数据的器件则为接收器。
在多主机系统中,可能同时有几个主机企图启动总线传送数据,为了避免混乱, I2C 总线要通过总线仲裁,以决定由哪一台主机控制总线。
在FPGA/CPLD应用系统的串行总线扩展中,我们经常遇到的是以FPGA/CPLD为主机,其它接口器件为从机的单主机情况。
(2I2C总线的数据传送1)、数据位的有效性规定I2C 总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
实验7——LM75A传感器应用实验
课程名称:嵌入式软件技术开课机房:11号机房2012年5月15日星期五一、实验任务与实验目的二、报告内容1.I2C驱动程序#include"LM3S_I2CM.h"#include<hw_ints.h>#include<interrupt.h>#include<sysctl.h>#include<gpio.h>#define PART_LM3S8962#include<pin_map.h>// 定义工作状态#define STAT_IDLE 0 // 空闲状态#define STAT_ADDR 1 // 发送数据地址状态#define STAT_DATA 2 // 接收或发送数据状态#define STAT_FINISH 3 // 收发完成状态// 定义全局变量static unsigned long I2CM_BASE = I2C0_MASTER_BASE; // 定义I2C主机基址,并初始化static tI2CM_DEVICE gtDevice; // 器件数据接口static unsigned char gucStatus = STAT_IDLE; // 工作状态static tBoolean gbSendRecv; // 收发操作标志,false发送,true接收static char gcAddr[4]; // 数据地址数组static unsigned int guiAddrIndex; // 数据地址数组索引变量static unsigned int guiDataIndex; // 数据缓冲区索引变量// 对tI2CM_DEVICE结构体变量初始化设置所有数据成员void I2CM_DeviceInitSet(tI2CM_DEVICE *pDevice, unsigned char ucSLA, unsigned long ulAddr, unsigned int uiLen, char *pcData,unsigned int uiSize) {pDevice->ucSLA = ucSLA;pDevice->ulAddr = ulAddr;pDevice->uiLen = uiLen;pDevice->pcData = pcData;pDevice->uiSize = uiSize;}// 对tI2CM_DEVICE结构体变量设置与数据收发相关的成员(数据地址、数据缓冲区、数据大小)void I2CM_DeviceDataSet(tI2CM_DEVICE *pDevice, unsigned long ulAddr, char *pcData, unsigned int uiSize) {pDevice->ulAddr = ulAddr;pDevice->pcData = pcData;pDevice->uiSize = uiSize;}// I2C主机初始化void I2CM_Init(void) {I2CM_DeviceInitSet(>Device, 0, 0, 0, (void *) 0, 0);if ((I2CM_BASE != I2C0_MASTER_BASE) && (I2CM_BASE != I2C1_MASTER_BASE)) { I2CM_BASE = I2C0_MASTER_BASE;}switch (I2CM_BASE) {case I2C0_MASTER_BASE:SysCtlPeripheralEnable (SYSCTL_PERIPH_I2C0); // 使能I2C0模块SysCtlPeripheralEnable (I2C0SCL_PERIPH); // 使能SCL所在的GPIO模块GPIOPinTypeI2C(I2C0SCL_PORT, I2C0SCL_PIN); // 配置相关管脚为SCL功能SysCtlPeripheralEnable (I2C0SDA_PERIPH); // 使能SDA所在的GPIO模块GPIOPinTypeI2C(I2C0SDA_PORT, I2C0SDA_PIN); // 配置相关管脚为SDA功能IntEnable (INT_I2C0); // 使能I2C0中断break;case I2C1_MASTER_BASE:SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); // 使能I2C1模块SysCtlPeripheralEnable(I2C0SCL_PERIPH); // 使能SCL所在的GPIO模块GPIOPinTypeI2C(I2C0SCL_PORT, I2C0SCL_PIN); // 配置相关管脚为SCL功能SysCtlPeripheralEnable(I2C0SDA_PERIPH); // 使能SDA所在的GPIO模块GPIOPinTypeI2C(I2C0SDA_PORT, I2C0SDA_PIN); // 配置相关管脚为SDA功能IntEnable(INT_I2C0); // 使能I2C1中断break;default:break;}I2CMasterInit(I2CM_BASE, false); // I2C主机模块初始化,100kbpsI2CMasterIntEnable(I2CM_BASE); // 使能I2C主模块中断IntMasterEnable(); // 使能处理器中断I2CMasterEnable(I2CM_BASE); // 使能I2C主机}// 功能:I2C主机发送或接收数据// 参数:pDevice是指向tI2CM_DEVICE型结构体变量的指针// bFlag取值false表示发送操作,取值true表示接收操作// 返回:I2C_MASTER_ERR_NONE 没有错误// I2C_MASTER_ERR_ADDR_ACK 地址应答错误// I2C_MASTER_ERR_DATA_ACK 数据应答错误// I2C_MASTER_ERR_ARB_LOST 多主机通信仲裁失败// 发送格式:S | SLA+W | addr[1~4] | data[1~n] | P// 接收格式:S | SLA+W | addr[1~4] | Sr | SLA+R | data[1~n] | P unsigned long I2CM_SendRecv(tI2CM_DEVICE *pDevice, tBoolean bFlag) { // 数据地址长度或收发数据大小不能为0,否则不执行任何操作if ((pDevice->uiLen <= 0) || (pDevice->uiSize <= 0)) {return (I2C_MASTER_ERR_NONE);}gtDevice = *pDevice;if (gtDevice.uiLen > 4)gtDevice.uiLen = 4; // 数据地址长度不能超过4BgbSendRecv = bFlag; // 相关全局变量初始化guiAddrIndex = 0;guiDataIndex = 0;switch (gtDevice.uiLen) // 将数据地址分解成数组{case 1: // 1字节数据地址gcAddr[0] = (char) (gtDevice.ulAddr);break;case 2: // 2字节数据地址gcAddr[0] = (char) (gtDevice.ulAddr >> 8);gcAddr[1] = (char) (gtDevice.ulAddr);break;case 3: // 3字节数据地址gcAddr[0] = (char) (gtDevice.ulAddr >> 16);gcAddr[1] = (char) (gtDevice.ulAddr >> 8);gcAddr[2] = (char) (gtDevice.ulAddr);break;case 4: // 4字节数据地址gcAddr[0] = (char) (gtDevice.ulAddr >> 24);gcAddr[1] = (char) (gtDevice.ulAddr >> 16);gcAddr[2] = (char) (gtDevice.ulAddr >> 8);gcAddr[3] = (char) (gtDevice.ulAddr);break;default:break;}// 如果是多主机通信,则需要首先等待总线空闲// while (I2CMasterBusBusy(I2CM_BASE)); // 等待总线空闲I2CMasterSlaveAddrSet(I2CM_BASE, gtDevice.ucSLA, false); // 设置从机地址,写操作I2CMasterDataPut(I2CM_BASE, gcAddr[guiAddrIndex++]); // 开始发送数据地址gucStatus = STAT_ADDR; // 设置状态:发送数据地址// 命令:主机突发发送起始I2CMasterControl(I2CM_BASE, I2C_MASTER_CMD_BURST_SEND_START);while (gucStatus != STAT_IDLE); // 等待总线操作完毕return (I2CMasterErr(I2CM_BASE)); // 返回可能的错误状态}// I2C中断服务函数void I2C_ISR(void) {unsigned long ulStatus;ulStatus = I2CMasterIntStatus(I2CM_BASE, true); // 读取中断状态I2CMasterIntClear(I2CM_BASE); // 清除中断状态if (I2CMasterErr(I2CM_BASE) != I2C_MASTER_ERR_NONE) // 若遇到错误{gucStatus = STAT_IDLE;return;}if (!ulStatus)return;switch (gucStatus) {case STAT_ADDR: // 发送数据地址状态if (guiAddrIndex < gtDevice.uiLen) // 若数据地址未发送完毕{// 继续发送数据地址I2CMasterDataPut(I2CM_BASE, gcAddr[guiAddrIndex++]);// 命令:主机突发发送继续I2CMasterControl(I2CM_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);break;} else {gucStatus = STAT_DATA; // 设置状态:收发数据if (gbSendRecv) // 若是接收操作{// 设置从机地址,读操作I2CMasterSlaveAddrSet(I2CM_BASE, gtDevice.ucSLA, true);if (gtDevice.uiSize == 1) // 若只准备接收1个字节{gucStatus = STAT_FINISH; // 设置状态:接收结束// 命令:主机单次接收I2CMasterControl(I2CM_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE);} else {// 命令:主机突发接收起始I2CMasterControl(I2CM_BASE,I2C_MASTER_CMD_BURST_RECEIVE_START);}break;}}// 直接进入下一条case语句case STAT_DATA: // 收发数据状态if (gbSendRecv) // 若是接收操作{// 读取接收到的数据gtDevice.pcData[guiDataIndex++] = I2CMasterDataGet(I2CM_BASE);if (guiDataIndex + 1 < gtDevice.uiSize) // 若数据未接收完毕{// 命令:主机突发接收继续I2CMasterControl(I2CM_BASE,I2C_MASTER_CMD_BURST_RECEIVE_CONT);} else {gucStatus = STAT_FINISH; // 设置状态:接收完成// 命令:主机突发接收完成I2CMasterControl(I2CM_BASE,I2C_MASTER_CMD_BURST_RECEIVE_FINISH);}} else {// 发送数据I2CMasterDataPut(I2CM_BASE, gtDevice.pcData[guiDataIndex++]);if (guiDataIndex < gtDevice.uiSize) // 若数据未发送完毕{// 命令:主机突发发送继续I2CMasterControl(I2CM_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);} else {gucStatus = STAT_FINISH; // 设置状态:发送完成// 命令:主机突发发送完成I2CMasterControl(I2CM_BASE,I2C_MASTER_CMD_BURST_SEND_FINISH);}}break;case STAT_FINISH: // 收发完成状态if (gbSendRecv) // 若是接收操作{// 读取接最后收到的数据gtDevice.pcData[guiDataIndex] = I2CMasterDataGet(I2CM_BASE);}gucStatus = STAT_IDLE; // 设置状态:空闲break;default:break;}}2.LM75数据采集#include"systemInit.h"#include"uartGetPut.h"#include"LM3S_I2CM.h"#include<stdio.h>// 定义LM75A(NXP半导体数字温度传感器,I2C接口)#define LM75A_SLA (0x90 >> 1) // 定义LM75A的器件地址#define LM75A_REG_TMP 0x00 // 定义LM75A的温度寄存器地址tI2CM_DEVICE LM75A;// 读取LM75A的温度值,并通过UART发送显示void LM75A_TmpDisp(char *pcTmp) {char Tab[8][4] = { "000", "125", "250", "375", "500", "625", "750", "875"};char s[20];short t;t = pcTmp[0];t <<= 8;t |= pcTmp[1] & 0xE0;if (t < 0) {t = -t;uartPutc('-');}sprintf(s, "%d", (int) (t) / 256);uartPuts(s);uartPutc('.');uartPuts(Tab[(t >> 5) & 0x07]);uartPuts("\r\n");}// 主函数(程序入口)int main(void) {char cBuf[2];unsigned long ulStatus;I2CM_DeviceInitSet(&LM75A, LM75A_SLA, LM75A_REG_TMP, 1, cBuf, 2);jtagWait(); // 防止JTAG失效,重要!clockInit(); // 时钟初始化:晶振,6MHzuartInit(); // UART初始化I2CM_Init(); // I2C主机初始化for (;;) {ulStatus = I2CM_DataRecv(&LM75A);if (ulStatus == I2C_MASTER_ERR_NONE) // 没有错误{LM75A_TmpDisp(cBuf); // 显示LM75A温度} else {uartPuts("Error\r\n");if (ulStatus & I2C_MASTER_ERR_ADDR_ACK) // 地址应答错误{uartPuts("cannot find LM75A.\r\n");}if (ulStatus & I2C_MASTER_ERR_DATA_ACK) // 数据应答错误{uartPuts("cannot get data from LM75A.\r\n");}if (ulStatus & I2C_MASTER_ERR_ARB_LOST) // 多主机通信仲裁失败{uartPuts("arbitration lost.\r\n");}break;}SysCtlDelay(10000 * (TheSysClock / 3000));}for (;;) {}}3.温度采集系统public partial class TempChartForm : Form{PointPairList tempList = new PointPairList();int pointIndex = 0;public TempChartForm(){InitializeComponent();lm75Port.PortName = "COM5";lm75Port.BaudRate = 9600;lm75Port.Open();ZedGraphInit();}private void lm75Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e){string line = lm75Port.ReadLine();if (line != null && line != ""){float tempValue = float.Parse(line);pointIndex++;tempList.Add(pointIndex, tempValue);tempChart.AxisChange();tempChart.Invalidate();}}void ZedGraphInit(){GraphPane paneCurrent = tempChart.GraphPane;// Set the TitlespaneCurrent.Title.Text = "温度数据";paneCurrent.YAxis.Title.Text = "Counts, (A)";paneCurrent.XAxis.Title.Text = "points";paneCurrent.XAxis.Scale.MinorStep = 1;paneCurrent.XAxis.Scale.MajorStep = 5;paneCurrent.AddCurve("温度", tempList, Color.Red, SymbolType.Circle);tempChart.AxisChange();}}三、运行结果。
基于FPGA的温度传感报警系统设计
基于FPGA的温度传感报警系统设计一、引言温度传感器在许多领域中被广泛使用,用于监测环境或设备的温度变化。
为了及时发现温度异常并采取相应措施,设计一个基于FPGA的温度传感报警系统具有重要意义。
本文将介绍如何利用FPGA实现温度传感器数据采集、处理和报警功能的设计方案。
二、系统结构基于FPGA的温度传感报警系统通常包括温度传感器模块、FPGA开发板、显示模块和报警器。
温度传感器用于采集环境温度数据,将数据传输给FPGA开发板;FPGA开发板负责接收并处理传感器数据,根据预设阈值判断是否触发报警;当温度超过设定阈值时,FPGA会触发报警器进行提示。
三、设计原理1. 数据采集:FPGA通过接口与温度传感器通信,获取实时温度数据。
2. 数据处理:FPGA对采集到的温度数据进行处理,与预设阈值比较,判断是否触发报警。
3. 报警功能:当温度超过设定阈值时,FPGA触发相应报警装置,如LED灯闪烁、蜂鸣器响声等。
四、软件实现1. Verilog/VHDL编程:使用Verilog或VHDL语言编写FPGA的逻辑设计,包括数据采集、阈值比较和报警逻辑。
2. 开发工具:选择适合的FPGA开发工具,如Xilinx ISE、Quartus II 等,进行逻辑综合、布局布线和下载等操作。
3. 调试验证:通过仿真和实验验证系统设计的正确性和稳定性。
五、性能分析通过对基于FPGA的温度传感报警系统进行性能分析,可以评估系统的响应速度、准确性和稳定性等指标。
同时,还可以分析系统的功耗、资源利用情况和可靠性等方面,为系统优化提供依据。
六、总结基于FPGA的温度传感报警系统设计结合了硬件设计和软件编程技朧,具有广泛的应用前景。
通过合理设计系统结构和软硬件实现,可以实现对温度异常的及时监测和报警提示,保障设备和环境的安全。
希望本文的介绍能够为读者深入理解基于FPGA的温度传感报警系统设计提供参考和启发,促进相关领域的技术创新和应用。
基于FPGA的温度检测无线发射接
基于FPGA的温度检测无线发射接
前言
随着社会节能环保意识的增强,人们越来越重视能源的利用效率。
传统的暖气控制都是利用锅炉烧出蒸汽或热水,通过管道输送到建筑物内的散热器中,散出热量,使室温增高。
但是这种设备控制中心和客户端不在同一个地方,这样就存在着一种控制中心不了解客户的情况。
存在着暖气开得过大或者过小,从而导致客户温度过低或过高而浪费了能源!
以前大多温度控制系统都是用单片机控制的,但是随着FPGA的迅速发展,应用也越来越广。
本人将设计出一套由FPGA独立控制的、智能化的远程温度控制系统。
由一个放置于客户端的温度采集系统采集到客户端温度(可排除工程中热损失),当大于或小于人体最佳温度区时发出报警信号,由控制端去控制是应该加温还是降温,从而达到节能的作用。
1 数字温度传感技术
1.1 数字温度传感器原理。
I2C实践(一)-LM75A温度传感器_图文.
FPGA/CPLD开发套件实验教程—— PERI2-4DI 篇实验四、I 2C 实践(一)-LM75A 温度传感器实验目的:在这一课里,我们一起来学习I2C 协议,以及I2C 驱动的编写方法,并通过FPGA/CPLD来驱动LM75A 温度传感器,读出当前温度信息。
实验原理:(1 I2C串行总线概述采用串行总线技术可以使系统的硬件设计大大简化、系统的体积减小、可靠性提高。
同时,系统的更改和扩充极为容易。
常用的串行扩展总线有: I2C (Inter IC BUS )总线、单总线(1-WIRE BUS )、SPI (Serial Peripheral Interface )总线及Microwire/PLUS等。
本课仅讨论I2C 串行总线。
I2C 总线是PHLIPS 公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C 总线只有两根双向信号线。
一根是数据线SDA ,另一根是时钟线SCL 。
I2C 总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA 及SCL 都是线“与”关系。
每个接到I2C 总线上的器件都有唯一的地址。
主机与其它器件间的数据传送可以是由主机发送数据到其它器件,这时主FPGA/CPLD开发套件实验教程—— PERI2-4DI 篇机即为发送器,总线上接收数据的器件则为接收器。
在多主机系统中,可能同时有几个主机企图启动总线传送数据,为了避免混乱, I2C 总线要通过总线仲裁,以决定由哪一台主机控制总线。
在FPGA/CPLD应用系统的串行总线扩展中,我们经常遇到的是以FPGA/CPLD为主机,其它接口器件为从机的单主机情况。
(2I2C总线的数据传送1)、数据位的有效性规定I2C 总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
基于FPGA和LM75A的测温系统设计
基于FPGA和LM75A的测温系统设计刘欢;欧伟明;陈财彪;周志伟【摘要】设计了一种基于FPGA和LM75A的温度测量系统.硬件设计上,系统以EP4CE15F17C8N为主控芯片,采用数字温度传感器LM75A检测环境温度,并利用LM75A自带的ⅡC总线接口传输数据,通过数码管将温度实时显示出来;软件设计上,采用自顶向下模块化设计思想,先设计出ⅡC通信模块、温度显示模块,然后再编写顶层模块,将2个模块整合.试验结果表明,本系统测温精确,且运行稳定.【期刊名称】《湖南工业大学学报》【年(卷),期】2014(028)004【总页数】5页(P25-29)【关键词】温度采集;FPGA;LM75A;EP4CE15F17C8N;ⅡC总线【作者】刘欢;欧伟明;陈财彪;周志伟【作者单位】湖南工业大学电气与信息工程学院,湖南株洲412007;湖南工业大学电气与信息工程学院,湖南株洲412007;湖南工业大学电气与信息工程学院,湖南株洲412007;湖南工业大学电气与信息工程学院,湖南株洲412007【正文语种】中文【中图分类】TH811EP4CE15F17C8N是由Altera公司2009年推出的Cyclone IV FPGA(field-programmable gate array)芯片。
Cyclone IV FPGA所需的供电电源很少,在电路设计中,可以使用相对简单的电源稳压器以及相关的滤波器电路,这样电源分配网络得到简化,电路板面积也将减小,进一步降低了成本[1]。
由于FPGA非常的灵活,其产品能比大部分新开发的A S I C(application specific integrated circuit)或者ASSP(application specific standard parts)产品更迅速地推向市场,因此FPGA具有增加新功能方便、迅速跟上市场变化以及满足客户需求等优点,能通过提高其可靠性,降低系统的维护成本,还可以重新设计以避免过时问题。
lm75a 指标 -回复
lm75a 指标-回复什么是lm75a指标?lm75a是一种温度传感器芯片,由德国公司飞雅特(Infineon)开发和生产。
它是一款数字式温度传感器,可通过I2C总线与微处理器或其他外围设备进行通信。
lm75a传感器具有高精度、低功耗和多功能的特点,广泛应用于工业控制、电子设备和医疗仪器等领域。
lm75a指标是指这款温度传感器的性能参数和技术规格。
下面将一步一步回答关于lm75a指标的问题,详细介绍其主要特点和应用。
1. lm75a的温度测量范围是多少?精度如何?lm75a温度传感器的测量范围是-55至+125。
其精度可达±2。
这意味着在这个温度范围内,lm75a能够提供高度精确的温度测量结果。
2. lm75a的接口协议是什么?lm75a使用I2C总线协议进行通信。
使用I2C协议的好处是可以与其他设备进行简单、快速的串联连接,并且能够同时与多个设备进行通信。
3. lm75a的供电电压范围是多少?lm75a传感器的供电电压范围是2.8V至5.5V。
这个范围内的供电电压都可以满足芯片的正常工作要求。
4. lm75a传感器的功耗如何?lm75a传感器的功耗相对较低,最大值为100μA。
这意味着它可以在低功耗要求的应用中长时间工作,而不会对系统电源造成过大的负担。
5. lm75a具有哪些特殊功能?lm75a传感器除了基本的温度测量功能外,还具有一些特殊功能。
首先,它提供了温度限制报警功能,可以在温度超过或低于用户设定的阈值时触发报警。
其次,lm75a还具有可编程的分辨率设置功能,用户可以根据实际需求选择不同的分辨率来平衡测量精度和系统性能。
此外,lm75a还支持多个传感器的串联连接,以便同时测量多个温度点。
6. lm75a广泛应用于哪些领域?由于其高精度、低功耗和多功能的特点,lm75a传感器在许多领域得到了广泛应用。
在工业控制领域,lm75a可用于温度监测和控制系统,例如自动化设备、生产线和仪表等。
lm75a 指标
lm75a指标什么是LM75A指标?LM75A是一种数字式温度传感器,属于I2C总线原件。
它能够提供精确的温度测量数据,并且具有高精度和可靠性,被广泛应用于各种电子设备中。
首先,让我们了解LM75A指标的基本特性。
LM75A的主要特点包括以下几个方面:1.高分辨率:LM75A可以提供12位精度的温度测量数据,这意味着它可以检测到非常微小的温度变化。
2.宽工作范围:LM75A可以在-55C至+125C的温度范围内工作,使其适用于各种环境条件。
3.数字输出:LM75A通过I2C总线输出温度测量数据,使其与其他电子设备的通信更加便捷。
4.低功耗:LM75A的工作电流非常低,在典型情况下仅为200μA左右,这使得它非常适合用于电池供电的设备中。
5.可编程阈值:LM75A具有可编程的高温和低温阈值,当温度超过或低于设定的阈值时,LM75A会触发报警信号。
接下来,让我们详细了解LM75A指标的工作原理。
LM75A采用热敏电阻和模拟数字转换器(ADC)来测量温度。
当温度变化时,热敏电阻的电阻值也会发生变化,LM75A将这个变化转换为数字信号,并通过I2C 总线发送给主控制器。
LM75A的工作原理可以分为以下几个步骤:1.初始化:首先,主控制器需要通过I2C总线初始化LM75A,包括设置工作模式、温度测量分辨率和报警阈值等。
2.温度测量:一旦LM75A被初始化,它将开始测量环境温度。
它通过读取热敏电阻的电阻值,并将其转换为相应的数字信号。
3.数据传输:LM75A将温度测量数据转换为数字信号后,通过I2C总线传输给主控制器。
主控制器可以读取该数据并进行进一步处理。
4.报警功能:LM75A具有可编程的高温和低温阈值,如果温度超过或低于设定的阈值,LM75A将触发报警信号,以便主控制器采取相应的措施。
5.最后,让我们来讨论LM75A指标的应用领域。
由于LM75A具有高精度和可靠性,它被广泛应用于各种电子设备中,特别是需要监测温度的领域,如:1.家庭电器:LM75A可以用于监测家用电器的工作温度,如空调、冰箱、洗衣机等。
LM75A程序解析(数字式温度传感器
LM75A程序解析(数字式温度传感器2011-01-29 15:14:13| 分类:默认分类| 标签:lm75a 工程师|字号订阅最近在测试LM75A的过程中出现的问题,从网上找来资料,调试发现都有问题,所以啊思路可以参考别人的具体程序还是自己写吧呵呵!网上的两个程序都有问题,都是数据处理过程中的问题:第一篇网上的帖子:在如今什么芯片都在涨价就是工资没涨价的情况下,看到LM75A 比DS18B20还是便宜,有兴趣的朋友可以考虑下,这是网上资料,本人没测试LM75A是PHILPS公司生产的数字温度传感器及看门狗。
通过片内集成的带隙温度传感器和∑-△数摸转换器来实现数字温度的测量,并通过该温度传感器为用户提供温度超限报警输出。
LM75A内部包含多个数据寄存器:(1)配置寄器(Conf):用来存储器件的配置,如:器件工作模式、OS工作模式、OS极性和OS故障队列;(2)温度寄存器(Temp):用于存储读取的数字温度;(3)设定点寄存器(Tos&Thyst):用来存储可编程的过热关断和滞后限制。
器件通过2线的串行I2C总线接口与控制器通信。
LM75A包含一个开漏输出(OS),当温度超过编程限制的值时该输出有效。
LM75A有3个可选的逻辑地址管脚,使得同一总线上可同时挂8个LM75A而无需其他硬件的支持CPU:STC89C54RD+晶震:11.0592MA0 A1 A2 均接地地址设置为0 OS脚和INT0相连并通过10K上拉到VCC;当转换温度超过极限温度,输出中断蜂鸣器报警;刷新数码管显示温度共5位前一位表示正负温度后三位为温度125 - -55 最后一位为0.1度最高可精确到0.125 数码管图略(看程序应该会知道)定时器100MS采集温度一次#include#include#includesbit xiaoshu=P2^0; //COM口sbit ge=P2^1;sbit shi=P2^3;sbit bai=P2^4;sbit fh=P2^5;sbit SDA_LM75=P1^0; //数据sbit SCL_LM75=P1^1;sbit BP=P2^1;bit dp=0;unsigned char JS=0;#define LED P0 //8位数码管动态时时刷新#define CONF 0X01 //配置寄存器#define TEMP 0X00 //温度寄存器只读#define ALARM 0X03 //超温关闭极限寄存器默认5000H#define DELAY 0X02 //滞后寄存器默认4B00H#define WADDR 0X90 //写地址#define RADDR 0X91 //读地址unsigned int tempdata=0; //全局变量申明温度unsigned char code tab[]={ 0x3f,0x30,0x6d,0x79,0x72,0x5b,0x5f,0x31,0x7f,0x7b,0x40}; //共阴//0, 1, 2 3 4 5 6 7 8 9//unsigned char tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳//0, 1, 2 3 4 5 6 7 8 9unsigned char code tabdp[]={ 0xbf,0xb0,0xed,0xf9,0xf2,0xdb,0xdf,0xb1,0xff,0xfb,0xc0 };//共阴带小数点//0, 1, 2 3 4 5 6 7 8 9//unsigned char tabdp[]={ 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};/ /共阳void delay_xms(unsigned int count) //延时函数{register unsigned char j;while (count --){for (j=0;j<125;j++) //约1MS{}}}void Led_Display(unsigned int i,bit mode) //显示函数{if(mode)LED = 0x40; //共阴负//LED=0xBF;elseLED = 0x00;//LED= 0XFF;fh = 1;bai = 0;shi = 0;ge = 0;xiaoshu=0;delay_xms(1);LED = tab[i/1000];i%=1000;fh = 0;shi = 0;ge = 0;xiaoshu=0;delay_xms(1);LED = tab[i/100];fh=0;bai = 0;shi = 1;ge = 0;xiaoshu=0;delay_xms(1);LED = tabdp[i/10]; //带小数点fh=0; bai = 0;shi = 0;ge = 1;xiaoshu=0;delay_xms(1);LED = tab[i%10];fh=0;bai = 0;shi = 0;ge = 0;xiaoshu=1;delay_xms(1);}void delay(void) //延时函数{_nop_();_nop_();_nop_();_nop_();}void start_lm75(void)//起始{SDA_LM75=1;SCL_LM75=1;delay();SDA_LM75=0;delay();SCL_LM75=0;}void stop_lm75(void)//停止{SDA_LM75=0;SCL_LM75=1;SDA_LM75=1;delay();SCL_LM75=0;}void Check_Ack(void) //检查应答信号{SDA_LM75=1;SCL_LM75=1;F0=0;delay();if(SDA_LM75) //如果数据为高置位非应答标志FO F0=1; //通用标志位PSW状态寄存器SCL_LM75=0; //准备下一变化数据}void Ack(void) //发响应信号{SDA_LM75=0;delay();SCL_LM75=1;delay();SCL_LM75=0;}void no_Ack(void) //发非响应信号{SDA_LM75=1;SCL_LM75=0;delay();SCL_LM75=1; //迫使数据传输结束delay();}void send_byte(unsigned char temp) //发送一字节数据{ unsigned char i=8;while(i--){SDA_LM75=(bit)(temp&0x80);SCL_LM75=1;delay();SCL_LM75=0;temp<<=1;}SCL_LM75=0;SDA_LM75=1; //释放SDA数据线}unsigned char read_byte(void) //读一字节数据{unsigned char i=8;unsigned char temp;while(i--){temp<<=1;if(SDA_LM75)temp++;SCL_LM75=1;delay();SCL_LM75=0;}SCL_LM75=0;delay();SDA_LM75=1; //释放SDA数据线return (temp);}void Write_chardata(unsigned char addr,unsigned char tempdata)//写配置寄存器{start_lm75();send_byte(WADDR);Check_Ack();if(F0){no_Ack();return;}Ack();send_byte(addr);Check_Ack();if(F0){no_Ack();return;}Ack();send_byte(tempdata);Check_Ack();if(F0)return;}Ack();delay();stop_lm75();}void Write_intdata(unsigned char addr,unsigned int tempdata)//写16位寄存器{unsigned char datahigh;unsigned char datalow;datahigh=(unsigned char)(tempdata>>8);datalow=(unsigned char)(tempdata&0x00FF);start_lm75();send_byte(WADDR);Check_Ack();if(F0){no_Ack();return;}Ack();send_byte(addr);Check_Ack();if(F0){no_Ack();return;}Ack();send_byte(datahigh);send_byte(datalow);Check_Ack();if(F0){no_Ack();return;}Ack();delay();stop_lm75();}unsigned char read_chardata(unsigned char addr) //读8位寄存器unsigned char temp;start_lm75();send_byte(WADDR);Check_Ack();if(F0){no_Ack();return 0;}Ack();send_byte(addr);Check_Ack();if(F0){no_Ack();return 0;}Ack();send_byte(RADDR);Check_Ack();if(F0){no_Ack();return 0;}Ack();temp=read_byte();stop_lm75();return (temp);}unsigned int read_intdata(unsigned char addr) //读16位寄存器{//unsigned char temphigh,templow; 原函数使用的是无符号字符型,8位unsigned int temphigh,templow; //改成了无符号整形16位start_lm75();send_byte(WADDR);Check_Ack();if(F0){no_Ack();return 0;}Ack();send_byte(addr);Check_Ack();if(F0){no_Ack();return 0;}Ack();send_byte(RADDR);Check_Ack();if(F0){no_Ack();return 0;}Ack();temphigh=read_byte(); templow=(read_byte())&0xe0; stop_lm75();if(!(temphigh&0x80)){dp=0;return (((temphigh<<8)|templow)>>5); //如果使用的是8位字符型temphigh的话左移过程中数据已经全部丢了!}else{dp=1;return (0x800-((temphigh<<8)|templow)>>5);}}void initial() // 初始化LM75A{Write_chardata(CONF,0X20); //0S中断模式,温度转换正常模式Write_intdata(ALARM,0x3300); //100度极限由高9位有效位组成BIT15为1表示为负为0表示为正超过100度触发外部中断0 Write_intdata(DELAY,0X4A80); // 95度后不报警}void int0_int() interrupt 0 using 1 // 外部中断0服务函数{BP=0;delay_xms(1000);delay_xms(1000);}void t0_int() interrupt 1 using 1 //定时器0中断服务函数{TR0=0;TH0=0xdc; // 10MS中断初值TL0=0xff;TR0=1;JS++;if(JS>10) //加到10为100MS{JS=0;tempdata=read_intdata(TEMP); //采集数据tempdata=(tempdata/8)*10; //转换为温度}}void main() // 入口函数{IP=0X01;TMOD=0X01;TH0=0xdc; // 10MS中断初值TL0=0xff;IT0=0; //外部中断0采用电平触发ET0=1;TR0=1; //开放定时器0中断EX0=1;EA=1;initial();while(1){if(dp)Led_Display(tempdata,1);elseLed_Display(tempdata,0);}}第二个程序,问题同样出现在数据处理中!://main主函数/*main.cLM75A数字温度计*/#include "Disp.h"#include "I2C.h"#include#include/*函数:Delay()功能:延时1ms~65.536s 参数:t>0时,延时(t*0.001)st=0时,延时65.536s*/void Delay(unsigned int t) {do{TH0 = 0xFC;TL0 = 0x66;TR0 = 1;while ( !TF0 );TR0 = 0;TF0 = 0;} while ( --t != 0 );}/*函数:SysInit()功能:系统初始化*/void SysInit(){TMOD &= 0xF0;TMOD |= 0x01; //设置T0为16位定时器 DispInit(); //数码管扫描显示初始化I2C_Init(); //初始化I2C总线}/*函数:ByteT oStr()功能:字节型变量c转换为十进制字符串void ByteToStr(unsigned char idata *s, unsigned char c){code unsigned char Tab[] = {100,10};unsigned char i;unsigned char t;for ( i=0; i<2; i++ ){t = c / Tab[i];*s++ = '0' + t;c -= t * Tab[i];}*s++ = '0' + c;*s = '\0';}/*函数:LM75A_GetT emp功能:读出LM75A的温度值返回:LM75A温度寄存器的数值(乘以0.125可得到摄氏度值)*/int LM75A_GetTemp(){unsigned char buf[2];int t;I2C_Gets(0x90,0x00,2,buf);t = buf[0];t <<= 8;t += buf[1];t >>= 5; //去掉无关位右移8位后再左移高位始终是0 正负将无法判断 return t;}/*函数:DispTemp()功能:在数码管上显示出温度值参数:t:补码,除以8以后才是真正温度值*/void DispTemp(int t){code unsigned char Tab[8][4] ={"000","125","375","500","625","750","875"};unsigned char buf[4];bit s; //符号位unsigned char i; //整数部分unsigned char d; //小数部分unsigned char x; //临时变量//分离出符号s = 0;if ( t < 0 ){s = 1;t = -t;}//分离出整数和小数部分i = t / 8;d = t % 8;//整数部分转换成字符串ByteToStr(buf,i);x = 4 - strlen(buf);//清除所有显示DispClear();//显示符号if ( s ) DispChar(x,'-');x++;//显示整数部分DispStr(x,buf);//显示小数点DispDotOn(4);//显示小数部分DispStr(5,Tab[d]);}void main(){int t;SysInit();for (;;){t = LM75A_GetT emp(); DispTemp(t); Delay(1000); } }。
(完整版)基于FPGA的温度传感器课程设计
FPGA课程设计论文学生姓名周悦学号20091321018院系电子与信息工程学院专业电子科学与技术指导教师李敏二O一二年5月28 日基于FPGA的温度传感器系统设计1引言温度是一种最基本的环境参数,人们的生活与环境的温度息息相关,在工业生产过程中需要实时测量温度,在农业生产中也离不开温度的测量,因此研究温度的测量方法和装置具有重要的意义。
测量温度的关键是温度传感器,温度传感器的发展经历了三个发展阶段:传统的分立式温度传感器;模拟集成温度传感器;智能集成温度传感器。
目前,国际上新型温度传感器正从模拟式向数字式,从集成化向智能化、网络化的方向飞速发展。
本文将介绍采用智能集成温度传感器DS18B20,并以FPGA为控制器的温度测量装置的硬件组成和软件设计,用液晶来实现温度显示。
2电路分析系统框图如下:第一部分:DS18B20温度传感器美国 Dallas 半导体公司的数字化温度传感器 DS1820 是世界上第一片支持 "一线总线"接口的温度传感器,在其内部使用了在板(ON-B0ARD)专利技术。
全部传感元件及转换电路集成在形如一只三极管的集成电路内。
一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。
现在,新一代的 DS18B20 体积更小、更经济、更灵活。
使你可以充分发挥“一线总线”的优点。
DS18B20 的主要特性:(1)适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电(2)独特的单线接口方式,DS18B20 在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20 的双向通讯(3)DS18B20 支持多点组网功能,多个DS18B20 可以并联在唯一的三线上,实现组网多点测(4)DS18B20 在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内(5)温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃(6)可编程的分辨率为 9~12位,对应的可分辨温度分别为 0.5℃、0.25℃、0.125℃和 0.0625℃,可实现高精度测温(7)在 9 位分辨率时最多在93.75ms 内把温度转换为数字,12 位分辨率时最多在 750ms 内把温度值转换为数字,速度更快(8)测量结果直接输出数字温度信号,以"一线总线"串行传送给 CPU,同时可传送 CRC 校验码,具有极强的抗干扰纠错能力(9)负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。
基于LM75A的多点温度监测系统设计
基于LM75A的多点温度监测系统设计杨新鹏【摘要】The paper designs a multi - channels temperature monitoring system based on digital intellective temperature sensor LM75A. The monitoring system have the characteristics of high working stability and measure precision. It possess wide application fields and worthiness.%采用基于I2C总线的智能数字温度传感器LM75A,设计了一款基于I2C总线的多点温度监测系统.所设计的多路温度监测系统工作稳定,测量精度高,具有宽广的应用领域和应用价值.【期刊名称】《工业仪表与自动化装置》【年(卷),期】2013(000)002【总页数】3页(P80-81,84)【关键词】I2C总线;LM75A;温度;单片机【作者】杨新鹏【作者单位】中航工业洛阳电光设备研究所,河南洛阳471009【正文语种】中文【中图分类】TP274温度检测是现代检测技术的重要组成部分,在保证产品质量、节约能源和安全生产等方面起着重要作用。
该文介绍了基于I2C总线的智能数字温度传感器LM75A的多点温度采集监测系统,具有宽广的应用领域和使用价值。
1 系统总体设计方案系统采用ATMEL公司的AT89C52单片机作为处理器,通过P1.0和P1.1端口模拟I2C总线时序,采用智能数字温度传感器LM75A,设计了一款基于I2C总线的8点温度采集监测系统。
系统可通过上位机监控软件实现传感器序号显示、温度值显示、温度报警、远距离通信。
测温系统与上位机软件通过RS232进行通信。
2 系统硬件设计系统使用ATMEL公司的AT89C52单片机作为主控制器,最多可采集8路温度。
基于FPGA的VHDL语言温度控制
基于FPGA的恒温控制系统孵化器是一种最新的孵化禽蛋的机器,通过人工制造适合禽蛋孵化的恒温环境,来以较小的经济投入孵化禽蛋,通过调查,市面上的孵化器多数是以模拟电路的方式制造恒温环境,如下图这种模拟电路控制在实际应用中很难做到恒温控制,温度会在最终归的预设值附近上下浮动,影响禽蛋的孵化。
而且,孵化器的温度设置也是模拟电路,这样是完全达不到精准的温度设置。
通过学习FPGA,我设想运用数字电路来对禽蛋孵化器内部温度进行控制,来实现可控,可调,温度恒定的禽蛋孵化器。
具体的设计框架如下通过前向温度采集电路,采集当前孵化器内部的温度信号,将采集到的模拟信号通过ADC0809模数转换芯片,转变为FPGA可控的数字信号,FPGA芯片根据输入的当前实际温度,控制输出合理的数字信号,再由DAC0832转换为模拟信号,输入到后向加热执行电路,以此来完成对整个孵化器的温度控制。
整个系统中,带有温度传感器的前向温度采集电路作为系统的反馈环节,实时反映当前环境的具体温度,具体的电路图如下。
前向温度采集电路图此电路设计以AD590作为温度触感器,通过添加相应的调节电阻,让温度与输出电压保持一个相对线性的关系 其中: W1R 为调零电阻 2w R 为调满度电阻 最终得到的温度与输出电压的关系式为:U 5T 100模数转换芯片采用的是ADC0809,具体的连接电路图如下IN0—IN7管角中任选一路作为前向温度采集电路的输入,VCC与VREF同VREF与GND接地,OUT1—OUT8数据输出端连接FPGA,时接+5V电压,_START,OE,EOC,ADDA-C均连接FPGA,根据ADC0809的工作时序图,由FPGA给出相应的信号控制ADC0809。
数模转换部分采用的是DAC0832,具体连接图如下DI0-DI7分别于FPGA的8位数据输出端相连,因为DAC0832工作在连续的负反馈电路中,故采用直通的工作方式,将WR1与WR2直接与地相连,ILE与CS,Xfer引脚均接至FPGA,有FPGA发送控制信号来控制DAC0832的工作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.编写的程序(一)功能模块:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;--实体--entity at24c08 isport(clk : in std_logic; --时钟信号rst : in std_logic; --复位信号scl : out std_logic; --i2c时钟线sda : inout std_logic; --i2c数据线urv_1 : in std_logic; --上限值1urv_2 : in std_logic; --上限值2sel : out std_logic_vector(3 downto 0);seg : out std_logic_vector(7 downto 0);beep : out std_logic --蜂鸣器输出信号线);end at24c08;--结构体--architecture arch_at24c08 of at24c08 issignal clk_sslow : std_logic;signal counter : std_logic_vector(23 downto 0);signal readdata_reg_buf : std_logic_vector(15 downto 0);signal readdata_ten : integer range 0 to 24564;signal readdata_std : std_logic_vector(15 downto 0);signal qian : std_logic_vector(3 downto 0);signal bai : std_logic_vector(3 downto 0);signal shi : std_logic_vector(3 downto 0);signal ge : std_logic_vector(3 downto 0);signal qian_0 : integer range 0 to 10;signal bai_0 : integer range 0 to 10;signal shi_0 : integer range 0 to 10;signal ge_0 : integer range 0 to 10;--数码管部分信号signal sel_0 : std_logic_vector(3 downto 0);signal seg_0 : std_logic_vector(7 downto 0);signal count : std_logic_vector(13 downto 0);signal clk_slow : std_logic;signal scan_num : std_logic_vector(1 downto 0);signal seg_data_buf : std_logic_vector(3 downto 0);--i2c部分信号signal sda_buf : std_logic; --i2c输入/输出数据寄存器signal link : std_logic; --sda输入输出方向寄存器signal readdata_reg : std_logic_vector(15 downto 0);--i2c读回的数据寄存器signal sda_0 : std_logic; --与sda端口连接信号signal scl_0 : std_logic; --与scl端口连接信号--按键消抖部分信号signal delay_cnt : std_logic_vector(19 downto 0); --消抖延时计数器signal start_delay : std_logic; --按键延时开始--分频部分信号signal clk_div : std_logic_vector(12 downto 0); --分频计数器,5000分频,10khz--蜂鸣器部分信号signal beep_en : std_logic; --蜂鸣器使能信号signal beep_buf : std_logic; --与beep端口连接的信号--时钟部分信号signal level_high : std_logic; --高电平中间值,1249 signal level_low : std_logic; --低电平中间值,3749 signal level_hig_edge : std_logic; --上升沿,4999signal level_low_edge : std_logic; --下降沿,2499--状态机部分信号signal main_state : std_logic_vector(1 downto 0); --状态机主状态signal i2c_state : std_logic_vector(2 downto 0); --i2c状态signal i2c_per_state : std_logic_vector(3 downto 0); --i2c每一步状态--分频部分常量constant div_parameter : std_logic_vector(12 downto 0):="1001110001000";--分频系数,500--状态机部分常量--操作状态常量constant read_init : std_logic_vector(2 downto 0) :="000";--EEPORM 初始化constant read_high : std_logic_vector(2 downto 0) :="001";--读高位数据状态constant read_low : std_logic_vector(2 downto 0) :="010";--读低位数据状态--i2c每一步状态常量constant start : std_logic_vector(3 downto 0) :="0000";--开始位constant first : std_logic_vector(3 downto 0) :="0001";--数据第一位constant second : std_logic_vector(3 downto 0) :="0010";--数据第二位constant third : std_logic_vector(3 downto 0) :="0011";--数据第三位constant fourth : std_logic_vector(3 downto 0) :="0100";--数据第四位constant fifth : std_logic_vector(3 downto 0) :="0101";--数据第五位constant sixth : std_logic_vector(3 downto 0) :="0110";--数据第六位constant seventh : std_logic_vector(3 downto 0) :="0111";--数据第七位constant eighth : std_logic_vector(3 downto 0) :="1000";--数据第八位constant ack : std_logic_vector(3 downto 0) :="1001";--应答位constant stop : std_logic_vector(3 downto 0) :="1010";--停止位--结构体开始beginscl <= scl_0;seg <= seg_0;sda_0 <= sda_buf when (link)='1' else 'Z';sda <= sda_0;sel <= sel_0;beep <= beep_buf;--按键消抖key : process(clk,rst)beginif(not rst='1') thendelay_cnt <= (others => '0');elsif (clk'event and clk='1') thenif start_delay='1' thenif(delay_cnt /= "11110100001001000000") then --20ms延时delay_cnt <= delay_cnt+'1';elsedelay_cnt <= (others => '0');end if;end if;end if;end process key;--分频部分div : process(rst,clk)beginif(not rst='1') thenclk_div <= "0000000000000";level_high <= '0';level_low <= '0';level_hig_edge <= '0';level_low_edge <= '0';elsif(clk'event and clk='1') thenif(clk_div /= div_parameter-'1') then clk_div <= clk_div+'1';elseclk_div <= "0000000000000";end if;if(level_high='1') thenlevel_high <= '0';elseif(clk_div="10011100001") thenlevel_high <= '1';end if;end if;if(level_low_edge='1') thenlevel_low_edge <= '0';elseif(clk_div="100111000011") thenlevel_low_edge <= '1';end if;end if;if(level_low='1') thenlevel_low <= '0';elseif(clk_div="111010100101") thenlevel_low <= '1';end if;end if;if(level_hig_edge='1') thenlevel_hig_edge <= '0';elseif(clk_div="1001110000111") thenlevel_hig_edge <= '1';end if;end if;end if;end process div;--EEPROM操作部分state : process(clk,rst)beginif(not rst='1') thenstart_delay <= '0';scl_0 <= '1';sda_buf <= '1';link <= '0';readdata_reg <= "0000000000000000";main_state <= "00";i2c_state <= read_init;i2c_per_state <= start;elsif(clk'event and clk='1') thencase main_state is--初始化EEPROMwhen "00" =>--等待读写要求scl_0 <= '1';sda_buf <= '1';link <= '0';i2c_state <= read_init;i2c_per_state <= start;main_state <= "10";--读取EEPRO数据when "10" =>if(level_hig_edge='1') thenscl_0 <= '1';elseif(level_low_edge='1') thenscl_0 <= '0';end if;end if;case i2c_state iswhen read_init => --读命令地址case i2c_per_state iswhen start =>if(level_high='1') thensda_buf <= '0';link <= '1';end if;if((level_low and link)='1') thenlink <= '1';sda_buf <= '1';i2c_per_state <= first;end if;when first =>if(level_low='1') thensda_buf <= '0';i2c_per_state <= second;end if;when second =>if(level_low='1') thensda_buf <= '0';link <= '1';i2c_per_state <= third;end if;when third =>if(level_low='1') thensda_buf <= '1';link <= '1';i2c_per_state <= fourth;end if;when fourth =>if(level_low='1') thensda_buf <= '0';link <= '1';i2c_per_state <= fifth;end if;when fifth =>if(level_low='1') thensda_buf <= '0';link <= '1';i2c_per_state <= sixth;end if;when sixth =>if(level_low='1') thensda_buf <= '0';i2c_per_state <= seventh;end if;when seventh =>if(level_low='1') thensda_buf <= '1';link <= '1';i2c_per_state <= eighth;end if;when eighth =>if(level_low='1') thenlink <= '0';i2c_per_state <= ack;end if;when ack =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenif(sda_buf='1') thenmain_state <= "00";end if;end if;if(level_low='1') thenlink <= '0';i2c_state <= read_high;i2c_per_state <= first;end if;when others => null;end case;when read_high => --读回数据case i2c_per_state iswhen first =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= second;end if;when second =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= third;end if;when third =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= fourth;end if;when fourth =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= fifth;end if;when fifth =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= sixth;end if;when sixth =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= seventh;end if;when seventh =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= eighth;end if;when eighth =>if(level_hig_edge='1') thensda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(15 downto 9) <= readdata_reg(14 downto 8);readdata_reg(8) <= sda;end if;if(level_low='1') theni2c_per_state <= ack;end if;when ack =>if(level_high='1') thenlink <= '1';sda_buf <= '0';i2c_per_state <= first;i2c_state <= read_low;end if;when others => null;end case;when read_low =>case i2c_per_state iswhen first =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= second;end if;when second =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= third;end if;when third =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= fourth;end if;when fourth =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= fifth;end if;when fifth =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= sixth;end if;when sixth =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= seventh;end if;when seventh =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= eighth;end if;when eighth =>if(level_hig_edge='1') thenlink <= '0';sda_buf <= sda;end if;if(level_high='1') thenreaddata_reg(7 downto 1) <= readdata_reg(6 downto 0);readdata_reg(0) <= sda;end if;if(level_low='1') theni2c_per_state <= ack;end if;when ack =>if(level_high='1') thenlink <= '1';sda_buf <= '1'; --非应答位-- i2c_per_state <= stop;end if;if(level_low='1') thenlink <= '1';sda_buf <= '0';i2c_per_state <= stop;end if;when stop =>if(level_high='1') thenlink <= '1';sda_buf <= '1'; --停止位end if;if(level_low='1') thenmain_state <= "00";end if;when others => null;end case;when others => null;end case;when others => null;end case;end if;end process state;--数据处理部分anly1 : process(readdata_reg_buf)beginreaddata_ten <= conv_integer(readdata_reg_buf)*12;qian_0 <= readdata_ten/1000;bai_0 <= (readdata_ten/100) rem 10;shi_0 <= (readdata_ten/10) rem 10;ge_0 <= readdata_ten rem 10;end process anly1;anly2 : process(qian_0,bai_0,shi_0,ge_0)beginqian <= conv_std_logic_vector(qian_0,4);bai <= conv_std_logic_vector(bai_0,4);shi <= conv_std_logic_vector(shi_0,4);ge <= conv_std_logic_vector(ge_0,4);end process anly2;--数码管显示部分scan : process(rst,clk)beginif(not rst='1') thencount <= (others => '0');clk_slow <= '0';elsif(clk'event and clk='1') thenif(count="11111011011111") thencount <= (others => '0');clk_slow <= not clk_slow;elsecount <= count + '1';end if;end if;end process scan;seg1 : process(clk_slow,rst)beginif(not rst='1') thenscan_num <= "00";elsif(clk_slow'event and clk_slow='1') thenif(scan_num="11") thenscan_num <= "00";elsescan_num <= scan_num + '1';end if;end if;end process seg1;seg2 : process(seg_data_buf)begincase seg_data_buf iswhen "1111" => seg_0 <= "10001110";when "1110" => seg_0 <= "10000110"; when "1101" => seg_0 <= "10100001";when "1100" => seg_0 <= "11000110";when "1011" => seg_0 <= "10000011";when "1010" => seg_0 <= "10011000";when "1001" => seg_0 <= "10010000";when "1000" => seg_0 <= "10000000"; when "0111" => seg_0 <= "11111000"; when "0110" => seg_0 <= "10000010"; when "0101" => seg_0 <= "10010010"; when "0100" => seg_0 <= "10011001"; when "0011" => seg_0 <= "10110000"; when "0010" => seg_0 <= "10100100"; when "0001" => seg_0 <= "11111001"; when "0000" => seg_0 <= "11000000"; when others => seg_0 <= "11111111";end case;end process seg2;seg0 : process(scan_num)begincase scan_num iswhen "00" =>sel_0 <= "1110";seg_data_buf <= ge;when "01" =>sel_0 <= "1101";seg_data_buf <= shi;when "10" =>sel_0 <= "1011";seg_data_buf <= bai;when "11" =>sel_0 <= "0111";seg_data_buf <= qian;when others => null;end case;end process seg0;--数据缓存部分ss : process(clk,rst)beginif(not rst='1') thenclk_sslow <= '0';counter <= (others => '0');elsif(clk'event and clk='1') thenif(counter /= "111111111111111111111110") then counter <= counter + '1';elsecounter <= (others => '0');clk_sslow <= not clk_sslow;end if;end if;end process ss;buf : process(clk_sslow)beginif(clk_sslow'event and clk_sslow='1') thenreaddata_reg_buf <= readdata_reg;elsereaddata_reg_buf <= readdata_reg_buf;end if;end process buf;--蜂鸣器报警部分bep : process(clk,rst)variable count : integer range 0 to 50000; --1KHz方波beginif(not rst='1') thencount := 0;beep_en <= '0';elsif(clk'event and clk='1') thenif(beep_en='1') thencount := count+1;if(count>50000) thencount := 0;beep_buf <= not beep_buf;end if;elseif(not urv_1='1') thenif(readdata_reg>"0000000000000011") thenbeep_en <= '1';end if;elsif(not urv_2='1') thenif(readdata_reg>"1111111111100000") thenbeep_en <= '1';end if;end if;end if;end if;end process bep;end arch_at24c08;(二)测试模块:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity tb is--null;end tb;architecture behv_tb of tb iscomponent at24c08port(clk : in std_logic; --时钟信号rst : in std_logic; --复位信号scl : out std_logic; --i2c时钟线sda : inout std_logic; --i2c数据线urv_1 : in std_logic; --上限值1urv_2 : in std_logic; --上限值2sel : out std_logic_vector(3 downto 0);seg : out std_logic_vector(7 downto 0);beep : out std_logic --蜂鸣器输出信号线);end component;constant clockperiod : time := 20ns;signal clk_tb : std_logic := '0';signal rst_tb : std_logic;signal scl_tb : std_logic;signal sda_tb : std_logic;signal urv_1_tb : std_logic;signal urv_2_tb : std_logic;signal sel_tb : std_logic_vector(3 downto 0);signal seg_tb : std_logic_vector(7 downto 0);signal beep_tb : std_logic;beginmyuit : at24c08 port map(clk => clk_tb,rst => rst_tb,scl => scl_tb,sda => sda_tb,urv_1 => urv_1_tb,urv_2 => urv_2_tb,sel => sel_tb,seg => seg_tb,beep => beep_tb);process(clk_tb)beginclk_tb <= not clk_tb after clockperiod/2;end process;rst_tb <= ‘0',‘1' after 1000ns;end behv_tb;。