之间的比较 PT100温度传感器 探针和 DS18B20模块
1) 信号采集的基本原理
① PT100的阻值随温度成比例变化 (温度越高, 阻力越大), 但电阻变化很小, 关于 0.385 哦 / 程度;
② PT100的温度测量范围为-200℃ -200℃, 且在0℃时, 电阻正好等于 100 哦;
③ PT100的工作电流应小于 5 嘛;
④ 虽然PT100的阻值随温度成比例变化, 其变化率 (那是, K值 K值 K值) 在不同的温度范围内是不同的.
2) PT100耐温变化表
3. PT100驱动电路
1) 通过分压法, AD采集PT100电压获取电阻值计算温度
PT100在常温水中的电阻值 (25℃25℃25℃) 是关于 109.89 哦.
单片机输出3.3V电压, 电压除以 PT100 大约为:
109.89 * 0.005 = 0.54945 V
根据AD转换公式转换后的AD值约为:
0.54945 / 3.3 * 4096 = 681.98 ≈ 682
当温度升高一度, 假设 PT100 的电阻仅上升 0.385 哦, 分压的变化值约等于:
0.385 * 0.005 = 0.001925 V
根据AD转换公式转换后的AD值约为:
0.001925 / 3.3 * 4096 = 2.39 ≈ 2
实验中, 发现由于stm32电源3.3V电压不稳定, ADC采集PT100电压波动,分压误差较大. 优化方案是设计恒流源电路. 通过采集PT100的电压和恒流源的电流, 即可求出PT100的阻值, 然后就可以得到温度值.
2) 基于LDO稳压器的恒流源电路 (MD5333)
网上有很多测试PT100的驱动电路, 如直流电桥电路, 基于运算放大器的恒流源电路, ETC. 作者在驱动电路的选择上也花了很多功夫, 考虑到电路板的制作难度和元件数量, 最终选择了基于LDO稳压的恒流源电路 (MD5333). 电路图如下:
在此刻, 硬件选型已基本完成. 使用的开发板是正电Atom F10ZET6 Elite Board
 DS18B20模块
