日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【教程】STM32串口設(shè)計(jì)與上位機(jī)對(duì)接技術(shù)

 西北望msm66g9f 2024-05-13 發(fā)布于山東
圖片
一、確定方案和目的

      使用ESP8266或者其它模塊串口AT指令是比較常見,今天我們學(xué)習(xí)如何設(shè)計(jì)和使用AT指令,方案是:?jiǎn)纹瑱C(jī)STM32+串口通訊+AT指令+labview上位機(jī),涉及STM32和Labview代碼的完整串口數(shù)據(jù)通訊流程,具體要求如下:

任務(wù):學(xué)會(huì)使用labview結(jié)合STM32語言實(shí)現(xiàn)AT指令數(shù)據(jù)通訊要求:  01.STM32串口基本配置、發(fā)送、接收數(shù)據(jù)的語法;  02.構(gòu)建STM32單片機(jī)的AT指令處理體系  03.學(xué)會(huì)C語言的字符串處理函數(shù)strstrstrcmp函數(shù)、atoi函數(shù)使用;  03.實(shí)現(xiàn)AT接收、AT發(fā)送、AT的應(yīng)答、實(shí)現(xiàn)靈活指令;  04.用ESP8266模塊實(shí)現(xiàn)labview數(shù)據(jù)的接收和數(shù)據(jù)的處理;關(guān)鍵詞:labview、STM32、ESP8266strcmp函數(shù)、strstr函數(shù)、atoi、VISA備注1:手機(jī)微信可瀏覽相關(guān)高清圖片;

圖片

二、串口通訊原理

圖片

01、串口通訊的底層基礎(chǔ)驅(qū)動(dòng)語法內(nèi)容請(qǐng)自行查詢相關(guān)教程網(wǎng)站,本教程著重介紹串口的思維方法是功能層面的設(shè)計(jì);
02、串口通訊通常是存在3種方式:主動(dòng)發(fā)送不接收,被動(dòng)接收不發(fā)送,被動(dòng)接收發(fā)送反饋;
03、主動(dòng)發(fā)送不接收模式需要定義發(fā)送時(shí)間和間隔,如不定期的上傳數(shù)據(jù),不管對(duì)方是否收到;
04、被動(dòng)接收不發(fā)送模式是單片機(jī)是主機(jī)的模式,需要解析接收到的內(nèi)容,一般用到設(shè)置主機(jī)某些參數(shù),比如ESP8266的設(shè)置wifi參數(shù)連接TCP服務(wù)器;
05、被動(dòng)接收發(fā)送反饋模式是比較常用的應(yīng)答模式,保證通訊雙方的數(shù)據(jù)正常;

06、產(chǎn)品通常需要獲取數(shù)據(jù)和設(shè)置數(shù)據(jù)兩個(gè)操作,而且字符長(zhǎng)度不固定,比如Modbus協(xié)議和AT指令,RTU模式和ASCII模式;

三、STM32串口注意事項(xiàng)
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指令不固定長(zhǎng)度,串口接收函數(shù)需要獲取到接收的起點(diǎn)終點(diǎn)和長(zhǎng)度,同時(shí)需要有錯(cuò)誤處理、超時(shí)恢復(fù)機(jī)制、超長(zhǎng)恢復(fù)機(jī)制;

        接收指針 uart_i 是存到字符串?dāng)?shù)組的指針,接收到數(shù)據(jù)就會(huì)加一移動(dòng)一位,錯(cuò)誤會(huì)進(jìn)行指針清零,數(shù)據(jù)安全的化建議重置覆蓋防止內(nèi)存泄露;
        識(shí)別特定規(guī)律的字符串指令,AT指令的識(shí)別原理是if(當(dāng)前字符和上一個(gè)字符==回車鍵),識(shí)別到回車鍵只能說明收到一條符合規(guī)則的未知指令,這時(shí)需要通知進(jìn)程來處理這個(gè)指令;
     USART_RX_STA 標(biāo)記放在主程序的while中處理,也可以放在中斷中處理,建議盡量不要在串口中斷中處理;
        收到的未知指令需要識(shí)別是具體含義,這里的指令有固定字符的控制指令,有靈活可變的不固定字符的參數(shù)傳遞指令;
        指令有固定字符的控制指令只需要用strcmp函數(shù)識(shí)別即可,注意函數(shù)不能識(shí)別回車,所以在收到字符后指針-2再添加字符結(jié)束符號(hào);
        指令不固定長(zhǎng)度字符的配置指令,需要用strstr函數(shù)識(shí)別前部分的字符,還要剪切出后面的數(shù)據(jù)來換算,最后再賦值,比如設(shè)置輸出電壓函數(shù),同樣注意strstr函數(shù)不能識(shí)別回車,所以在收到字符后指針-2再添加字符結(jié)束符號(hào)
