基于STM32设计的炉温温度检测仪
(资料图片)
一、项目背景
随着工业生产的发展,炉温检测在现代化工、钢铁、电子、玻璃等行业中变得越来越重要。对于这些行业,稳定的生产环境和品质稳定的产品是必须的,而炉温是影响产品品质的重要因素之一。如果炉温过高或过低,都有可能导致产品结构改变、硬度变化、强度下降等质量问题,使得产品不能达到预期的性能指标。此外,炉温不仅会影响产品质量,还会影响设备的使用寿命和工作效率,有时甚至会对整个工厂的正常生产造成影响。
为了防止这些问题的发生,现代化工、钢铁、电子、玻璃等行业需要精准测量炉温并实时地监测炉温变化情况。而本项目即是为了满足这些需求而设计的。采用STM32F103C8T6作为主控芯片,它是一款基于ARMCortex-M3内核的微控制器,具有丰富的外设和良好的计算能力,并且易于控制和集成到系统中。同时,铂电阻PT100是一种高精度、稳定性好、线性度高的温度传感器,能够提供更加准确的温度测量结果。采用0.96寸IIC接口的OLED屏幕进行显示,操作简便、节省成本,并且具有较好的兼容性和可移植性。
二、设计思路
【1】硬件设计
主控芯片采用STM32F103C8T6,其内置有多种外设,可满足该项目的需求。铂电阻PT100作为测温传感器,能够提供更加准确的温度测量结果。0.96寸IIC接口的OLED显示屏幕是本项目的显示工具,能够直观地显示测量结果。
【2】软件设计
软件设计分为数据采集、数据处理和数据显示三个部分。采用STM32的ADC进行数据采集,通过PT100将温度信号转换为电阻信号,再通过AD转换器转换成数字信号进行处理。在数据处理中,对ADC采样值进行数据校准、滤波处理和算法计算,得到准确的温度值。最后,通过IIC总线协议将温度值发送给OLED屏幕进行显示,实现实时显示检测结果的功能。
三、代码实现
【1】OLED显示屏代码
以下是基于STM32F103C8T6主控芯片,通过IIC接口控制0.96寸OLED显示屏显示数字的代码:
#include "stm32f10x.h" #include "i2c.h" #define OLED_ADDRESS 0x78 // OLED IIC地址 void oled_init(void) { OLED_Write_Command(0xAE); // 关闭显示 OLED_Write_Command(0xD5); // 设置时钟分频因子 OLED_Write_Command(0x80); // 重要参数,必须设置,不然屏幕无法上电 OLED_Write_Command(0xA8); // 设置驱动路数 OLED_Write_Command(0x3F); // 默认值 OLED_Write_Command(0xD3); // 设置显示偏移 OLED_Write_Command(0x00); // 默认值 OLED_Write_Command(0x40); // 设置起始行 OLED_Write_Command(0x8D); // 电荷泵设置 OLED_Write_Command(0x14); // 开启电荷泵 OLED_Write_Command(0x20); // 设置内存地址模式 OLED_Write_Command(0x00); // 水平模式 OLED_Write_Command(0xA1); // 段重新映射设置 OLED_Write_Command(0xC0); // 设置COM扫描方向 OLED_Write_Command(0xDA); // 设置COM引脚硬件配置 OLED_Write_Command(0x12); // 默认值 OLED_Write_Command(0x81); // 对比度设置 OLED_Write_Command(0xCF); // 默认值 OLED_Write_Command(0xd9); // 设置预充电周期 OLED_Write_Command(0xF1); // 默认值 OLED_Write_Command(0xDB); // 设置VCOMH OLED_Write_Command(0x40); // 默认值 OLED_Write_Command(0xA4); // 关闭全屏点亮 OLED_Write_Command(0xA6); // 设置显示方式 OLED_Write_Command(0xAF); // 开启屏幕显示 } void OLED_Write_Command(uint8_t cmd) { // 写命令 I2C1_Start(); I2C1_SendByte(OLED_ADDRESS); I2C1_SendByte(0x00); I2C1_SendByte(cmd); I2C1_Stop(); } void OLED_Write_Data(uint8_t data) { // 写数据 I2C1_Start(); I2C1_SendByte(OLED_ADDRESS); I2C1_SendByte(0x40); I2C1_SendByte(data); I2C1_Stop(); } void OLED_Set_Pos(uint8_t x, uint8_t y) { // 设置光标位置 OLED_Write_Command(0xb0+y); OLED_Write_Command(((x&0xf0)>>4)|0x10); OLED_Write_Command(x&0x0f); } void OLED_Show_Number(uint8_t x, uint8_t y, uint32_t num) { // 在指定位置显示数字 OLED_Set_Pos(x, y); while (num) { uint8_t temp = num % 10; OLED_Write_Data(temp + "0"); num /= 10; } } int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C1_Init(); oled_init(); OLED_Show_Number(0, 0, 12345); //在第1行第1列显示数字12345 while (1) { } }
首先,通过oled_init()
函数初始化OLED屏幕,在函数中依次写入了一系列命令,来设置OLED的各种参数,例如驱动路数、扫描方向、预充电周期、对比度等。接着,在OLED_Show_Number()
函数中,调用了OLED_Set_Pos()
函数来设置数字显示的位置,然后通过循环取余数的方法将数字逐位分离,再将其转换为字符型并通过OLED_Write_Data()
函数输出到OLED屏幕上,最终实现在屏幕上显示指定数字的功能。
【2】温度测量代码
以下是基于STM32F103C8T6主控芯片,通过IIC接口控制0.96寸OLED显示屏显示温度,并通过串口打印温度的代码:
#include "stm32f10x.h" #include "i2c.h" #include "usart.h" #define OLED_ADDRESS 0x78 // OLED IIC地址 // PT100温度转换函数 float RTD2Temperature(float R) { float temperature = 0; float RTD_A = 3.9083e-003f; float RTD_B = -5.775e-007f; temperature = (-RTD_A + sqrtf(RTD_A * RTD_A - 4 * RTD_B * (1 - R / 100))) / (2 * RTD_B); return temperature; } void oled_init(void) { OLED_Write_Command(0xAE); // 关闭显示 OLED_Write_Command(0xD5); // 设置时钟分频因子 OLED_Write_Command(0x80); // 重要参数,必须设置,不然屏幕无法上电 OLED_Write_Command(0xA8); // 设置驱动路数 OLED_Write_Command(0x3F); // 默认值 OLED_Write_Command(0xD3); // 设置显示偏移 OLED_Write_Command(0x00); // 默认值 OLED_Write_Command(0x40); // 设置起始行 OLED_Write_Command(0x8D); // 电荷泵设置 OLED_Write_Command(0x14); // 开启电荷泵 OLED_Write_Command(0x20); // 设置内存地址模式 OLED_Write_Command(0x00); // 水平模式 OLED_Write_Command(0xA1); // 段重新映射设置 OLED_Write_Command(0xC0); // 设置COM扫描方向 OLED_Write_Command(0xDA); // 设置COM引脚硬件配置 OLED_Write_Command(0x12); // 默认值 OLED_Write_Command(0x81); // 对比度设置 OLED_Write_Command(0xCF); // 默认值 OLED_Write_Command(0xd9); // 设置预充电周期 OLED_Write_Command(0xF1); // 默认值 OLED_Write_Command(0xDB); // 设置VCOMH OLED_Write_Command(0x40); // 默认值 OLED_Write_Command(0xA4); // 关闭全屏点亮 OLED_Write_Command(0xA6); // 设置显示方式 OLED_Write_Command(0xAF); // 开启屏幕显示 } void OLED_Write_Command(uint8_t cmd) { // 写命令 I2C1_Start(); I2C1_SendByte(OLED_ADDRESS); I2C1_SendByte(0x00); I2C1_SendByte(cmd); I2C1_Stop(); } void OLED_Write_Data(uint8_t data) { // 写数据 I2C1_Start(); I2C1_SendByte(OLED_ADDRESS); I2C1_SendByte(0x40); I2C1_SendByte(data); I2C1_Stop(); } void OLED_Set_Pos(uint8_t x, uint8_t y) { // 设置光标位置 OLED_Write_Command(0xb0+y); OLED_Write_Command(((x&0xf0)>>4)|0x10); OLED_Write_Command(x&0x0f); } void OLED_Show_Temperature(uint8_t x, uint8_t y, float temperature) { // 在指定位置显示温度 OLED_Set_Pos(x, y); int temp = (int)(temperature * 10); for (int i = 0; i < 5; i++) { if (i == 2) { OLED_Write_Data("."); } else { OLED_Write_Data(temp % 10 + "0"); temp /= 10; } } OLED_Write_Data("C"); } int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C1_Init(); oled_init(); USART1_Init(); while (1) { float resistance = 100; // 铂电阻的电阻值 float temperature = RTD2Temperature(resistance); // 算出温度值 // OLED显示温度 OLED_Show_Temperature(0, 0, temperature); // 串口输出温度 char str[32]; sprintf(str, "Temperature: %.1f C\\r\\n", temperature); USART1_SendString(str); delay_ms(1000); // 延时1s } }
首先,利用RTD2Temperature()
函数将铂电阻的电阻值转换为温度值。接着,在OLED_Show_Temperature()
函数中,调用了OLED_Set_Pos()
函数来设置温度显示的位置,并将温度值逐位分离,通过OLED_Write_Data()
函数输出到OLED屏幕上,最终实现在屏幕上显示测量的温度的功能。同时,也通过串口输出温度值。
在主函数main()
中,不断循环读取铂电阻的电阻值,并通过RTD2Temperature()
函数转换为温度值。然后,调用OLED_Show_Temperature()
函数将温度显示在OLED屏幕上,并调用USART1_SendString()
函数通过串口输出温度值。最后,通过delay_ms()
函数延时1秒,等待下一次测量。审核编辑:汤梓红
标签: