描述

这一篇文章是继续上一篇关于stm32的串口中断学习,主要是利用CubeMX对stm32进行配置,完成基于232通信协议的模块检测信息读取

本篇文章最后能达到的效果就是,可以令stm32与基于232协议的模块,进行通信

研发平台:淘宝上购买的野火店铺的一款单片机,名字叫骄阳开发板,核心芯片是
stm32F407IGT6
开发器件:本文使用的传感器,是在淘宝上购买的广州联网科技的磁传感器。需要链接的话可以私信我,在这里就不贴出来了。

学习步骤

  1. 了解什么是232协议
  2. 基于232通信协议的模块,是如何与单片机进行连接与通信的
  3. 利用CubeMX设置stm32的usart串口中断,与该模块完成通信

磁传感器

1. 学习

我们购买到的磁传感器,是一个八位检测通道的传感器。当传感器放置在磁条上方时,如果磁条极性与传感器检测极性相同时,对应通道会产生一个检测数据。当检测数值超过一个设定阈值时,对应通道的led灯会变亮,代表着该通道检测到了磁条。

因此我们不难学习,该传感器具有8个位置检测宽度的能力。每个位置有0和1的变化,我们只要能够从传感器中读到每一个位置,是0还是1,就能判断出磁条在我们机器人下位机的具体位置了,我们的电机也可以根据这个信号的变化进行调整。

2. 传感器设置与连接

设置

根据厂商提供的说明书,我们得知传感器有几个输出数据的模式。首先我们明确这一篇文章的核心点,是学习232通信协议,因此和我们相关的输出模式有两个:一个是变化232输出,一个是连续232输出。其中,变化 232 输出代表参数有变化即输出,连续 232 输出代表间隔 7ms 持续输出。

我们希望磁条传感器在发生数据变化时,返回下位机,随后电机进行相应的调整。如果磁条传感器8个位置的检测值一直没有变化,显然我们的电机最好也不要进行调整。因此我们将传感器设置为变化232输出

连接

我们买到的传感器,有14个接线端口,其中与我们通信连接相关的有5个,电源VCC、电源GND、Tx、Rx、信号GND。

在传感器与电脑之间,使用USB转232的转接线。我们可以查阅232接口的定义,这里不过多展开知识细节。232通信协议使用的DP9接头有9个管脚,上面5针为1-5,下面4针分别为6-9。为了连接磁传感器,232接头的2、3、5需要接线。

具体的接线方式如下:
24V电源正极——磁传感器的1号管脚(VCC)
24V电源负极——磁传感器的2号管脚(GND)
232接口的2号管脚(RXD)——磁传感器的3号管脚(Tx)
232接口的3号管脚(TXD)——磁传感器的4号管脚(Rx)
232接口的5号管脚(GND)——磁传感器的14号管脚(GND)

连接对应管脚后,将转接线的USB一端连接电脑,传感器上24V电。我们打开厂商给的UI调试软件,将波特率设置为115200,设备ID设置为1后。点击“打开端口”和“连接设备”后,可以发现传感器正常工作。

3. 数据的解析

将232转USB连接传感器后,USB接口连接电脑。打开串口调试助手,移动传感器与磁条的相对位置,会发现收到的数据一直是

 01 AB 00 28 00 xx xx xx

根据手册我们可以得知, 01 AB 00 28是厂商设置的通信协议,分别代表的是设备地址、功能码等,这里不解释。后面四个字节,分别代表的是数据高位、数据低位、CNC校验高位、CNC校验低位。我们的传感器是8通道检测的,实际上厂商还有16通道的检测值。数据高位+数据低位,对应的就是这16个通道的0/1状态值,由于我们的是8通道,所以高通道的数据一直是00,这就是原因。CNC校验位我们不去管它,保证校验位正确是厂商的事情,它们要确保发上来的数据校验位正确。按照理论,我们的代码中应该也包含一个CNC校验检测的功能,不过这里先不介绍了。结论:8字节数据的第6个字节,就是8个通道的开关状态值

我们做一下实验,就可以理解数据了。我们将磁条传感器下方放置磁条,传感器从左到右分别为1-8通道。传感器从磁条左侧运动到磁条右侧,也就是第8通道最先接触磁条,1通道最晚接触磁条;8通道最先离开磁条,1通道最晚离开磁条。

以下是这一过程中,我收到的数据,和数据解析。例如第一条数据,左面是收到的hex数据
右面是将第6个字节的数据“80”转成2进制的结果:

