1.步骤
1.打开STM32cubemx,我的版本号是4.27.0,新建工程,选择芯片,例如STM32F103R8T6
2.左侧使能串口1,sys那里选择serial wire,否则导致后面无法下载程序,配置时钟树,使能串口中断
3.在configuration页面配置DMA,如下所示
4.点击生成代码,在keil打开,在HAL_UART_IRQHandler(&huart1);
前面添加 UsartReceive_IDLE(&huart1);
此函数实现如下:
void UsartReceive_IDLE(UART_HandleTypeDef *huart)//IDLE接收数据
{
uint32_t temp;
if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1);
temp = huart1.hdmarx->Instance->CNDTR;
UsartType.RX1_Size = RX_LEN - temp;
UsartType.RX_flag=1;
HAL_UART_Receive_DMA(&huart1,(uint8_t *)UsartType.RX1_pData,RX_LEN);
}
}
在主程序前面使能DMA接收,使能串口idle中断
#define RX1_LEN 300
typedef struct
{
uint8_t RX1_flag;
uint16_t RX1_Size;
uint8_t RX1_pData[RX1_LEN];
} USART1_RECEIVETYPE;
void DMA4_START()//开启DMA
{
HAL_UART_Receive_DMA(&huart1, (uint8_t *) Usart1Type.RX1_pData, RX1_LEN);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
}
main里面轮询flag就行,数据分析判断,清除flag
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
DMA1_START();//开启DMA
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(Usart1Type.RX1_flag == 1)
{
//数据处理
Usart1Type.RX1_flag = 0; // clean flag
Usart1Type.RX1_Size = 0;
memset(Usart1Type.RX1_pData, 0, sizeof(Usart1Type.RX1_pData));
}
}
/* USER CODE END 3 */
}
或者在中断清标志
回调处理
2.单独DMA方式
void UART4_IRQHandler(void)
{
uint8_t data = 0;
data = data;
if(USART_GetITStatus(LoraUSARTx, USART_IT_RXNE) == SET)
{
USART_ClearITPendingBit(LoraUSARTx, USART_IT_RXNE);
if(Lora_RecvData.Rx_over == 0)
Lora_RecvData.RxBuf[Lora_RecvData.Rx_count++] = LoraUSARTx->DR;
}
if(USART_GetITStatus(LoraUSARTx, USART_IT_IDLE) == SET)
{
data = LoraUSARTx->SR;
data = LoraUSARTx->DR;
Lora_RecvData.Rx_over = 1; //接收完成,主程序查询此flag
}
}
参考以下文章:
http://www.firebbs.cn/thread-24555-1-1.html
http://www.firebbs.cn/thread-23695-1-1.html
http://www.waveshare.net/study/article-644-1.html
2.空闲时间