四、STM32串口收發(fā)代碼(部分)
#include 'stm32f10x.h'#include 'stdio.h' #include 'string.h'   //strstr strlen  strcmpchar USART2_RX_BUF[200]='';     //接收緩沖,最大USART_REC_LEN個(gè)字節(jié).u8   uart2_i=0;  u16  USART2_REC_LEN=4;  u16  USART2_RX_STA=0;                   //串口字節(jié)指針 //接收字節(jié)長(zhǎng)度//接收狀態(tài)標(biāo)記    char * user_after(char *instr,char *markstr)//輸入源字符串和目標(biāo)字段,輸出目標(biāo)字段后面的字符{//剪切處理字符串(指針方法)  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');  //應(yīng)答測(cè)試指令        if(strcmp(usercmd,'AT+GetADC')==0) printf('CH1=%f \r\n',讀取到的數(shù)據(jù));                //讀取參數(shù)類           if(strstr(USART2_RX_BUF,'AT+SetDAC')!=NULL){      //參數(shù)設(shè)置類 strbuf = user_after(USART2_RX_BUF,'AT+SetDAC='); i0buf=atoi(strbuf);       設(shè)置模擬輸出函數(shù)(i0buf); } usercmd_en=0; } } }
void USART_IRQHandler(void)                  { u8 r;//串口2中斷服務(wù)程序(正常)字符限制,有結(jié)束字符檢測(cè),未加入超時(shí)清空緩存區(qū)  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收中斷 { r =USART_ReceiveData(USART2);//(USART2->DR); //讀取接收到的數(shù)據(jù)    USART2_RX_BUF[uart2_i++]=r;    if(uart2_i>200)uart2_i=0;                          //數(shù)據(jù)超過長(zhǎng)度    if(r=='\n' && USART2_RX_BUF[uart2_i-2]=='\r')      //判斷是否回車,可加入CRC    { USART2_RX_BUF[uart2_i-2]='\0'; //加結(jié)束符號(hào),將數(shù)據(jù)去掉回車符號(hào) USART2_REC_LEN=uart2_i-2; //記錄字符長(zhǎng)度        USART2_RX_STA=1;                               //接收到一條未知數(shù)據(jù)需要處理,#define usercmd_en   USART2_RX_STA 重定義為 uart2_i=0; //清零索引指針 } } }
        代碼的調(diào)試推薦使用編譯器軟件加仿真模擬軟件的方法,然后再實(shí)際下載到STM32調(diào)試結(jié)合串口助手,當(dāng)串口助手?jǐn)?shù)據(jù)不正常要嘗試使用邏輯分析儀來觀察串口數(shù)據(jù)波形;下圖是仿真軟件仿真STM32串口調(diào)試

圖片

五、上位機(jī)串口數(shù)據(jù)對(duì)接

       Labview串口讀取最常用的方式是輪詢查詢讀取緩存區(qū)的數(shù)據(jù)(架構(gòu)代碼1),只要將輪詢時(shí)間調(diào)整合適就能實(shí)現(xiàn)正常數(shù)據(jù)接收,只要時(shí)間合適接收就沒問題,時(shí)間合適就可以!

        通過架構(gòu)代碼1來分析輪詢讀取串口數(shù)據(jù)的問題:

       在現(xiàn)實(shí)應(yīng)用中串口控制通常是不規(guī)定長(zhǎng)度的指令,那么運(yùn)用代碼1模式接收數(shù)據(jù)會(huì)出現(xiàn):短指令正常,長(zhǎng)指令出錯(cuò)的情況。那按照最長(zhǎng)指令計(jì)算等待時(shí)間,會(huì)發(fā)現(xiàn)等待時(shí)間變長(zhǎng)不能滿足響應(yīng)時(shí)間的要求

圖片

圖片

01、如何在不影響<實(shí)時(shí)響應(yīng)>性能的情況下<適應(yīng)不同長(zhǎng)度>的指令?

02、按照代碼2的思想是:運(yùn)用上位機(jī)等待中斷方式,獨(dú)立一個(gè)進(jìn)程作為生產(chǎn)者,短時(shí)間接收數(shù)據(jù),然后將相鄰有效數(shù)據(jù)拼接起來驗(yàn)證,接收為空時(shí)清空緩存(可在代碼2中添加驗(yàn)證成功時(shí)清空緩存)。

03、接下來進(jìn)行上位機(jī)的實(shí)例介紹,選擇有成熟協(xié)議的ESP8266無線模塊進(jìn)行上位機(jī)AT指令的對(duì)接:

圖片
圖片
01、ESP8266AT指令的代碼舉例,主要是labview發(fā)送給主機(jī)指令,主機(jī)應(yīng)答到接收數(shù)據(jù)框,調(diào)試助手需要清空接收;
02、該代碼是筆者小白級(jí)別最初設(shè)計(jì),存在缺陷,需要把串口接收功能和用戶事件結(jié)構(gòu)設(shè)計(jì)成兩個(gè)獨(dú)立的進(jìn)程;

03、可以參考使用該labview結(jié)構(gòu)來設(shè)計(jì)STM32的AT指令對(duì)接上位機(jī),注意事件結(jié)構(gòu)進(jìn)入指定事件一定取消鎖定選項(xiàng)不要鎖定前面板(鎖定后所有前面板局部變量?jī)鼋Y(jié)不再實(shí)時(shí)更新),如果對(duì)應(yīng)事件中用到局部變量數(shù)據(jù),會(huì)有計(jì)算出錯(cuò)現(xiàn)象,還不容易查找錯(cuò)誤點(diǎn),建議盡量多使用數(shù)據(jù)流設(shè)計(jì),減少局部變量的使用

六、相關(guān)參考文章鏈接
01、labview串口異步同步接收數(shù)據(jù)技術(shù)

02、STM32串口例程之ESP8266

03、C語言字符串處理函數(shù)string語法解析
七、聲明
01、本教程STM32代碼是修飾后的代碼,思維模式和方案方法,存在錯(cuò)誤僅供參考;

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多