基于stm32f103c8t6的红外测温仪如何实现
时间: 2023-09-21 07:05:40 浏览: 121
要基于STM32F103C8T6实现红外测温仪,一般需要以下步骤:
1. 选择合适的红外传感器模块,比如MLX90614或AMG8833。
2. 连接红外传感器模块到STM32F103C8T6开发板上,可以使用I2C或SPI接口进行通信。
3. 编写STM32的代码,实现与红外传感器模块的通信,并读取红外传感器模块返回的温度数据。
4. 将读取到的温度数据进行处理,比如转换为摄氏度或华氏度等单位,并显示在LCD屏幕上或通过串口发送到PC端。
5. 根据需要,可以添加其他功能,比如设置报警阈值、记录历史温度数据等。
需要注意的是,红外测温仪需要在正确的环境下进行校准,以保证测量结果的准确性。同时,为了避免干扰,还需要将红外测温仪放置在恰当的位置上,远离其他热源和光源。
相关问题
非接触式stm32f103c8t6红外测温枪usb接口说明
非接触式STM32F103C8T6红外测温枪是一款使用红外线技术进行测温的设备,通过USB接口与主机进行连接和通讯。它主要适用于测量人体、动物、食物、水和其它物体的表面温度。
这款红外测温枪采用STM32F103C8T6芯片,具有高速、低功耗、高性能的特点,并且支持USB接口通信,能够快速进行数据传输和控制。用户只需要将红外测温枪通过USB接口与主机连接,即可进行实时测温操作。
该设备通过非接触式红外测温技术,可以在较远的距离内进行测温,无需接触被测物体,因此更加安全和卫生。另外,红外测温枪还具有高灵敏度和快速测温的特点,能够迅速获取被测物体的温度,大大提高了测温的效率和准确性。
在使用过程中,用户只需要将红外测温枪对准目标物体,触发测温按钮,即可在主机上显示出被测物体的温度数据。通过USB接口,可以实现测温数据的传输和存储,同时还可以通过主机进行参数设置和控制,非常方便实用。
总之,非接触式STM32F103C8T6红外测温枪通过USB接口与主机连接,具有高性能、高灵敏度和快速测温等特点,是一款非常实用的测温设备。
基于stm32f103c8t6的红外测温仪代码
以下为基于STM32F103C8T6的红外测温仪的代码,主要使用了STM32的定时器、ADC、UART等模块:
```c
#include "stm32f10x.h"
#include "stdio.h"
#define USART_REC_LEN 20 //定义串口接收缓冲区大小
#define TEMP_AMBIENT_ADDR 0x00 //环境温度寄存器地址
#define TEMP_OBJECT_ADDR 0x01 //物体温度寄存器地址
uint8_t USART_RX_BUF[USART_REC_LEN]; //串口接收缓冲区
uint16_t USART_RX_STA = 0; //串口接收状态标志
void USART1_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1、GPIOA时钟
//USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = 115200; //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
}
void TIM3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //TIM3时钟使能
TIM_TimeBaseStructure.TIM_Period = 199; //定时器周期200us
TIM_TimeBaseStructure.TIM_Prescaler = 71; //预分频器72,即72MHz/72 = 1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
void ADC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); //使能ADC1、GPIOA时钟
//PA.0 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
//ADC1 初始化设置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //1个转换在规则序列中
ADC_Init(ADC1, &ADC_InitStructure);
//使能指定的ADC1的DMA传输
ADC_DMACmd(ADC1, ENABLE);
//启动ADC1校准
ADC_ResetCalibration(ADC1); //复位校准寄存器
while (ADC_GetResetCalibrationStatus(ADC1))
; //等待校准寄存器复位完成
ADC_StartCalibration(ADC1); //开始校准
while (ADC_GetCalibrationStatus(ADC1))
; //等待校准完成
//开启ADC1
ADC_Cmd(ADC1, ENABLE);
}
uint16_t Get_Adc(uint8_t ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
//启动指定的ADC转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
//等待转换完成
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
;
//返回最近一次ADC1规则组的转换结果
return ADC_GetConversionValue(ADC1);
}
uint16_t readTemp(uint8_t addr)
{
uint16_t data;
I2C_Start();
I2C_Send_Byte(0x5a << 1 | 0); //发送写命令
if (I2C_Wait_Ack() != 0)
return 0xffff; //接收应答失败,退出
I2C_Send_Byte(addr); //发送寄存器地址
I2C_Wait_Ack(); //等待应答
I2C_Start(); //重新启动一次总线
I2C_Send_Byte(0x5a << 1 | 1); //发送读命令
I2C_Wait_Ack(); //等待应答
data = I2C_Read_Byte(0); //读取数据
I2C_Stop(); //停止总线
return data;
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
static uint8_t i = 0;
USART_RX_BUF[i++] = USART_ReceiveData(USART1);
if (USART_RX_BUF[i - 1] == '\n') //接收到换行符
{
USART_RX_STA |= 1 << 15; //标志接收完成
USART_RX_BUF[i - 1] = 0; //将换行符替换为字符串结束符
i = 0; //重新开始接收
}
}
}
void USART_Send_Str(char *str)
{
while (*str)
{
while ((USART1->SR & 0X40) == 0) //等待上一次发送完成
;
USART1->DR = (u8)*str++;
}
}
int main(void)
{
uint16_t raw;
float temp_ambient, temp_object;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //优先级分组设置
USART1_Init(); //初始化串口1
TIM3_Init(); //初始化定时器3
ADC1_Init(); //初始化ADC1
I2C_GPIO_Config(); //初始化I2C总线
delay_init(); //延时函数初始化
while (1)
{
TIM_SetCounter(TIM3, 0); //计数器清零
GPIO_ResetBits(GPIOA, GPIO_Pin_6); //拉低SCL
while (TIM_GetCounter(TIM3) < 5); //等待5us
GPIO_SetBits(GPIOA, GPIO_Pin_6); //拉高SCL
while (TIM_GetCounter(TIM3) < 10); //等待10us
GPIO_ResetBits(GPIOA, GPIO_Pin_6); //拉低SCL
raw = Get_Adc(0); //采集环境温度
temp_ambient = (float)raw * 3.3 / 4096 * 100 - 273.15; //计算环境温度
raw = readTemp(TEMP_OBJECT_ADDR); //读取物体温度
if (raw == 0xffff) //读取失败
{
USART_Send_Str("read object temperature failed!\r\n");
delay_ms(1000);
continue;
}
temp_object = (float)(raw & 0x7fff) * 0.02 - 273.15; //计算物体温度
if (raw & 0x8000) //负温度
{
temp_object = -temp_object;
}
printf("ambient temperature:%.2fC, object temperature:%.2fC\r\n", temp_ambient, temp_object);
delay_ms(1000);
}
}
```
在此代码中,我们使用了定时器3来产生红外测温仪所需的时序信号,使用ADC1来采集环境温度,使用I2C总线读取红外传感器的物体温度。同时,我们通过串口1将温度数据发送至PC端进行显示。
阅读全文