STM32串口设计与上位机对接技术

一、确定方案和目的

      使用ESP8266或者其它模块串口AT指令是比较常见,今天我们学习如何设计和使用AT指令,方案是:单片机STM32+串口通讯+AT指令+labview上位机,涉及STM32和Labview代码的完整串口数据通讯流程,具体要求如下:

任务:学会使用labview结合STM32语言实现AT指令数据通讯要求:

01.STM32串口基本配置、发送、接收数据的语法;  02.构建STM32单片机的AT指令处理体系  03.学会C语言的字符串处理函数strstr、strcmp函数、atoi函数使用;  03.实现AT接收、AT发送、AT的应答、实现灵活指令;  04.用ESP8266模块实现labview数据的接收和数据的处理;关键词:labview、STM32、ESP8266、strcmp函数、strstr函数、atoi、VISA备注1:手机微信可浏览相关高清图片;80264e4d62524ad38cc082fb8a4ae5cf.png

二、串口通讯原理a9abd84f7bea439bb974f4f8ae88ab81.png 

 

01、串口通讯的底层基础驱动语法内容请自行查询相关教程网站,本教程着重介绍串口的思维方法是功能层面的设计;

02、串口通讯通常是存在3种方式:主动发送不接收,被动接收不发送,被动接收发送反馈;

03、主动发送不接收模式需要定义发送时间和间隔,如不定期的上传数据,不管对方是否收到;

04、被动接收不发送模式是单片机是主机的模式,需要解析接收到的内容,一般用到设置主机某些参数,比如ESP8266的设置wifi参数连接TCP服务器;

05、被动接收发送反馈模式是比较常用的应答模式,保证通讯双方的数据正常;

06、产品通常需要获取数据和设置数据两个操作,而且字符长度不固定,比如Modbus协议和AT指令,RTU模式和ASCII模式;

三、STM32串口注意事项   

if(strcmp(usercmd,"AT")==0)if(strstr(USART2_RX_BUF,"AT+SetDAC")!=NULL)     strbuf = user_after(USART2_RX_BUF,"AT+SetDAC=");    USART2_RX_BUF[uart2_i-2]='\0';

AT指令不固定长度,串口接收函数需要获取到接收的起点终点和长度,同时需要有错误处理、超时恢复机制、超长恢复机制;

        接收指针 uart_i 是存到字符串数组的指针,接收到数据就会加一移动一位,错误会进行指针清零,数据安全的化建议重置覆盖防止内存泄露;

        识别特定规律的字符串指令,AT指令的识别原理是if(当前字符和上一个字符==回车键),识别到回车键只能说明收到一条符合规则的未知指令,这时需要通知进程来处理这个指令;

     USART_RX_STA 标记放在主程序的while中处理,也可以放在中断中处理,建议尽量不要在串口中断中处理;

        收到的未知指令需要识别是具体含义,这里的指令有固定字符的控制指令,有灵活可变的不固定字符的参数传递指令;

        指令有固定字符的控制指令只需要用strcmp函数识别即可,注意函数不能识别回车,所以在收到字符后指针-2再添加字符结束符号;

        指令不固定长度字符的配置指令,需要用strstr函数识别前部分的字符,还要剪切出后面的数据来换算,最后再赋值,比如设置输出电压函数,同样注意strstr函数不能识别回车,所以在收到字符后指针-2再添加字符结束符号;

四、STM32串口收发代码

#include "stm32f10x.h"

#include "stdio.h"

#include "string.h"             //strstr strlen  strcmpchar USART2_RX_BUF[200]="";     //接收缓冲,最大USART_REC_LEN个字节.u8   uart2_i=0;  u16  USART2_REC_LEN=4;  u16  USART2_RX_STA=0;                   //串口字节指针 //接收字节长度//接收状态标记    char * user_after(char *instr,char *markstr)//输入源字符串和目标字段,输出目标字段后面的字符{//剪切处理字符串(指针方法)  char *p;  int i;  if(strstr(instr,markstr)!=NULL){ p=strstr(instr,markstr);  i=strlen(markstr); p+=i;  return p;  }  else{ p=NULL; }}

