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

STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號

這篇具有很好參考價值的文章主要介紹了STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一. 問題描述

能夠點進(jìn)這篇文章的小伙伴肯定是對STM32串口DMA空閑中斷接收數(shù)據(jù)感興趣的啦,今天用這一功能實現(xiàn)串口解析航模遙控器sbus信號時,查閱了很多網(wǎng)友發(fā)布的文章(勤勞的搬運工~),包括自己之前寫過一篇博客 STM32_HAL庫_CubeMx串口DMA通信(DMA發(fā)送+DMA空閑接收不定長數(shù)據(jù))。本文進(jìn)一步梳理一下HAL庫串口空閑中斷三種不同的使用方式,其中前兩種使用DMA方式,最后一種使用HAL庫自帶的空閑中斷機(jī)制。

本文環(huán)境:

  • Keil MDK5.14
  • STM32CubeMX6.2.1
  • 開發(fā)板/芯片:自制板/STM32F407ZGT6

實現(xiàn)功能:

  • 串口DMA/非DMA空閑中斷接收不定長數(shù)據(jù)/解析航模遙控器SBUS信號

二. 方法一——使用HAL_UART_Receive_DMA

最常見的方法就是使用HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)這個庫函數(shù),其使用方法類似于HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size),初始化時需要調(diào)用一次,然后每次在中斷服務(wù)函數(shù)里面處理完數(shù)據(jù)后重新調(diào)用一次。

使用HAL_UART_Receive_IT只需要打開串口接收中斷,即HAL_NVIC_EnableIRQ(UART5_IRQn);

使用HAL_UART_Receive_DMA空閑中斷需要在初始化時打開串口空閑中斷使能,調(diào)用方式為:__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE)。

此時DMA中斷可開可不開,開了也不用管,因為數(shù)據(jù)處理是在串口空閑中斷中進(jìn)行的。

1. 串口初始化代碼:

void MX_USART2_UART_Init(void)
{
	huart2.Instance = USART2;
	huart2.Init.BaudRate = 100000;
	huart2.Init.WordLength = UART_WORDLENGTH_9B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_EVEN;
	huart2.Init.Mode = UART_MODE_TX_RX;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart2) != HAL_OK)
	{
		Error_Handler();
	}

	__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);		// 開啟串口空閑中斷,必須調(diào)用
	HAL_UART_Receive_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN);		// 啟動DMA接收
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
	if(uartHandle->Instance==USART2)
	{
		 __HAL_RCC_USART2_CLK_ENABLE();
		 __HAL_RCC_GPIOA_CLK_ENABLE();
		 
		 GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
		 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		 GPIO_InitStruct.Pull = GPIO_NOPULL;
		 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
		 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
		
		 hdma_usart2_rx.Instance = DMA1_Stream5;
		 hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
		 hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
		 hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
		 hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
		 hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		 hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		 hdma_usart2_rx.Init.Mode = DMA_NORMAL;
		 hdma_usart2_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
		 hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
		 if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
		 {
		   Error_Handler();
		 }
		
		 __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
		
		 /* USART2 interrupt Init */
		 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
		 HAL_NVIC_EnableIRQ(USART2_IRQn);
	}
}

初始化中調(diào)用__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE)開啟空閑中斷,HAL_UART_Receive_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN)啟動DMA串口接收,USART2_RX_BUF是接收緩沖區(qū),USART_REC_LEN是定義的DMA接收緩沖區(qū)長度,接收的數(shù)據(jù)不能超過這個長度。

2. 中斷處理:

中斷處理有兩種方式,第一種是直接定義在void USART1_IRQHandler(void)中,第二種是自定義一個函數(shù),然后在void USART1_IRQHandler(void)中調(diào)用。注意網(wǎng)上很多資源自定義了中斷回調(diào)函數(shù)但代碼又沒貼全,讀者可能以為是HAL庫自帶的回調(diào)函數(shù),結(jié)果因為沒有在void USART1_IRQHandler(void)中調(diào)用導(dǎo)致失敗。

第一種形式——直接定義:

void USART2_IRQHandler(void)
{
	uint32_t tmp_flag ;
	u8 len;
	u8 data[25];
	tmp_flag  = __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE);

	if( tmp_flag  != RESET)
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除標(biāo)志位
		HAL_UART_DMAStop(&huart2); //停止DMA接收,防止數(shù)據(jù)出錯
	
		len = USART_REC_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 獲取DMA中傳輸?shù)臄?shù)據(jù)個數(shù)
		
		// 以下為用戶數(shù)據(jù)處理,將數(shù)據(jù)拷貝出去
		if(len == 25)
		{
			memcpy(data,USART2_RX_BUF,len);
			update_sbus(data);
		}
		HAL_UART_Receive_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN);   //打開DMA接收,數(shù)據(jù)存入rx_buffer數(shù)組中。
	}
	
	HAL_UART_IRQHandler(&huart2); //調(diào)用HAL庫中斷處理公用函數(shù)
}

第二種形式——自定義回調(diào)函數(shù):

void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
{
	uint32_t tmp_flag ;
	u8 len;
	u8 data[25];

	if (huart->Instance == USART2)
	{
		tmp_flag  = __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE);
		if( tmp_flag  != RESET)
		{
			__HAL_UART_CLEAR_IDLEFLAG(huart);//清除標(biāo)志位
			HAL_UART_DMAStop(huart); //停止DMA接收
		
			len = USART_REC_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 獲取DMA中傳輸?shù)臄?shù)據(jù)個數(shù)
			
			// 以下為用戶數(shù)據(jù)處理,將數(shù)據(jù)拷貝出去
			if(len == 25)
			{
				memcpy(data,USART2_RX_BUF,len);
				update_sbus(data);
			}
			HAL_UART_Receive_DMA(huart,USART2_RX_BUF,USART_REC_LEN);   //打開DMA接收,數(shù)據(jù)存入rx_buffer數(shù)組中。
		}
	}
}

void USART2_IRQHandler(void)
{
	HAL_UART_IdleCpltCallback(&huart2)
	HAL_UART_IRQHandler(&huart2); //調(diào)用HAL庫中斷處理公用函數(shù)
}

再次提醒一下,HAL庫中并沒有類似void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)這樣的回調(diào)函數(shù),大家不要看到了以為是自帶的回調(diào)函數(shù)而不在void USART2_IRQHandler(void)中調(diào)用而導(dǎo)致失敗。

中斷處理中的函數(shù)說明:
__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE):返回中斷標(biāo)志位,產(chǎn)生空閑中斷后會返回1;
__HAL_UART_CLEAR_IDLEFLAG(&huart2):清除空閑中斷標(biāo)志位,必須調(diào)用;
HAL_UART_DMAStop(&huart2):停止DMA接收,防止數(shù)據(jù)處理出錯,數(shù)據(jù)處理完成后重新打開;
__HAL_DMA_GET_COUNTER(&hdma_usart2_rx):返回DMA中未傳輸?shù)臄?shù)據(jù)量,用緩沖區(qū)總長減去未傳輸數(shù)量就是已接收的數(shù)據(jù)長度;
HAL_UART_Receive_DMA(huart,USART2_RX_BUF,USART_REC_LEN):重新打開DMA接收。

以上就能成功實現(xiàn)不定長數(shù)據(jù)的接受了,其實只要步驟對了還是很簡單的。

三. 方法二——使用HAL_UARTEx_ReceiveToIdle_DMA

第二種方式是使用HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)這個庫函數(shù),并重定義void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)這個中斷回調(diào)函數(shù)。

Attention:__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)是正兒八經(jīng)的庫函數(shù)(弱函數(shù)),不是自定義的,我們可以重定義它。

使用這個庫函數(shù),串口初始化代碼中就不需要調(diào)用__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE)了,因為HAL_UARTEx_ReceiveToIdle_DMA函數(shù)內(nèi)部已經(jīng)打開了空閑中斷,當(dāng)然你加上也沒事。

1. 串口初始化代碼:

void MX_USART2_UART_Init(void)
{
	huart2.Instance = USART2;
	huart2.Init.BaudRate = 100000;
	huart2.Init.WordLength = UART_WORDLENGTH_9B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.Mode = UART_MODE_TX_RX;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart2) != HAL_OK)
	{
		Error_Handler();
	}

	//__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);// 開啟串口空閑中斷,可省略
	HAL_UARTEx_ReceiveToIdle_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN);		// 使用串口DMA空閑中斷,會自動開啟空空閑中斷
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
	if(uartHandle->Instance==USART2)
	{
		 __HAL_RCC_USART2_CLK_ENABLE();
		 __HAL_RCC_GPIOA_CLK_ENABLE();
		 
		 GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
		 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		 GPIO_InitStruct.Pull = GPIO_NOPULL;
		 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
		 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
		
		 hdma_usart2_rx.Instance = DMA1_Stream5;
		 hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
		 hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
		 hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
		 hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
		 hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		 hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		 hdma_usart2_rx.Init.Mode = DMA_NORMAL;
		 hdma_usart2_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
		 hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
		 if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
		 {
		   Error_Handler();
		 }
		
		 __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
		
		 /* USART2 interrupt Init */
		 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
		 HAL_NVIC_EnableIRQ(USART2_IRQn);
	}
}