以便测试实时温度与PT100温度对比, 添加DS18B20模块进行校准对比测试
1) DS18B20简介
DS18B20是单总线温度传感器,测试温度范围为-55~+125℃,精度为±0.5℃. 现场温度以单总线数字方式直接传输, 大大提高了系统的抗干扰能力. 可直接读取被测温度, 并可根据实际需求通过简单编程实现9~12位数字值读取方式. 其工作电压范围为3~5.5V, 并且采用多种包装形式, 使系统设置灵活方便. 用户设置的设定分辨率和报警温度存储在EEPROM中,断电后仍然保存.
2) DS18B20工作时序介绍
所有单总线设备都需要严格的信号时序以确保数据完整性. DS18B20有 6 信号类型: 复位脉冲, 响应脉冲, 写 0, 写 1, 读 0 并阅读 1. 所有这些信号, 除了响应脉冲, 是主机发送的同步信号. 并且所有命令和数据都是以字节的低位在前发送.
① 复位脉冲和响应脉冲
单总线上的所有通信均以初始化序列开始. 主机输出低电平并保持低电平至少480us产生复位脉冲. 然后主机释放总线, 4.7K上拉电阻将单总线拉高, 延迟时间15~60us, 并进入接收模式 (接收). 然后DS18B20将总线拉低60~240us,产生低电平响应脉冲.
② 写入时序
写时序包括写 0 计时和写作 1 定时. 所有写入时序至少需要 60us, 两次独立写时序之间至少需要1us恢复时间. 两个写入时序均从主机拉低总线开始. 写 1 定时: 主机输出低电平, 延迟2us, 然后释放总线, 延迟60us. 写 0 定时: 主机输出低电平, 延迟60us, 然后延迟2us释放总线.
③ 读取时序
单总线设备仅在主机发出读时序时才向主机传输数据. 所以, 主机发出读数据命令后, 必须立即生成读取时序,以便从机可以传输数据. 所有读取时序至少需要 60us, 两次独立的读时序之间至少需要1us的恢复时间. 每次读取时序均由主机发起, 这会拉低总线至少 1us. 主机必须在读计时期间释放总线,并在计时开始后15us内采样总线状态. 典型的读时序过程是: 主机输出低电平延时2us, 然后主机切换到输入模式延迟12us, 然后读取单总线当前电平, 然后延迟50us.
了解单总线时序后, 我们看一下DS18B20的典型温度读取过程. DS18B20的典型温度读取流程为: 复位 → 发送 SKIPROM (0xCC) → 发送启动转换命令 (0x44) → 延时 → 复位 → 发送 SKIPROM 命令 (0xCC) → 发送内存命令 (0乙醚) → 读取两个字节的数据 (IE. 温度) 连续→结束.
3) 示意图和CUBEMAX配置
从原理图来看, 可以看到DS18B20通过PG11口使能打开串口打印温度信息
4) 代码部分
代码部分移植了正电Atom的ds18b20库并稍作修改
#ifndef __DS18B20_H
#定义__DS18B20_H
#包括 “蒂姆.h”
/***********************************************************************************/
/* DS18B20引脚定义 */
#定义 DS18B20_DQ_GPIO_PORT GPIOG
#定义 DS18B20_DQ_GPIO_PIN GPIO_PIN_11
#定义DS18B20_DQ_GPIO_CLK_ENABLE() 做{ __HAL_RCC_GPIOG_CLK_ENABLE(); }尽管(0) /* PG口时钟使能 */
/**********************************************************************************************/
/* IO操作功能 */
#定义DS18B20_DQ_OUT(x) 做{ x ? \
HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_RESET); \
}尽管(0) /* 数据端口输出 */
#定义 DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN) /* 数据端口输入 */
uint8_t DS18b20_init(空白); /* 初始化DS18B20 */
uint8_t DS18b20_check(空白); /* 检查DS18B20是否存在 */
短 ds18b20_get_温度(空白);/* 获取温度 */
#恩迪夫
5. 红外遥控模块
1) 无线模块编码协议
红外遥控广泛采用的编码方式有: PWM的NEC协议 (脉宽调制) 和飞利浦 PPM 的 RC-5 协议 (脉冲位置调制). 开发板自带的遥控器采用NEC协议, 它具有以下特点:
1. 8-位地址和8位指令长度;
2. 地址和命令传输两次 (确保可靠性);
3. PWM脉冲位置调制, 传输的红外载波的占空比代表 “0” 和 “1”;
4. 载波频率为38Khz;
5. 位时间为1.125ms或2.25ms;
在NEC协议中, 如何将协议中的数据设置为 ‘0’ 或“1”? 这里, 红外接收器和红外发射器分离.
红外发射器: 发送协议数据‘0’=载波信号传输560us + 560使用无载波信号传输
发送协议数据‘1’=载波信号传输560us + 1680使用无载波信号传输
红外发射器的位定义如下图所示
红外接收头: 接收协议数据‘0’=560us低电平 + 560美国高层
接收协议数据‘1’=560us低电平 + 1680美国高层
NEC远程控制命令的数据格式为: 同步终端, 地址码, 地址反码, 控制码, 控制反码. 同步码由9ms低电平和4.5ms高电平组成. 地址代码, 地址反码, 控制码, 和控制反码都是8位数据格式. 按低位在先、高位在后的顺序发送. 使用反码来增加传输的可靠性.
所以, 输入捕捉可测量高电平脉宽,实现遥控解码.
2) 示意图和CUBEMAX配置
从原理图来看, 我们可以看到无线模块通过PB9引脚使能并通过 4 TIM4通道:
TIM4_CH4的默认引脚不是PB9, 所以需要手动设置, 并且同时开启中断设置
3) 代码部分
通过tim回调函数捕获上升沿
此时, 可以得到解码信号:
此时, 数据比较复杂,可以稍微处理一下:
效果如下:
最后两位是解码后的码及其反码. 此时, 可以定义一个宏来调整温度阈值:
效果如下:
红外部分代码:
/* 用户代码开始标题 */
/**
******************************************************************************
* @文件 : 主程序
* @简短的 : 主程序体
******************************************************************************
* @注意力
*
* <小时2><中心>&复制; 版权 (c) 2024 意法半导体.
* 版权所有。</中心></小时2>
*
* 该软件组件由 ST 根据 BSD 3-Clause 许可证获得许可,
* 这 “执照”; 除非遵守以下规定,否则您不得使用此文件
* 执照. 您可以在以下位置获取许可证副本::
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* 用户代码结束标头 */
/* 包括 ——————————————————————*/
#包括 “主程序.h”
#包括 “蒂姆.h”
#包括 “usart.h”
#包括 “GPIO.h”
/* 私人包括 ———————————————————-*/
/* 用户代码开始包括 */
#包括 “stdio.h”
#包括 “字符串.h”
#定义最大 157
#定义最大下降 87
#定义 MINUP 221
#定义 MINDOWN 61
/* 用户代码结束 包括 */
/* 私有类型定义 ———————————————————–*/
/* 用户代码开始 PTD */
/* 用户代码结束 PTD */
/* 私人定义 ————————————————————*/
/* 用户代码开始 PD */
/* 用户代码结束 PD */
/* 私有宏 ————————————————————-*/
/* 用户代码开始 PM */
/* 用户代码 结束 PM */
/* 私有变量 ———————————————————*/
/* 用户代码开始PV */
uint32_t upCount=0;
uint16_t ValueUp=0;
uint16_t ValueDown=0;
uint8_t isUpCapt=1;
uint16_t 宽度=0;
uint16_t 缓冲区[128]={0};
uint16_t bufferId=0;
uint8_t rcvFalg=0;
/* 用户代码结束PV */
/* 私有函数原型 ———————————————–*/
无效系统时钟_配置(空白);
/* 用户代码开始 PFP */
/* 用户代码结束 PFP */
/* 私人用户代码 ———————————————————*/
/* 用户代码开始 0 */
无效 HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
向上计数++;
}
无效 HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
如果(是上尉)//如果是上升沿捕获
{
ValueUp=HAL_TIM_ReadCapturedValue(赫蒂姆,TIM_CHANNEL_4);
isUpCapt=0;
__HAL_TIM_SET_CAPTUREPOLARITY(赫蒂姆,TIM_CHANNEL_4、TIM_ICPOLARITY_FALLING);
向上计数=0;
}
别的{
ValueDown=HAL_TIM_ReadCapturedValue(赫蒂姆,TIM_CHANNEL_4);
isUpCapt=1;
__HAL_TIM_SET_CAPTUREPOLARITY(赫蒂姆,TIM_CHANNEL_4、TIM_ICPOLARITY_RISING);
宽度=ValueDown+upCount*65536-ValueUp;
如果(宽度>4400&&宽度<4600)
{
缓冲区ID=0;
缓冲[缓冲区ID++]=宽度;
}
否则如果(缓冲区ID>0)
{
缓冲[缓冲区ID++]=宽度;
如果(缓冲区ID>32)
{
rcvFalg=1;
缓冲区ID=0;
}
}
}
}
无效位缓冲区2num(字符数[])
{
编号[0]=0;
编号[1]=0;
编号[2]=0;
编号[3]=0;
为了(整数i=0;我<32;我++)
{
如果(缓冲[我+1]<1000)
{
编号[我/8]=数字[我/8]<<1;
}
别的
{
编号[我/8]=数字[我/8]<<1;
编号[我/8]|=0x01;
}
}
}
/* 用户代码结束 0 */
/**
* @brief 应用程序入口点.
* @retval整数
*/
整型主(空白)
{
/* 用户代码开始 1 */
字符打印缓冲区[128]={0};
字符数[4]={0};
字符键=0;
/* 用户代码结束 1 */
/* 单片机配置——————————————————–*/
/* 重置所有外设, 初始化Flash接口和Systick. */
HAL_初始化();
/* 用户代码开始初始化 */
/* 用户代码结束初始化 */
/* 配置系统时钟 */
系统时钟配置();
/* 用户代码开始 SysInit */
/* 用户代码结束 SysInit */
/* 初始化所有配置的外设 */
MX_GPIO_初始化();
MX_TIM4_初始化();
MX_USART1_UART_Init();
/* 用户代码开始 2 */
/* 用户代码结束 2 */
/* 无限循环 */
/* 用户代码开始同时 */
HAL_GPIO_TogglePin(LED0_GPIO_端口,LED0_引脚);
HAL_TIM_Base_Start_IT(&赫蒂姆4);//定时器更新产生中断
HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_4);//
尽管 (1)
{
如果(接收错误)
{
为了(整数i=0;我<4;我++)
{
位缓冲区2个数(编号);
冲刺函数(打印缓冲区,”0xx “,编号[我]);
HAL_UART_传输(&huart1,打印缓冲区,斯特伦(打印缓冲区),HAL_MAX_DELAY);
}
// 冲刺函数(打印缓冲区,”%你 “,缓冲[我]);
// HAL_UART_传输(&huart1,打印缓冲区,斯特伦(打印缓冲区),HAL_MAX_DELAY);
// }
HAL_UART_传输(&huart1,”\rn”,2,HAL_MAX_DELAY);
rcvFalg=0;
}
打印函数(“%drn”,编号[3]);
如果(编号[3]==157)
{
打印函数(“111111\rn”);
}
HAL_延迟(1000);
/* 用户代码结束同时 */
/* 用户代码开始 3 */
}
/* 用户代码结束 3 */
}
/**
* @brief系统时钟配置
* @retval 无
*/
无效系统时钟_配置(空白)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 English
 English Afrikaans
 Afrikaans العربية
 العربية বাংলা
 বাংলা bosanski jezik
 bosanski jezik Български
 Български Català
 Català 粤语
 粤语 中文(简体)
 中文(简体) 中文(漢字)
 中文(漢字) Hrvatski
 Hrvatski Čeština
 Čeština Nederlands
 Nederlands Eesti keel
 Eesti keel Suomi
 Suomi Français
 Français Deutsch
 Deutsch Ελληνικά
 Ελληνικά हिन्दी; हिंदी
 हिन्दी; हिंदी Magyar
 Magyar Bahasa Indonesia
 Bahasa Indonesia Italiano
 Italiano 日本語
 日本語 한국어
 한국어 Latviešu valoda
 Latviešu valoda Lietuvių kalba
 Lietuvių kalba македонски јазик
 македонски јазик Bahasa Melayu
 Bahasa Melayu Norsk
 Norsk پارسی
 پارسی Polski
 Polski Português
 Português Română
 Română Русский
 Русский Cрпски језик
 Cрпски језик Slovenčina
 Slovenčina Slovenščina
 Slovenščina Español
 Español Svenska
 Svenska ภาษาไทย
 ภาษาไทย Türkçe
 Türkçe Українська
 Українська اردو
 اردو Tiếng Việt
 Tiếng Việt 
	 
						
					








