基于STM32利用串口读取香氛传感器的浓度值,并通过MatLab读取串口数据生成曲线

基于STM32利用串口读取香氛传感器的浓度值,并通过MatLab读取串口数据生成曲线

所需要的元器件/软件

  1. stm32f1c8t6最小核心板;
  2. 杜邦线;
  3. USB-TTL;
  4. 香氛传感器;
  5. MDK5;
  6. llcom串口助手;
  7. flymcu烧写软件;
  8. MatLab。

stm32f1c8t6最小核心板;

最小核心板

香氛传感器以及通讯协议

传感器正面图
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用语法后生成一个完美的目录。
传感器背面图
在这里插入图片描述

香氛传感器的引脚定义:
在这里插入图片描述

通讯设置:
在这里插入图片描述

通讯命令(主动发送):
在这里插入图片描述

ou值的计算
气体浓度值=(气体浓度高位*256+气体浓度低位)*分辨率
分辨率这边为0.1

串口1的配置

串口1初始化:将数据发送到上位机 代码



#include "stm32f10x.h"
#include "usart.h"
#include "sys.h"


#if 1
#pragma import(__use_no_semihosting)             
               
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch,FILE *f)
{
    USART1->SR;  
    USART_SendData(USART1, (unsigned char) ch);
   
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
    
    return(ch);
}
#endif 


//功能:串口1初始化
void uart1_init(u32 bound)   //初始化串口1,函数的参数是波特率
{
  
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING
  GPIO_Init(GPIOA, &GPIO_InitStructure); 

    USART_InitStructure.USART_BaudRate = bound;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    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); 
  USART_Cmd(USART1, ENABLE);                     
}


串口2初始化

串口2初始化:传感器通过串口2读取数据 代码


#include "stm32f10x.h"
#include "uart2.h"
#include "sys.h"
#include "usart.h"

#if 1
#pragma import(__use_no_semihosting)
struct __FILE 
{ 
  int handle;
};
#endif

void uart2_init(u32 bound)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  USART_InitStructure.USART_BaudRate = bound;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  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(USART2, &USART_InitStructure);
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART2, ENABLE);
}

##串口中断触发

串口中断 代码


#define USART2_BUFFER_SIZE 10

u8 USART_RX_BUF[USART2_BUFFER_SIZE];
u8 USART_RX_STA = 0;
static char start = 0;
float ou;


void USART2_IRQHandler(void)
{
  u8 Res = 0;
  
  if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
  {
    Res = USART_ReceiveData(USART2);
    
    if (start == 0)
    {
      if (Res == 0xFF)
      {
        start = 1;
        USART_RX_STA = 0;
      }
    }
    
    if (start == 1)
    {
      USART_RX_BUF[USART_RX_STA] = Res;
      USART_RX_STA++;
      
      if (USART_RX_STA >= 2 && USART_RX_BUF[USART_RX_STA - 1] == 0xFF)
      {
        if (USART_RX_STA >= 9)
        {
      
          ou = (USART_RX_BUF[4] * 256 + USART_RX_BUF[5]) * 0.1;
         
					printf("%.1f\n", ou);

          
          USART_RX_STA = 0;
          start = 0;
        }
      }
      
      if (USART_RX_STA >= USART2_BUFFER_SIZE)
      {
        start = 0;
        USART_RX_STA = 0;
      }
    }
  }
}

上位机演示效果

在这里插入图片描述

Matlab代码:

曲线 代码


% 创建串口对象
s = serial('COM3'); % 将COMx替换为实际的串口号
set(s, 'BaudRate', 9600); % 设置串口波特率
fopen(s);

% 初始化数据缓冲区
N = 100; % 假设数据点的数量为 100
dataBuffer = zeros(N, 1); % N为数据点数

% 创建图形窗口
figure;

% 绘制空曲线
hLine = plot(dataBuffer, '-');
ylim([0, 100]); % 根据实际情况设置y轴范围

% 实时读取和绘制数据
while true
    % 读取数据
    data = fscanf(s, '%f'); % 根据实际的数据格式进行读取

    % 更新数据缓冲区
    dataBuffer = [dataBuffer(2:end); data];

    % 更新曲线数据
    set(hLine, 'YData', dataBuffer);

    % 实时刷新图形
    drawnow;

    % 控制刷新频率,调整延时时间以控制刷新频率
    pause(0.1);
end

% 关闭串口对象
fclose(s);
delete(s);
clear s;

效果展示

在这里插入图片描述

总结

这次的项目难度不大,是我学习的一个分享,后期将继续分享一些可以实战的项目,需要源码的可以留言,非常感谢。

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就爱吃夜宵

您的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值