int main(void){  float i=0.0f;  串口初始化();        //串口初始化   while(1)   {      if(usercmd_en==1)  //   需要重新定义 USART2_RX_STA       {                  //  usercmd 需要重新定义 USART2_RX_BUF         if(strcmp(usercmd,"AT")==0)        printf("ok\r\n");  //应答测试指令        if(strcmp(usercmd,"AT+GetADC")==0) printf("CH1=%f \r\n",读取到的数据);                //读取参数类           if(strstr(USART2_RX_BUF,"AT+SetDAC")!=NULL){      //参数设置类           strbuf = user_after(USART2_RX_BUF,"AT+SetDAC=");           i0buf=atoi(strbuf);           设置模拟输出函数(i0buf);        }            usercmd_en=0;      }         } }

void USART_IRQHandler(void)                  { u8 r;//串口2中断服务程序(正常)字符限制,有结束字符检测,未加入超时清空缓存区  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收中断  {    r =USART_ReceiveData(USART2);//(USART2->DR);     //读取接收到的数据    USART2_RX_BUF[uart2_i++]=r;    if(uart2_i>200)uart2_i=0;                          //数据超过长度    if(r=='\n' && USART2_RX_BUF[uart2_i-2]=='\r')      //判断是否回车,可加入CRC    {        USART2_RX_BUF[uart2_i-2]='\0';                 //加结束符号,将数据去掉回车符号        USART2_REC_LEN=uart2_i-2;                      //记录字符长度        USART2_RX_STA=1;                               //接收到一条未知数据需要处理,#define usercmd_en   USART2_RX_STA 重定义为        uart2_i=0;                                     //清零索引指针    }  }    }

 代码的调试推荐使用编译器软件加仿真模拟软件的方法,然后再实际下载到STM32调试结合串口助手,当串口助手数据不正常要尝试使用逻辑分析仪来观察串口数据波形;下图是仿真软件仿真STM32串口调试7987548ee4034100bf6a6ff560ed8144.png

 

五、上位机串口数据对接

       Labview串口读取最常用的方式是轮询查询读取缓存区的数据(架构代码1),只要将轮询时间调整合适就能实现正常数据接收,只要时间合适接收就没问题,时间合适就可以!

        通过架构代码1来分析轮询读取串口数据的问题:

       在现实应用中串口控制通常是不规定长度的指令,那么运用代码1模式接收数据会出现:短指令正常,长指令出错的情况。那按照最长指令计算等待时间,会发现等待时间变长不能满足响应时间的要求。

e5e7cb2f862744bca86b48e6943190d5.png
4d0c22ceae054e75ab0c5782a274f708.png

01、如何在不影响<实时响应>性能的情况下<适应不同长度>的指令?

02、按照代码2的思想是:运用上位机等待中断方式,独立一个进程作为生产者,短时间接收数据,然后将相邻有效数据拼接起来验证,接收为空时清空缓存(可在代码2中添加验证成功时清空缓存)。

03、接下来进行上位机的实例介绍,选择有成熟协议的ESP8266无线模块进行上位机AT指令的对接:


bb4d0560c2e64c17a1ba7978c8a0e9c9.png

2a71fdbdd1ee4fe191ea603371d7c6cc.png 

 

01、ESP8266AT指令的代码举例,主要是labview发送给主机指令,主机应答到接收数据框,调试助手需要清空接收;

02、该代码是笔者小白级别最初设计,存在缺陷,需要把串口接收功能和用户事件结构设计成两个独立的进程;

03、可以参考使用该labview结构来设计STM32的AT指令对接上位机,注意事件结构进入指定事件一定取消锁定选项不要锁定前面板(锁定后所有前面板局部变量冻结不再实时更新),如果对应事件中用到局部变量数据,会有计算出错现象,还不容易查找错误点,建议尽量多使用数据流设计,减少局部变量的使用;

 

 

 

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值