這里__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE)是可省略的,HAL_UARTEx_ReceiveToIdle_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN)啟動DMA串口空閑中斷接收,USART2_RX_BUF是接收緩沖區(qū),USART_REC_LEN是定義的DMA接收緩沖區(qū)長度,接收的數(shù)據(jù)不能超過這個長度。

2. 中斷處理:

中斷處理定義在void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)這個中斷回調(diào)函數(shù)中。

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	u8 len;
	u8 data[25];
	if(huart->Instance == USART2)
	{
		HAL_UART_DMAStop(huart);
		len = USART_REC_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 獲取DMA中傳輸?shù)臄?shù)據(jù)個數(shù)
		if (USART2_RX_BUF[0] == 0x0F && len == 25)	//接受完一幀數(shù)據(jù)
		{
			memcpy(data,USART2_RX_BUF,len);
			update_sbus(data);
		}
		HAL_UARTEx_ReceiveToIdle_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN);		// 再次開啟DMA空閑中斷
	}
}	

void USART2_IRQHandler(void)
{
	HAL_UART_IRQHandler(&huart2); //調(diào)用HAL庫中斷處理公用函數(shù)
}

當(dāng)然也可以像方法一種一樣,中斷邏輯處理直接定義在void USART2_IRQHandler(void)中。

四. 方法三——使用HAL_UARTEx_ReceiveToIdle_IT(不使用DMA)

這種方法參考這篇文章: STM32 hal庫串口空閑中斷最新用法

使用方法:
1、在主函數(shù)中調(diào)用HAL_UARTEx_ReceiveToIdle_IT()
2、在回調(diào)函數(shù)HAL_UARTEx_RxEventCallback()中做中斷邏輯處理。

這里我換用串口4,實現(xiàn)上位機(jī)發(fā)送,單片機(jī)原封不動返回數(shù)據(jù)。

1. 串口初始化代碼:

void MX_UART4_Init(void)
{
	huart4.Instance = UART4;
	huart4.Init.BaudRate = 115200;
	huart4.Init.WordLength = UART_WORDLENGTH_8B;
	huart4.Init.StopBits = UART_STOPBITS_1;
	huart4.Init.Parity = UART_PARITY_NONE;
	huart4.Init.Mode = UART_MODE_TX_RX;
	huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart4.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart4) != HAL_OK)
	{
		Error_Handler();
	}
	// HAL_UARTEx_ReceiveToIdle_IT同時開啟空閑中斷,開啟接收
	HAL_UARTEx_ReceiveToIdle_IT(&huart4,USART4_RX_BUF,USART_REC_LEN);
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
	if(uartHandle->Instance==UART4)
	{
		 __HAL_RCC_UART4_CLK_ENABLE();
	    __HAL_RCC_GPIOC_CLK_ENABLE();
	  
	    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
	    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	    GPIO_InitStruct.Pull = GPIO_PULLUP;
	    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	    GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
	    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	    HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
	    HAL_NVIC_EnableIRQ(UART4_IRQn);
	}
}

可以看到這里是沒有使用DMA的,初始化中調(diào)用了HAL_UARTEx_ReceiveToIdle_IT(&huart4,USART4_RX_BUF,USART_REC_LEN)來開啟串口4的空閑中斷,USART4_RX_BUF是接收緩沖區(qū),USART_REC_LEN是緩沖區(qū)的長度。這里可以看下庫中HAL_UARTEx_ReceiveToIdle_IT的定義和提示:

STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號

框1的地方說,這個函數(shù)用于在中斷模式下接收一定量數(shù)據(jù),直到指定的數(shù)據(jù)長度被接收到或者空閑中斷產(chǎn)生。也就是說,如果USART_REC_LEN定義很小,還沒到產(chǎn)生空閑中斷,接收就會完成。

框2的地方,即是打開串口空閑中斷。所以不需要額外再去開啟空閑中斷了。

2. 中斷處理:

