HAL庫配置RS485+DMA+空閑中斷收發數據

前言:

(1)DMA是單片機集成在芯片內部的一個數據搬運工,它可以代替單片機對數據進行傳輸、存儲,節約CPU資源。一般應用場景,ADC多通道采集,串口收發(頻繁進入接收中斷),SPI和IIC通信等

(2)STM32F2系列的DMA控制器最多有2個,每個控制器有8個數據流,每個數據流可以映射到不同的通道。例如,DMA2的數據流7可能用于某個特定外設,比如USART1的TX。(每個數據流同一時間只能服務一個外設。例如,若USART1_TX占用了DMA2_Stream7,則該流不可用于其他外設)

(3)DMA配置參數:

DMA請求源與通道選擇:DMA1通道1

數據傳輸方向:外設 ? 存儲器,存儲器 ? 存儲器

地址遞增配置:外設地址遞增和存儲器地址遞增(如果外設是ADC數據寄存器,關閉遞增,如果存儲器地址是接收數組,則開啟遞增)

數據寬度與對齊:外設/存儲器數據寬度(串口一般是8位,ADC一般是16位)

傳輸模式:單次模式(串口接收)和循環模式(ADC采集數據)

正文:

1、配置時鐘,燒入方式,配置RS485的接收使能腳

2、配置串口,DMA

3、串口串口收發緩存結構體

#define USART_TX_MAX_LEN 100
#define USART_RX_MAX_LEN 100
typedef struct
{unsigned char tx_buf[USART_TX_MAX_LEN]; unsigned char rx_buf[USART_RX_MAX_LEN];unsigned char rx_flag;unsigned char rx_len;
}usart_data_t;extern usart_data_t stUsart1Data;

?4、 串口初始化代碼加入??開啟IDLE中斷、開始DMA接收

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中斷
HAL_UART_Receive_DMA(&huart1,stUsart1Data.rx_buf,USART_RX_MAX_LEN);

5、串口中斷函數中加入 接收數據代碼

void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 */if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))  {__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除標志位HAL_UART_AbortReceive(&huart1);	//已經接收完一幀數據,所以這里要停止接收,然后再重新接收	uint32_t   temp =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 獲取DMA中未傳輸的數據個數 ,stUsart1Data.rx_len =  USART_RX_MAX_LEN - temp; //總計數減去未傳輸的數據個數,得到已經接收的數據個數stUsart1Data.rx_flag = 1;	// 接受完成標志位置1	HAL_UART_Receive_DMA(&huart1,stUsart1Data.rx_buf,USART_RX_MAX_LEN);	//開始DMA接收}/* USER CODE END USART1_IRQn 1 */
}

6、配置串口printf打印函數

