爐溫檢測在現(xiàn)代工業(yè)生產(chǎn)中十分重要,因為爐溫過高或過低都會對產(chǎn)品質量產(chǎn)生影響,甚至影響工廠的正常運作。因此,設計一款能夠精準測量爐溫并顯示結果的檢測儀器具有很大的實用價值。
本項目采用了STM32F103C8T6作為主控芯片,該芯片擁有豐富的外設和性能較好的計算能力,能夠滿足該項目對計算和控制的需求。同時,鉑電阻PT100作為測溫傳感器,能夠提供更加精準的溫度測量結果。
一、項目背景
隨著工業(yè)生產(chǎn)的發(fā)展,爐溫檢測在現(xiàn)代化工、鋼鐵、電子、玻璃等行業(yè)中變得越來越重要。對于這些行業(yè),穩(wěn)定的生產(chǎn)環(huán)境和品質穩(wěn)定的產(chǎn)品是必須的,而爐溫是影響產(chǎn)品品質的重要因素之一。如果爐溫過高或過低,都有可能導致產(chǎn)品結構改變、硬度變化、強度下降等質量問題,使得產(chǎn)品不能達到預期的性能指標。此外,爐溫不僅會影響產(chǎn)品質量,還會影響設備的使用壽命和工作效率,有時甚至會對整個工廠的正常生產(chǎn)造成影響。
為了防止這些問題的發(fā)生,現(xiàn)代化工、鋼鐵、電子、玻璃等行業(yè)需要精準測量爐溫并實時地監(jiān)測爐溫變化情況。而本項目即是為了滿足這些需求而設計的。采用STM32F103C8T6作為主控芯片,它是一款基于ARM Cortex-M3內核的微控制器,具有豐富的外設和良好的計算能力,并且易于控制和集成到系統(tǒng)中。同時,鉑電阻PT100是一種高精度、穩(wěn)定性好、線性度高的溫度傳感器,能夠提供更加準確的溫度測量結果。采用0.96寸IIC接口的OLED屏幕進行顯示,操作簡便、節(jié)省成本,并且具有較好的兼容性和可移植性。
二、設計思路
【1】硬件設計
主控芯片采用STM32F103C8T6,其內置有多種外設,可滿足該項目的需求。鉑電阻PT100作為測溫傳感器,能夠提供更加準確的溫度測量結果。0.96寸IIC接口的OLED顯示屏幕是本項目的顯示工具,能夠直觀地顯示測量結果。
【2】軟件設計
軟件設計分為數(shù)據(jù)采集、數(shù)據(jù)處理和數(shù)據(jù)顯示三個部分。采用STM32的ADC進行數(shù)據(jù)采集,通過PT100將溫度信號轉換為電阻信號,再通過AD轉換器轉換成數(shù)字信號進行處理。在數(shù)據(jù)處理中,對ADC采樣值進行數(shù)據(jù)校準、濾波處理和算法計算,得到準確的溫度值。最后,通過IIC總線協(xié)議將溫度值發(fā)送給OLED屏幕進行顯示,實現(xiàn)實時顯示檢測結果的功能。
三、代碼實現(xiàn)
【1】OLED顯示屏代碼
以下是基于STM32F103C8T6主控芯片,通過IIC接口控制0.96寸OLED顯示屏顯示數(shù)字的代碼:
#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); // 重要參數(shù),必須設置,不然屏幕無法上電
OLED_Write_Command(0xA8); // 設置驅動路數(shù)
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) { // 寫數(shù)據(jù)
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) { // 在指定位置顯示數(shù)字
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列顯示數(shù)字12345
while (1) {
}
}
首先,通過oled_init()
函數(shù)初始化OLED屏幕,在函數(shù)中依次寫入了一系列命令,來設置OLED的各種參數(shù),例如驅動路數(shù)、掃描方向、預充電周期、對比度等。接著,在OLED_Show_Number()
函數(shù)中,調用了OLED_Set_Pos()
函數(shù)來設置數(shù)字顯示的位置,然后通過循環(huán)取余數(shù)的方法將數(shù)字逐位分離,再將其轉換為字符型并通過OLED_Write_Data()
函數(shù)輸出到OLED屏幕上,最終實現(xiàn)在屏幕上顯示指定數(shù)字的功能。
【2】溫度測量代碼
以下是基于STM32F103C8T6主控芯片,通過IIC接口控制0.96寸OLED顯示屏顯示溫度,并通過串口打印溫度的代碼:
#include "stm32f10x.h"
#include "i2c.h"
#include "usart.h"
#define OLED_ADDRESS 0x78 // OLED IIC地址
// PT100溫度轉換函數(shù)
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); // 重要參數(shù),必須設置,不然屏幕無法上電
OLED_Write_Command(0xA8); // 設置驅動路數(shù)
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) { // 寫數(shù)據(jù)
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 Crn", temperature);
USART1_SendString(str);
delay_ms(1000); // 延時1s
}
}
利用RTD2Temperature()
函數(shù)將鉑電阻的電阻值轉換為溫度值。接著,在OLED_Show_Temperature()
函數(shù)中,調用了OLED_Set_Pos()
函數(shù)來設置溫度顯示的位置,并將溫度值逐位分離,通過OLED_Write_Data()
函數(shù)輸出到OLED屏幕上,最終實現(xiàn)在屏幕上顯示測量的溫度的功能。同時,也通過串口輸出溫度值。
在主函數(shù)main()
中,不斷循環(huán)讀取鉑電阻的電阻值,并通過RTD2Temperature()
函數(shù)轉換為溫度值。然后,調用OLED_Show_Temperature()
函數(shù)將溫度顯示在OLED屏幕上,并調用USART1_SendString()
函數(shù)通過串口輸出溫度值。最后,通過delay_ms()
函數(shù)延時1秒,等待下一次測量。