中斷處理定義在void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)這個中斷回調(diào)函數(shù)中。注意到,和使用DMA傳輸時是同一個回調(diào)函數(shù)。

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	u8 len=0;
	u8 data[25];
	u8 uart4_len=0;
	u8 uart4_data[50];
	if(huart->Instance == USART2)
	{
		HAL_UART_DMAStop(huart);
		len = USART_REC_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 獲取DMA中傳輸?shù)臄?shù)據(jù)個數(shù)
		if (USART2_RX_BUF[0] == 0x0F && len == 25)	//接受完一幀數(shù)據(jù)
		{
			memcpy(data,USART2_RX_BUF,len);
			update_sbus(data);
		}
		HAL_UARTEx_ReceiveToIdle_DMA(&huart2,USART2_RX_BUF,USART_REC_LEN);		// 再次開啟DMA空閑中斷
	}
	
	if(huart->Instance == UART4)
	{		
		while (USART4_RX_BUF[uart4_len] != '\0')	uart4_len++;
		memcpy(uart4_data,USART4_RX_BUF,uart4_len);
		HAL_UART_Transmit(&huart4,uart4_data,uart4_len,0xff);
		
		// 調(diào)用printf是使用串口1
		printf("data: %s\r\n", uart4_data);	
		printf("data length: %d\r\n", uart4_len);	
		
		memset(USART4_RX_BUF, 0, USART_REC_LEN); 
		memset(uart4_data, 0, sizeof(uart4_data)); 

		HAL_UARTEx_ReceiveToIdle_IT(&huart4,USART4_RX_BUF,USART_REC_LEN);
	}
}	

void USART2_IRQHandler(void)
{
	HAL_UART_IRQHandler(&huart2); //調(diào)用HAL庫中斷處理公用函數(shù)
}

void UART4_IRQHandler(void)
{
	HAL_UART_IRQHandler(&huart4); //調(diào)用HAL庫中斷處理公用函數(shù)
}

回調(diào)函數(shù)中就是讀取USART4_RX_BUF緩沖區(qū)的數(shù)據(jù)和數(shù)據(jù)長度,然后做相應(yīng)處理,這里只是簡單的原數(shù)據(jù)發(fā)送回去,如果是SBSU信號或Modbus或其他帶協(xié)議幀的數(shù)據(jù),則可根據(jù)幀頭幀尾、數(shù)據(jù)長度、校驗位等做進(jìn)一步處理。

最終實現(xiàn)的效果就是上位機(jī)發(fā)送什么,單片機(jī)返回什么,如圖:

STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號

五. 總結(jié)

以上三種方式都能實現(xiàn)串口空閑中斷接收不定長數(shù)據(jù),適合用于處理不定長數(shù)據(jù)接收、減少CPU負(fù)擔(dān),相比較而言,方法三不使用DMA,使用上更簡潔。方法一、二使用DMA,好處是可以減少CPU負(fù)擔(dān)。文章來源地址http://www.zghlxwxcb.cn/news/detail-484474.html

