国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

極度優(yōu)雅的用stm32串口接收并分析不定長數(shù)據(jù)的方法(可用于發(fā)送和接收浮點(diǎn)數(shù))

這篇具有很好參考價值的文章主要介紹了極度優(yōu)雅的用stm32串口接收并分析不定長數(shù)據(jù)的方法(可用于發(fā)送和接收浮點(diǎn)數(shù))。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

應(yīng)用場景

比賽需要

我準(zhǔn)備電賽的時候參加了學(xué)校為了準(zhǔn)備電賽而舉辦的的積分賽,隊友通過樹莓派用給stm32發(fā)送執(zhí)行指令,而我在隊里作為寫單片機(jī)的就需要分析數(shù)據(jù)包,每一個數(shù)據(jù)包都比較大也比較復(fù)雜,而且不定長,用傳統(tǒng)的一個字節(jié)一個字節(jié)接收數(shù)據(jù)的方式收串口在代碼層面上就顯得和很復(fù)雜,因此我需要一個能定長接收數(shù)據(jù)并分析的方法。

ESP-01s

在我之前用AT指令玩ESP-01s模塊的時候,服務(wù)器下發(fā)的數(shù)據(jù)往往是不定長的,因此我也需要一個用單片機(jī)接收不定長數(shù)據(jù)的方式。

因此我在網(wǎng)上找了一些方法,整合了一些我認(rèn)為比較優(yōu)雅的基于stm32的解決方案。

廢話少說,開始實(shí)現(xiàn)。

原理

因?yàn)槲沂稚蠐碛凶疃嗟膯纹瑱C(jī)是stm32f401ccu6,因此這里以stm32f401為例演示

根據(jù)stm32f4的數(shù)據(jù)手冊stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
從這張表中可以看出stm32有RXNE(RX寄存器非空,代表有數(shù)據(jù)輸入)中斷,和IDLE(串口空閑,代表發(fā)送端發(fā)送結(jié)束)中斷,那么我們只需要從有數(shù)據(jù)輸入,一直接受直到串口出現(xiàn)空閑即可接收下整包不定長的數(shù)據(jù)。

但是在此之前,如果配置RXNE中斷,發(fā)送端每發(fā)送一個字節(jié),CPU就要進(jìn)一次中斷去處理該字節(jié),那這樣就和一個個字節(jié)接收無異了,那這時候就需要請出CPU的小弟:DMA出場,讓每個字節(jié)進(jìn)入單片機(jī)時都產(chǎn)生一個接收請求,然后讓DMA一個個字節(jié)搬入內(nèi)存,CPU在IDLE中斷中再對所有數(shù)據(jù)進(jìn)行處理,并重置DMA,則可大大減小CPU的占用,也方便了代碼的編寫。

STM32CUBEMX配置

stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
配置Debug接口
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu配置HSE和LSE(LSE其實(shí)可以不配)
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
配置時鐘樹
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
配置USART1為異步模式
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
打開USART1全局中斷
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
打開USART1 DMA接收請求,配置默認(rèn)就好,主要的是Increment Address勾選Memery,Data Width外設(shè)和內(nèi)存都選擇BYTE(這兩個必須相同)

然后接下來的就是工程配置,那個就按照自己的情況來,該怎么樣就怎么樣

代碼編寫

stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
在USER CODE BEGIN Include之后加上兩個頭文件

#include "stdio.h"
#include "string.h"

stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
點(diǎn)開魔術(shù)棒勾選Use MicroLIB
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
在工程的任意地方添加重定向代碼(我這里添加在了/* USER CODE BEGIN 4 */的后面)

int fputc(int ch, FILE *f)
{
//	HAL_UART_Transmit (&huart2 ,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	while((USART1->SR&0x40)==0);
		USART1->DR = (uint8_t)ch;
	//采用輪詢方式發(fā)送一個字節(jié)的數(shù)據(jù),沒有發(fā)送成功就一直等待
	return ch;
}
int fgetc(FILE *f)
//int fgetc(int ch, FILE *F)
{
	uint8_t ch;
	HAL_UART_Receive(&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
	return ch;
}

stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu

在工程的任意位置添加串口接收事件服務(wù)函數(shù)(我這里添加在了/* USER CODE BEGIN 4 */的后面)

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &huart1)
	{
		//獲取幀長
		usart1_data_len = 1024 - huart->hdmarx->Instance->NDTR;
		
		sscanf(usart1_rx_buf,"N%dM%d",&test1,&test2);
		
		HAL_UART_Transmit(&huart1,usart1_rx_buf,usart1_data_len,100);
		
		printf("%d,%d\r\n",test1,test2);
		
		//使dma從頭存數(shù)據(jù)
		huart->hdmarx->Instance -> NDTR =  1024;
		//重新打開dma接收,ILDE中斷
		HAL_UARTEx_ReceiveToIdle_DMA(&huart1,usart1_rx_buf,1024);
	}
}

stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu
在主函數(shù)的while(1)之前加上一句話

HAL_UARTEx_ReceiveToIdle_DMA(&huart1,usart1_rx_buf,1024);

這句話是串口接收數(shù)據(jù)直至IDLE事件,記得定義usart1_rx_buf作為串口接收數(shù)據(jù)緩沖區(qū),第三個參數(shù)是你定義的接收緩沖區(qū)的大小,建議用宏定義,我這里為了演示就懶得用宏定義了XD.

這樣就程序就編寫完成啦,目前的程序作用是:串口使用DMA接收數(shù)據(jù)至IDLE事件,當(dāng)IDLE事件發(fā)生時進(jìn)入中斷服務(wù)函數(shù)對數(shù)據(jù)進(jìn)行處理。

細(xì)心的小伙伴應(yīng)該已經(jīng)發(fā)現(xiàn)中斷服務(wù)函數(shù)中不僅有一個

HAL_UART_Transmit(&huart1,usart1_rx_buf,usart1_data_len,100);

將接收的數(shù)據(jù)從新發(fā)送,還有一個

sscanf(usart1_rx_buf,“N%dM%d”,&test1,&test2);

用于按格式提取數(shù)據(jù),當(dāng)發(fā)送端是使用print來發(fā)送數(shù)據(jù)的,那么它每個字節(jié)都是用ASCII編碼的,例如對方printf(“%d”,123)的時候,發(fā)送的數(shù)據(jù)為0X31 0X32 0X33,這就對我們接收端分析數(shù)據(jù)包時產(chǎn)生了障礙。

因此我們可以使用stdio.h中的sscanf函數(shù)對數(shù)據(jù)包按照格式提取數(shù)據(jù)

例如我這里格式為:“N%dM%d”
則發(fā)送端按照這個格式發(fā)送數(shù)據(jù)的話,我就可以把這兩個%d位置的整數(shù)提取出來

所以以上代碼的實(shí)際效果be like:
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu

總結(jié)&擴(kuò)展

總的來說,大致思路就是,打開USART1的中斷,打開USART1的DMA接收請求,讓DMA一個個字節(jié)搬運(yùn)數(shù)據(jù)到內(nèi)存中,然后在檢測串口空閑,當(dāng)串口空閑時,代表發(fā)送端發(fā)送完畢,則進(jìn)入中斷服務(wù)函數(shù)中處理數(shù)據(jù)包

看起來是不是很優(yōu)雅?
但是這還是有部分不是很優(yōu)雅的地方,例如:
當(dāng)發(fā)送端因某些原因發(fā)送數(shù)據(jù)的速度較慢,使得每發(fā)送一個字節(jié)之間時間間隔較大,而在字節(jié)之間出現(xiàn)空閑,則目前這個方法就不適用,會出bug,大家可以自己想想為什么會出bug,這里就不過多贅述。

而有了這個方法,愛動腦子的小伙伴應(yīng)該發(fā)現(xiàn)了這個方法的一個新用途。
既然可以按照格式發(fā)送接收數(shù)據(jù),那么在兩個單片機(jī)之間,用串口收發(fā)浮點(diǎn)數(shù)將不再是難事。

例如可以將中斷服務(wù)函數(shù)改為:
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &huart1)
	{
		//獲取幀長
		usart1_data_len = 1024 - huart->hdmarx->Instance->NDTR;
		sscanf(usart1_rx_buf,"N%fM%f",&test1,&test2);
		HAL_UART_Transmit(&huart1,usart1_rx_buf,usart1_data_len,100);
		printf("%.2f,%.2f\r\n",test1,test2);
		//使dma從頭存數(shù)據(jù)
		huart->hdmarx->Instance -> NDTR =  1024;
		//重新打開dma接收,ILDE中斷
		HAL_UARTEx_ReceiveToIdle_DMA(&huart1,usart1_rx_buf,1024);
	}
}