void Usart1Printf(const char *format,...)
{uint16_t len;va_list args;	va_start(args,format);len = vsnprintf((char*)stUsart1Data.tx_buf,sizeof(stUsart1Data.tx_buf)+1,(char*)format,args);va_end(args);if(HAL_UART_Transmit_DMA(&huart1, stUsart1Data.tx_buf, len)!= HAL_OK)   //判斷是否發送正常,如果出現異常則進入異常中斷函數{Error_Handler();}}

7、RS485通信加入使能發送和接收

/* USER CODE BEGIN 1 */
void USART1_RS485_Send_Enable(void)
{HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
}void USART1_RS485_Receive_Enable(void)
{HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}

8、測試代碼

USART1_RS485_Receive_Enable(); //默認為接收使能while (1){/* USER CODE END WHILE */if(stUsart1Data.rx_flag  == 1)  //接收完成標志{USART1_RS485_Send_Enable();Usart1Printf("%s\r\n",stUsart1Data.rx_buf);HAL_Delay(100);//等待串口DMA發送完成,如果不加入此行代碼,會出現發送失敗,因為還沒有發送完就切換成接收模式,導致不能發送數據 USART1_RS485_Receive_Enable();stUsart1Data.rx_len = 0;//清除計數stUsart1Data.rx_flag = 0;//清除接收結束標志位memset(stUsart1Data.rx_buf,0,USART_RX_MAX_LEN);}}

9、測試結果

10、優化RS485發送

當發送數據后,我們會等待一定時間,等待發送完成后在開啟串口接收,但此時資源遭到了一定的浪費

優化思路:等待觸發串口發送完成中斷后,使能串口接收中斷

void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&huart1);if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))  {__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除標志位HAL_UART_AbortReceive(&huart1);	//已經接收完一幀數據,所以這里要停止接收,然后再重新接收	uint32_t   temp =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 獲取DMA中未傳輸的數據個數 ,stUsart1Data.rx_len =  USART_RX_MAX_LEN - temp; //總計數減去未傳輸的數據個數,得到已經接收的數據個數stUsart1Data.rx_flag = 1;	// 接受完成標志位置1	HAL_UART_Receive_DMA(&huart1,stUsart1Data.rx_buf,USART_RX_MAX_LEN);	//開始DMA接收}if (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) {// 發送完成 USART1_RS485_Receive_Enable();}
}USART1_RS485_Receive_Enable();while (1){/* USER CODE END WHILE */if(stUsart1Data.rx_flag  == 1)  //接收完成標志{USART1_RS485_Send_Enable();Usart1Printf("%s\r\n",stUsart1Data.rx_buf);
//		HAL_Delay(100);//等待串口DMA發送完成 
//		USART1_RS485_Receive_Enable();stUsart1Data.rx_len = 0;//清除計數stUsart1Data.rx_flag = 0;//清除接收結束標志位memset(stUsart1Data.rx_buf,0,USART_RX_MAX_LEN);}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77495.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77495.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77495.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從零開始解剖Spring Boot啟動流程:一個Java小白的奇幻冒險之旅

大家好呀!今天我們要一起探索一個神奇的話題——Spring Boot的啟動流程。我知道很多小伙伴一聽到"啟動流程"四個字就開始頭疼,別擔心!我會用最通俗易懂的方式,帶你從main()方法開始,一步步揭開Spring Boot的…

下載HBuilder X,使用uniapp編寫微信小程序

到官網下載HBuilder X 地址:HBuilderX-高效極客技巧 下載完成后解壓 打開解壓后的文件夾找到HBuilderX.exe 打開顯示更多,發送到桌面快捷方式 到桌面上啟動HBuilderX.exe啟動應用 在工具點擊插件安裝 選擇安裝Vue3編譯器 點擊新建創建Vue3項目 編寫項目…

詳解與HTTP服務器相關操作

HTTP 服務器是一種遵循超文本傳輸協議(HTTP)的服務器,用于在網絡上傳輸和處理網頁及其他相關資源。以下是關于它的詳細介紹: 工作原理 HTTP 服務器監聽指定端口(通常是 80 端口用于 HTTP,443 端口用于 HT…

2. ubuntu20.04 和VS Code實現 ros的輸出 (C++,Python)

本節對應趙虛左ROS書籍的1.4.2 1)創建工作空間 mkdir -p catkin_ws/src cd catkin_ws catkin_make 2) 終端進入VS Code code . 3) vscoe 的基本配置 3.1)修改.vscode/tasks.json ,修改內容如下: { // 有關 tasks.json 格式的文檔,請參見…

SAP系統中MD01與MD02區別

知識點普及-MD01與MD02區別 1、從日常業務中,我們都容易知道MD01是運行全部物料,MD02是運行單個物料 2、在做配置測試中,也出現過MD02可以跑出物料,但是MD01跑不出的情況。 3、MD01與MD02的差異: 3.1、只要在物料主數…

快速迭代收縮-閾值算法(FISTA)

文章目錄 1. 數學與優化基礎2. FISTA 算法的原理、推導與機制3. Matlab 實現4. FISTA 在圖像處理與壓縮感知中的應用4.1. 基于小波稀疏先驗的圖像去噪4.2 壓縮感知圖像重建 1. 數學與優化基礎 在許多信號處理與機器學習問題中,我們希望獲得稀疏解,即解向…

微服務之間打通用戶上下文

微服務之間打通用戶上下文 打通上下文步驟需求:1、gateway網關登錄攔截器:【LoginFilter】解釋:代碼 2、SpringMVC全局處理:【GlobalConfig】解釋:代碼: 3、自定義登錄攔截器:【LoginIntercepto…

Hutool之DateUtil:讓Java日期處理變得更加簡單

前言 在Java開發中,日期和時間的處理是一個常見問題。為了簡化這個過程,許多開發者會使用第三方工具包,如Hutool。Hutool是一個Java工具包,提供了許多實用的功能,其中之一就是日期處理。日期時間工具類是Hutool的核心包…

ES中常用的Query和查詢作用,以及SpringBoot使用實例

ES中常用的Query和查詢作用,以及 SpringBoot 使用實例 文章目錄 ES中常用的Query和查詢作用,以及 SpringBoot 使用實例MatchAllQueryTermQueryBoolQueryRangeQueryMatchQueryMultiMatchQueryTermsQueryPrefixQueryWildcardQueryRegexpQueryFuzzyQueryDis…

Flutter 自定義插件基礎

1、Flutter插件是什么?官方插件庫 在開發Flutter應用過程中會涉及到平臺相關接口調用,例如數據庫操作、相機調用、外部瀏覽器跳轉等業務場景。其實Flutter自身并不支持直接在平臺上實現這些功能,而是通過插件包接口去調用指定平臺API從而實現…

極狐GitLab 外部授權控制機制是怎樣的?

極狐GitLab 是 GitLab 在中國的發行版,關于中文參考文檔和資料有: 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 外部授權控制 (BASIC SELF) 在高度控制的環境中,訪問策略可能需要由外部服務控制,該服務允許基于項目…

Linux系統之----馮諾依曼結構

1.簡要描述 馮諾依曼體系結構是現代計算機的基本設計思想,其核心理念是將計算機的硬件和軟件統一為一個整體,通過存儲程序的方式實現計算。馮諾依曼體系結構的核心思想是通過存儲程序實現自動計算,其五大部件協同工作,奠定了現代…

【八股】計算機網絡

1 概述 1.1 網絡的網絡 網絡把主機連接起來,而互連網(internet)是把多種不同的網絡連接起來,因此互連網是網絡的網絡。而互聯網(Internet)是全球范圍的互連網。 1.2 ISP 互聯網服務提供商 ISP 可以從互聯網管理機構獲得許多 IP 地址,同時擁有通信線路以及路由器等聯…

基于VS Code 為核心平臺的python語言智能體開發平臺搭建

以下是基于 VS Code 為核心平臺,整合 Node-RED、Gradio、Docker Desktop 的智能體可視化開發平臺優化方案,聚焦工具鏈深度集成與開發效率提升: 一、核心架構設計 #mermaid-svg-f8l9kYPAlJ2TlpGF {font-family:"trebuchet ms",verd…

STM32G0單片機自帶RTC

STM32有個自帶RTC外設,外接32.768KHz的晶振后可得到相對精確的計時功能。 實測了一個一小時快個1秒多。 1 cubeMX設置了RTC后自動生成的初始化代碼如下 static void MX_RTC_Init(void) {/* USER CODE BEGIN RTC_Init 0 *//* USER CODE END RTC_Init 0 */RTC_TimeT…

細說STM32單片機FreeRTOS任務管理API函數及多任務編程的實現方法

目錄 一、FreeRTOS任務管理API函數 1、任務管理API函數 2、獲取任務的句柄 (1)函數xTaskGetCurrentTaskHandle() (2)函數xTaskGetIdleTaskHandle() (3)函數xTaskGetHandle() 3、單個任務的操作 &a…

星露谷物語 7000+ 大型MOD整合包

衣服美化、家具美化、地圖美化、人物肖像美化 全地圖裝修存檔、人物美化、擴展包、環境美化、家具、動植物、通用前置包、新增NPC、功能、服裝發飾妝 帽子發型農場小鎮美化大型玩法拓展實用功能mod 動漫人物形象MOD 地點/動物/地圖/功能/機械/家具/建筑/界面美化/擴展/農場/食譜…

C++ `unique_ptr` 多線程使用

C unique_ptr 多線程使用 一、核心結論 操作同一個 unique_ptr:必須加鎖(所有權轉移是非原子操作)訪問被管理對象:若對象非線程安全,仍需額外同步獨立 unique_ptr 實例:不同線程操作不同實例時無需加鎖 二…

Android audio系統六 AudioEffect音效加載

對于Android系統智能硬件設備,音效處理的實現方式有以下幾種: AudioEffect – android系統音效處理 優點:純軟件實現,移植調試簡單方便 缺點:cpu上運行,容易因為資源競爭而出現卡頓 DSP/ADSP – 數字信號處…

深度學習總結(21)

超越基于常識的基準 除了不同的評估方法,你還應該了解的是利用基于常識的基準。訓練深度學習模型,你聽不到也看不到。你無法觀察流形學習過程,它發生在數千維空間中,即使投影到三維空間中,你也無法解釋它。唯一的反饋…