到了這里,關(guān)于STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • STM32基于HAL庫的串口接受中斷和空閑中斷

    在通信方面。UART由于全雙工通信,可以同時接受數(shù)據(jù)和發(fā)送數(shù)據(jù)而被廣泛使用。 而接受數(shù)據(jù)則又有很多種方法 比如: 1根據(jù)結(jié)束符判斷,數(shù)據(jù)是字符串形式,所以一般串口接受的接受符就是 \\\"rn\\\"? 換成16進(jìn)制ascil碼顯示就是 0X0D? ?0X0A (對應(yīng)rn) ?2定時器中斷,設(shè)計\\\"喂狗信號量

    2023年04月08日
    瀏覽(22)
  • STM32F4_HAL庫_串口阻塞/中斷/DMA三種方式發(fā)送數(shù)據(jù)的配置

    串口阻塞發(fā)送的意思就是,發(fā)送一段數(shù)據(jù),在沒有發(fā)送完所有數(shù)據(jù)之前,一直停留在此發(fā)送函數(shù)(可設(shè)定阻塞時間),這個過程中會阻塞別的程序運行; HAL庫的配置分為兩個層次,一個是HAL庫內(nèi)部調(diào)用的、與MCU硬件相關(guān)的初始化xxx_MspInit,一個是我們外部調(diào)用的初始化xxx_In

    2023年04月25日
    瀏覽(32)
  • 【STM32+HAL庫+CubeMX】UART輪詢收發(fā)、中斷收發(fā)、DMA收發(fā)方法及空閑中斷詳解

    【STM32+HAL庫+CubeMX】UART輪詢收發(fā)、中斷收發(fā)、DMA收發(fā)方法及空閑中斷詳解

    Author: DrinkCat(szt@drinkcat.com) Copyright ? 2023 DrinkCat Original link: DrinkCat’s Blog UART是一種異步串行通信接口,常用于通過串口與外部設(shè)備進(jìn)行通信。它通過發(fā)送和接收數(shù)據(jù)幀來實現(xiàn)數(shù)據(jù)傳輸,使用起來相對簡單。UART通常包含發(fā)送器(Transmitter)和接收器(Receiver),通過兩根信號線

    2024年02月10日
    瀏覽(22)
  • STM32學(xué)習(xí)筆記(五)串口空閑中斷+DMA實現(xiàn)不定長收發(fā)(stm32c8t6)

    STM32學(xué)習(xí)筆記(五)串口空閑中斷+DMA實現(xiàn)不定長收發(fā)(stm32c8t6)

    記錄一下學(xué)習(xí)過程 DMA DMA,全稱為: Direct Memory Access,即直接存儲器訪問, DMA 傳輸將數(shù)據(jù)從一個 地址空間復(fù)制到另外一個地址空間。 這一過程無需cpu的參與,從而提高cpu使用的效率 DMA相關(guān)的參數(shù):1 數(shù)據(jù)的源地址、2 數(shù)據(jù)傳輸?shù)哪繕?biāo)地址 、3 傳輸寬度,4 傳輸多少字節(jié),5 傳

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

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

    2024年02月03日
    瀏覽(26)
  • STM32—HAL庫中斷/DMA控制和完成串口通信

    STM32—HAL庫中斷/DMA控制和完成串口通信

    目錄 一、解決的問題 二、串口通訊協(xié)議和RS-232的介紹以及USB/TTL轉(zhuǎn)232模塊的工作原理? ?1、?串口協(xié)議和RS-232標(biāo)準(zhǔn): ?(1)串口協(xié)議: (2)RS-232 標(biāo)準(zhǔn):? ?2、RS232電平與TTL電平的區(qū)別? ?3、USB/TTL轉(zhuǎn)232“模塊(CH340芯片為例)? (1)基本原理:? (2)CH340模塊介紹: ?三、搭

    2024年02月02日
    瀏覽(30)
  • STM32使用三種方式(阻塞、中斷、DMA)實現(xiàn)串口發(fā)送和接收數(shù)據(jù)

    STM32使用三種方式(阻塞、中斷、DMA)實現(xiàn)串口發(fā)送和接收數(shù)據(jù)

    記錄下學(xué)習(xí)STM32開發(fā)板的心得的和遇見的問題。 板卡型號:STM32F405RGT6 軟件:STM32CubeMX、IAR STM32串口外設(shè)提供了3種接收和發(fā)送方式:阻塞、中斷、DMA,主要給大家分享中斷方式接收不定長數(shù)據(jù)和DMA使用空閑中斷接收不定長數(shù)據(jù)。 阻塞發(fā)送: 阻塞接收: 兩個函數(shù)需要注意的就

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

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

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

    2024年04月10日
    瀏覽(44)
  • (stm32之HAL庫)UART工作在DMA模式要打開串口中斷嗎?

    (stm32之HAL庫)UART工作在DMA模式要打開串口中斷嗎?

    最近學(xué)習(xí)了stm32(F4xx)的串口在DMA模式下的使用,期間以ST官方提供的例程進(jìn)行參考學(xué)習(xí),發(fā)現(xiàn)其初始化過程中是打開了UART的中斷的,而且HAL庫中stm32f4xx_hal_uart.c文件中的DMA模式使用說明里也有這么一句話: 即在非循環(huán)模式下(也就是發(fā)完一次數(shù)據(jù)就停止的常用模式)需要配置

    2024年02月12日
    瀏覽(30)
  • HAL庫 STM32運用DMA與IDLE中斷實現(xiàn)高效串口通信 (附代碼)

    HAL庫 STM32運用DMA與IDLE中斷實現(xiàn)高效串口通信 (附代碼)

    最近想做一個控制電機(jī)的項目,其中會用到Pytho與單片機(jī)STM32之間的互同,最近也在看一些關(guān)于數(shù)據(jù)通信和拆包的相關(guān)知識,所以記錄一下這段時間里對兩者之間的互通所做的事情和發(fā)現(xiàn)的問題,以供自己和大家參考。 單片機(jī)的串口是我們常用的與電腦通信的外設(shè),本次與P

    2024年01月22日
    瀏覽(22)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包