一、項(xiàng)目背景
隨著工業(yè)生產(chǎn)的發(fā)展,爐溫檢測(cè)在現(xiàn)代化工、鋼鐵、電子、玻璃等行業(yè)中變得越來越重要。對(duì)于這些行業(yè),穩(wěn)定的生產(chǎn)環(huán)境和品質(zhì)穩(wěn)定的產(chǎn)品是必須的,而爐溫是影響產(chǎn)品品質(zhì)的重要因素之一。如果爐溫過高或過低,都有可能導(dǎo)致產(chǎn)品結(jié)構(gòu)改變、硬度變化、強(qiáng)度下降等質(zhì)量問題,使得產(chǎn)品不能達(dá)到預(yù)期的性能指標(biāo)。此外,爐溫不僅會(huì)影響產(chǎn)品質(zhì)量,還會(huì)影響設(shè)備的使用壽命和工作效率,有時(shí)甚至?xí)?duì)整個(gè)工廠的正常生產(chǎn)造成影響。
為了防止這些問題的發(fā)生,現(xiàn)代化工、鋼鐵、電子、玻璃等行業(yè)需要精準(zhǔn)測(cè)量爐溫并實(shí)時(shí)地監(jiān)測(cè)爐溫變化情況。而本項(xiàng)目即是為了滿足這些需求而設(shè)計(jì)的。采用STM32F103C8T6作為主控芯片,它是一款基于ARM Cortex-M3內(nèi)核的微控制器,具有豐富的外設(shè)和良好的計(jì)算能力,并且易于控制和集成到系統(tǒng)中。同時(shí),鉑電阻PT100是一種高精度、穩(wěn)定性好、線性度高的溫度傳感器,能夠提供更加準(zhǔn)確的溫度測(cè)量結(jié)果。采用0.96寸IIC接口的OLED屏幕進(jìn)行顯示,操作簡(jiǎn)便、節(jié)省成本,并且具有較好的兼容性和可移植性。
二、設(shè)計(jì)思路
【1】硬件設(shè)計(jì)
主控芯片采用STM32F103C8T6,其內(nèi)置有多種外設(shè),可滿足該項(xiàng)目的需求。鉑電阻PT100作為測(cè)溫傳感器,能夠提供更加準(zhǔn)確的溫度測(cè)量結(jié)果。0.96寸IIC接口的OLED顯示屏幕是本項(xiàng)目的顯示工具,能夠直觀地顯示測(cè)量結(jié)果。
【2】軟件設(shè)計(jì)
軟件設(shè)計(jì)分為數(shù)據(jù)采集、數(shù)據(jù)處理和數(shù)據(jù)顯示三個(gè)部分。采用STM32的ADC進(jìn)行數(shù)據(jù)采集,通過PT100將溫度信號(hào)轉(zhuǎn)換為電阻信號(hào),再通過AD轉(zhuǎn)換器轉(zhuǎn)換成數(shù)字信號(hào)進(jìn)行處理。在數(shù)據(jù)處理中,對(duì)ADC采樣值進(jìn)行數(shù)據(jù)校準(zhǔn)、濾波處理和算法計(jì)算,得到準(zhǔn)確的溫度值。最后,通過IIC總線協(xié)議將溫度值發(fā)送給OLED屏幕進(jìn)行顯示,實(shí)現(xiàn)實(shí)時(shí)顯示檢測(cè)結(jié)果的功能。
三、代碼實(shí)現(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); // 關(guān)閉顯示
OLED_Write_Command(0xD5); // 設(shè)置時(shí)鐘分頻因子
OLED_Write_Command(0x80); // 重要參數(shù),必須設(shè)置,不然屏幕無法上電
OLED_Write_Command(0xA8); // 設(shè)置驅(qū)動(dòng)路數(shù)
OLED_Write_Command(0x3F); // 默認(rèn)值
OLED_Write_Command(0xD3); // 設(shè)置顯示偏移
OLED_Write_Command(0x00); // 默認(rèn)值
OLED_Write_Command(0x40); // 設(shè)置起始行
OLED_Write_Command(0x8D); // 電荷泵設(shè)置
OLED_Write_Command(0x14); // 開啟電荷泵
OLED_Write_Command(0x20); // 設(shè)置內(nèi)存地址模式
OLED_Write_Command(0x00); // 水平模式
OLED_Write_Command(0xA1); // 段重新映射設(shè)置
OLED_Write_Command(0xC0); // 設(shè)置COM掃描方向
OLED_Write_Command(0xDA); // 設(shè)置COM引腳硬件配置
OLED_Write_Command(0x12); // 默認(rèn)值
OLED_Write_Command(0x81); // 對(duì)比度設(shè)置
OLED_Write_Command(0xCF); // 默認(rèn)值
OLED_Write_Command(0xd9); // 設(shè)置預(yù)充電周期
OLED_Write_Command(0xF1); // 默認(rèn)值
OLED_Write_Command(0xDB); // 設(shè)置VCOMH
OLED_Write_Command(0x40); // 默認(rèn)值
OLED_Write_Command(0xA4); // 關(guān)閉全屏點(diǎn)亮
OLED_Write_Command(0xA6); // 設(shè)置顯示方式
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) { // 設(shè)置光標(biāo)位置
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ù)中依次寫入了一系列命令,來設(shè)置OLED的各種參數(shù),例如驅(qū)動(dòng)路數(shù)、掃描方向、預(yù)充電周期、對(duì)比度等。接著,在OLED_Show_Number()
函數(shù)中,調(diào)用了OLED_Set_Pos()
函數(shù)來設(shè)置數(shù)字顯示的位置,然后通過循環(huán)取余數(shù)的方法將數(shù)字逐位分離,再將其轉(zhuǎn)換為字符型并通過OLED_Write_Data()
函數(shù)輸出到OLED屏幕上,最終實(shí)現(xiàn)在屏幕上顯示指定數(shù)字的功能。
【2】溫度測(cè)量代碼
以下是基于STM32F103C8T6主控芯片,通過IIC接口控制0.96寸OLED顯示屏顯示溫度,并通過串口打印溫度的代碼:
#include "stm32f10x.h"
#include "i2c.h"
#include "usart.h"
?
#define OLED_ADDRESS 0x78 // OLED IIC地址
?
// PT100溫度轉(zhuǎn)換函數(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); // 關(guān)閉顯示
OLED_Write_Command(0xD5); // 設(shè)置時(shí)鐘分頻因子
OLED_Write_Command(0x80); // 重要參數(shù),必須設(shè)置,不然屏幕無法上電
OLED_Write_Command(0xA8); // 設(shè)置驅(qū)動(dòng)路數(shù)
OLED_Write_Command(0x3F); // 默認(rèn)值
OLED_Write_Command(0xD3); // 設(shè)置顯示偏移
OLED_Write_Command(0x00); // 默認(rèn)值
OLED_Write_Command(0x40); // 設(shè)置起始行
OLED_Write_Command(0x8D); // 電荷泵設(shè)置
OLED_Write_Command(0x14); // 開啟電荷泵
OLED_Write_Command(0x20); // 設(shè)置內(nèi)存地址模式
OLED_Write_Command(0x00); // 水平模式
OLED_Write_Command(0xA1); // 段重新映射設(shè)置
OLED_Write_Command(0xC0); // 設(shè)置COM掃描方向
OLED_Write_Command(0xDA); // 設(shè)置COM引腳硬件配置
OLED_Write_Command(0x12); // 默認(rèn)值
OLED_Write_Command(0x81); // 對(duì)比度設(shè)置
OLED_Write_Command(0xCF); // 默認(rèn)值
OLED_Write_Command(0xd9); // 設(shè)置預(yù)充電周期
OLED_Write_Command(0xF1); // 默認(rèn)值
OLED_Write_Command(0xDB); // 設(shè)置VCOMH
OLED_Write_Command(0x40); // 默認(rèn)值
OLED_Write_Command(0xA4); // 關(guān)閉全屏點(diǎn)亮
OLED_Write_Command(0xA6); // 設(shè)置顯示方式
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) { // 設(shè)置光標(biāo)位置
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); // 延時(shí)1s
}
}
首先,利用RTD2Temperature()
函數(shù)將鉑電阻的電阻值轉(zhuǎn)換為溫度值。接著,在OLED_Show_Temperature()
函數(shù)中,調(diào)用了OLED_Set_Pos()
函數(shù)來設(shè)置溫度顯示的位置,并將溫度值逐位分離,通過OLED_Write_Data()
函數(shù)輸出到OLED屏幕上,最終實(shí)現(xiàn)在屏幕上顯示測(cè)量的溫度的功能。同時(shí),也通過串口輸出溫度值。
在主函數(shù)main()
中,不斷循環(huán)讀取鉑電阻的電阻值,并通過RTD2Temperature()
函數(shù)轉(zhuǎn)換為溫度值。然后,調(diào)用OLED_Show_Temperature()
函數(shù)將溫度顯示在OLED屏幕上,并調(diào)用USART1_SendString()
函數(shù)通過串口輸出溫度值。最后,通過delay_ms()
函數(shù)延時(shí)1秒,等待下一次測(cè)量。
審核編輯:湯梓紅
-
微控制器
+關(guān)注
關(guān)注
48文章
7467瀏覽量
150882 -
傳感器
+關(guān)注
關(guān)注
2546文章
50498瀏覽量
751195 -
單片機(jī)
+關(guān)注
關(guān)注
6030文章
44500瀏覽量
632178 -
STM32
+關(guān)注
關(guān)注
2264文章
10858瀏覽量
354392 -
檢測(cè)儀
+關(guān)注
關(guān)注
5文章
4061瀏覽量
42177
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論