則在發(fā)送端和接收端之間則可以直接使用printf函數(shù)來實(shí)現(xiàn)浮點(diǎn)數(shù)的收發(fā),而再也不需要將浮點(diǎn)數(shù)拆成一個個字節(jié)發(fā)送,然后再在接收端將數(shù)據(jù)拼起來了

效果be like:
stm32串口接收不定長數(shù)據(jù),stm32,單片機(jī),嵌入式硬件,mcu

好啦,此貼到這里就結(jié)束啦,希望各位能開發(fā)出更優(yōu)雅的串口收發(fā)的方式,該貼為博主第一次寫文章,若是有任何問題歡迎討論 ??文章來源地址http://www.zghlxwxcb.cn/news/detail-757460.html

到了這里,關(guān)于極度優(yōu)雅的用stm32串口接收并分析不定長數(shù)據(jù)的方法(可用于發(fā)送和接收浮點(diǎn)數(shù))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32 串口接收不定長數(shù)據(jù) HAL_UART_Receive_IT (幀頭幀尾)

    最近使用sw4stm32調(diào)試串口時發(fā)現(xiàn)串口接收不定長數(shù)據(jù)很不方便,這里是幀頭幀尾的接收方式,歡迎大佬指導(dǎo)。 這里要用串口中斷接收的數(shù)據(jù)幀幀頭為0xEB,幀尾為0XBE 這里是其中定義的變量? 主函數(shù)里打開串口接收中斷 然后串口接收處理部分全都寫在的回調(diào)函數(shù)中。

    2024年01月19日
    瀏覽(31)
  • 【STM32】CUBEMX之串口:串口三種模式(輪詢模式、中斷模式、DMA模式)的配置與使用示例 + 串口重定向 + 使用HAL擴(kuò)展函數(shù)實(shí)現(xiàn)不定長數(shù)據(jù)接收

    【STM32】CUBEMX之串口:串口三種模式(輪詢模式、中斷模式、DMA模式)的配置與使用示例 + 串口重定向 + 使用HAL擴(kuò)展函數(shù)實(shí)現(xiàn)不定長數(shù)據(jù)接收

    目錄 ? 總覽 使用CUBEMX創(chuàng)建工程的基本配置 CUBEMX中的配置 Keil中的配置 實(shí)物連接 串口輪詢模式 輪詢模式HAL庫函數(shù) 特點(diǎn) 實(shí)驗(yàn)一:發(fā)送數(shù)據(jù)給單片機(jī)并讓其返回相同值 串口重定向 串口中斷模式 在CUBEMX中打開串口中斷 中斷模式HAL庫函數(shù) 特點(diǎn) 實(shí)驗(yàn)二:使用中斷回調(diào)完成實(shí)驗(yàn)一

    2024年04月10日
    瀏覽(44)
  • STM32 cubemx配置DMA+空閑中斷接收不定長數(shù)據(jù)

    STM32 cubemx配置DMA+空閑中斷接收不定長數(shù)據(jù)

    本篇文章給大家講解一下DMA+串口空閑中斷接收串口不定長數(shù)據(jù),之前我們也是講解過串口接收不定長數(shù)據(jù)的,那么本篇文章的話將使用DMA來接收不定長數(shù)據(jù)。 串口空閑中斷是指在串口接收到數(shù)據(jù)后,在數(shù)據(jù)的傳輸結(jié)束之后,在一段連續(xù)的空閑時間內(nèi)沒有接收到新數(shù)據(jù)時觸發(fā)

    2024年02月19日
    瀏覽(27)
  • STM32_HAL庫串口接收相關(guān)函數(shù)分析

    串口接收的程序整體分為三個部分:初始化部分,開啟中斷部分,中斷函數(shù)部分: 初始化部分: 該部分主要完成相關(guān)引腳的初始化,串口的初始化(設(shè)置波特率,校驗(yàn)位,字長等),為了邏輯清晰,把初始化相關(guān)代碼放在本文的最后。 開啟中斷部分: 調(diào)用HAL_UART_Receive_IT函數(shù)

    2024年02月16日
    瀏覽(14)
  • STM32F407普通IO口模擬串口實(shí)現(xiàn)不定長數(shù)據(jù)收發(fā)

    STM32F407普通IO口模擬串口實(shí)現(xiàn)不定長數(shù)據(jù)收發(fā)

    因?yàn)轫椖恐杏玫降拇诒容^多,STM32F407VET6自帶的串口不夠用了,所以只能考慮用模擬串口來實(shí)現(xiàn)功能。普通的IO口來模擬串口需要先了解串口的時序圖,需要用到兩個IO引腳即收發(fā)引腳,兩個定時器,一個用于發(fā)送延時使用,一個用于產(chǎn)生中斷接收數(shù)據(jù)。代碼的初始化主要用

    2024年02月07日
    瀏覽(27)
  • STM32 串口DMA接收數(shù)據(jù)(高效接收數(shù)據(jù))

    STM32 串口DMA接收數(shù)據(jù)(高效接收數(shù)據(jù))

    極度不推薦在使用DMA的時候按照傳統(tǒng)的方式進(jìn)行重定義?。。?非常簡單,輪詢方式整個CPU 在串口發(fā)送時處于等待狀態(tài),但是使用DMA時無法確保當(dāng)前DMA已經(jīng)傳輸完成。 有同學(xué)可能會認(rèn)為可以通過判斷DMA的傳輸標(biāo)志位來進(jìn)行等待,但如果這樣的話就喪失了DMA的設(shè)計意圖: 再次使

    2024年02月16日
    瀏覽(20)
  • stm32串口空閑中斷+DMA傳輸接受不定長數(shù)據(jù)+letter?shell?實(shí)現(xiàn)命令行

    空閑中斷(IDLE),俗稱幀中斷,即第一幀數(shù)據(jù)接收完畢到第二幀數(shù)據(jù)開始接收期間存在一個空閑狀態(tài)(每接收一幀數(shù)據(jù)后空閑標(biāo)志位置1),檢測到此空閑狀態(tài)后即執(zhí)行中斷程序。 空閑中斷的優(yōu)點(diǎn)在于省去了幀頭幀尾的檢測 ,進(jìn)入中斷程序即意味著已經(jīng)接收到一組完整數(shù)據(jù),僅需

    2024年02月03日
    瀏覽(26)
  • STM-32:USART串口協(xié)議、串口外設(shè)—數(shù)據(jù)發(fā)送/數(shù)據(jù)發(fā)送+接收

    STM-32:USART串口協(xié)議、串口外設(shè)—數(shù)據(jù)發(fā)送/數(shù)據(jù)發(fā)送+接收

    通信的目的:將一個設(shè)備的數(shù)據(jù)傳送到另一個設(shè)備,擴(kuò)展硬件系統(tǒng)。比如STM32芯片里面集成了很多功能模塊,如定時器計數(shù)、PWM輸出、AD采集等等,這些都是芯片內(nèi)部的電路,它們的配置寄存器、數(shù)據(jù)寄存器都在芯片里面,操作簡單,直接讀寫就行。但是有些功能STM32內(nèi)部沒有

    2024年02月04日
    瀏覽(93)
  • STM32實(shí)現(xiàn)DMA接收串口數(shù)據(jù)

    一..首先我們得配置DMA和USARAT,我們的原理是DMA1的通道5為USART1的RX引腳。 ?1.USART1的配置 2.DMA的配置 二.中斷進(jìn)行數(shù)據(jù)處理(stm32f10x_it.c) 我們可以串口打印出數(shù)組中的數(shù)據(jù),驗(yàn)證DMA是否正常工作??梢缘綌?shù)據(jù)處理那個地方進(jìn)行處理。USART1在初始化中就已經(jīng)波特率為115200.我們可以

    2024年02月16日
    瀏覽(19)
  • GD32F4單片機(jī)實(shí)現(xiàn)接收超時中斷+DMA實(shí)現(xiàn)串口的不定長接收和DMA發(fā)送

    GD32F4單片機(jī)實(shí)現(xiàn)接收超時中斷+DMA實(shí)現(xiàn)串口的不定長接收和DMA發(fā)送

    環(huán)形緩沖區(qū)+定時器超時中斷的方式 優(yōu)點(diǎn) 環(huán)形緩沖區(qū)可以接收多幀數(shù)據(jù) 數(shù)據(jù)幀超時間隔可以設(shè)置 缺點(diǎn) 設(shè)備任務(wù)比較繁重時,使用中斷接收可能會丟失數(shù)據(jù)。尤其是在長時間關(guān)閉中斷或者串口中斷優(yōu)先級不高時 頻繁進(jìn)出中斷。在使用RTOS的系統(tǒng)中,每收到一個數(shù)據(jù)就會進(jìn)行一

    2024年02月15日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包