環境:
- STM32CubeIDE
- STM32F103RB
- WIN10
- HAL庫V1.8
首先配置序列槽:
開啟序列槽中斷:
開啟DMA接收:
配置中斷分組:
然後生成代碼就可以了。
進入代碼,添加序列槽1中斷服務程式:
#define UART_RX_LEN 1024 // 一次最大接收的資料量
uint8_t UART_RX_BUF[UART_RX_LEN]; // DMA資料接收緩存
__IO uint16_t UART_RX_STA = 0; // 第15bit表示一幀資料接收完成,第14~0位表示接收到的資料量
void USART1_IRQHandler(void)
{
if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 空閑中斷标記被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除中斷标記
HAL_UART_DMAStop(&huart1); // 停止DMA接收
UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 總資料量減去未接收到的資料量為已經接收到的資料量
UART_RX_BUF[UART_RX_STA] = 0; // 添加結束符
UART_RX_STA |= 0X8000; // 标記接收結束
HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 重新啟動DMA接收
}
}
使能空閑中斷和DMA接收:
HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 啟動DMA接收
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能空閑中斷
while死循環中加入發回的代碼:
if(UART_RX_STA & 0X8000)
{
HAL_UART_Transmit(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF, 100); // 将接收到的資料發送回去
UART_RX_STA = 0; // 清除标記
}
完整代碼如下:
/* USER CODE BEGIN 0 */
#define UART_RX_LEN 1024
uint8_t UART_RX_BUF[UART_RX_LEN];
__IO uint16_t UART_RX_STA = 0;
void USART1_IRQHandler(void)
{
if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 空閑中斷标記被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清楚中斷标記
HAL_UART_DMAStop(&huart1); // 停止DMA接收
UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 總資料量減去未接收到的資料量為已經接收到的資料量
UART_RX_BUF[UART_RX_STA] = 0; // 添加結束符
UART_RX_STA |= 0X8000; // 标記接收結束
HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 重新啟動DMA接收
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 啟動DMA接收
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能空閑中斷
while (1)
{
if(UART_RX_STA & 0X8000)
{
HAL_UART_Transmit(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF, 100); // 将接收到的資料發送回去
UART_RX_STA = 0;
}
}
}
/* USER CODE END 0 */