01 AB 00 28 00 80 A5 BA        10000000    8号开关点亮
01 AB 00 28 00 C0 A4 4A        11000000    8号继续亮,7号点亮
01 AB 00 28 00 E0 A5 92     11100000
01 AB 00 28 00 F0 A4 5E     11110000
01 AB 00 28 00 F8 A5 98     11111000
01 AB 00 28 00 FC A4 5B     11111100
01 AB 00 28 00 FE 25 9A     11111110
01 AB 00 28 00 FF E4 5A     11111111
01 AB 00 28 00 7F E5 FA     01111111
01 AB 00 28 00 3F E4 0A     00111111
01 AB 00 28 00 1F E5 D2     00011111
01 AB 00 28 00 0F E4 1E     00001111
01 AB 00 28 00 07 E5 D8     00000111
01 AB 00 28 00 03 E4 1B     00000011
01 AB 00 28 00 01 65 DA     00000001
01 AB 00 28 00 00 A4 1A     00000000      1号开关熄灭

研发步骤

  1. 像之前一样,打开CubeMX工程,找到你使用的芯片并新建工程
  2. 翻阅数据手册,找到232串口的端口,该端口用于232通信协议的消息发送及接收;我们从数据手册中发现,该端口是PB10和PB11。我们根据原理图的线路走向,发现PB10是TXD,PB11是RXD。
  3. 我们在CubeMX界面左侧的“Connectivity”中找到“USART3”,将Mode选项从“Disable”变为“Asynchronous”,其他设置不变(不变的原因是,磁传感器的波特率等参数与CubeMx一致)
  4. 打开USART3的串口中断功能,勾选“USART3 global interrupt”
  5. 像之前一样配置工程的其他事项,最后点击生成工程
  6. 打开工程,这里参考上一篇文章,在函数中添加功能代码,用于接收USART的串口数据。我们这里只介绍一下额外增加的部分。
    main.c的头文件部分,添加有关磁传感器参数的定义

     #define MAGNETIC_BUFFER_LEN 8
     uint8_t magnetic_buffer[MAGNETIC_BUFFER_LEN];
     uint8_t Uart6_Rx_Cnt = 0;
    

    在主函数的while循环开始之前,打开usart3的串口数据接收

     HAL_UART_Receive_IT(&huart3, magnetic_buffer, MAGNETIC_BUFFER_LEN);
    

    在用户自定的函数部分,添加usart3串口中断处理的函数。这段代码稍微解释一下,显然我们取接收数据数组第6个值,这就是我们需要的8通道状态量。我们利用一小段while循环,将它解析成了二进制,也就拿到了我们需要的8通道状态值

     void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
     {
           UNUSED(huart);
         if (huart == &huart3)
         {
             uint8_t magnetic_status = magnetic_buffer[5];
             uint8_t magnetic_status_0_1[MAGNETIC_BUFFER_LEN] = {0};
             uint8_t temp = magnetic_status;
             uint8_t i = 0;
             while (temp != 0 )
             {
                 magnetic_status_0_1[i] = temp%2;
                 temp = temp/2;
                 i++;
             }
             printf("magnetic status: ");
             for (int i = 0 ; i < MAGNETIC_BUFFER_LEN; i++)
             {
                 printf("%d",magnetic_status_0_1[i]);
             }
             printf("\n");
    
             HAL_UART_Receive_IT(&huart3, magnetic_buffer, MAGNETIC_BUFFER_LEN);
         }
     }
    
  7. 由于这一篇文章与上一篇文章是相继开发的,因此我们将这篇新增的磁传感器数据读取功能,添加在上一篇文章的工程中。具体添加的内容就是步骤6的代码,我已经写在上面了。这里贴一下增加后的代码截图


  8. 打开串口助手,stm32会首先返回我们设定好的数据。将磁条在传感器附近移动,我们会得到这样的输出,依次显示从第1个通道-第8个通道的状态值
     magnetic status: 01111100
     magnetic status: 01111000
     magnetic status: 11111000
     magnetic status: 11110000
    
  9. 我们的研发成功了。

总结

这篇讲解了,stm32如何利用串口中断功能,完成232协议的消息读取

补充

我们这里使用了stm32单片机上自带的232的DP9接口,使用杜邦线连接了传感器和232接口2、3两个管脚。我们通过这种方式,成功的读取到了传感器232协议的数据。

我们有另外一种办法:就是通过232转ttl模块,然后利用其他的usart管脚(比如说上一篇文章用于接收NFC读取模块的usart6),按理说可以同样完成这篇文章的需求。但实际上,我们将传感器的管脚连接到232转ttl模块的232管脚,再将模块的ttl管脚接到了usart6的Rxd和Txd管脚。这样的连接方式看样子是无误的,但是我没能成功读取到传感器正确的数据,读取到的串口数据是不对的。我查了一下我这个转接模块,使用的芯片是MAX3232,也是没有问题的。

查了一下卖家的评价,发现有人和我一样的问题。目前可以大体判断,是这个模块是坏的。唉,不能贪小便宜啊,浪费了我不少的时间。我目前又买了其他的模块,准备继续测试一下。如果我不回来更新,结论就是模块坏了。