串口空闲中断接收看这一篇就够

库函数的实现,这篇文章非常清楚https://mp.weixin.qq.com/s/FPLdThjKX2sOlMZb_OyQdQ

我来操作:

第一步:初始化

void TS_USART3_Init(void)
{
      USART_Config(3, 9600, USART_WordLength_8b, USART_Parity_No,  2,  0, ENABLE, DISABLE);//前面自己写的全集
      USART3_DMA();//加入空闲中断+DMA
      USART3_485_En_Init();//RS485使能管脚
      USART3_485_OFF();//RS485使能管脚拉低进入接收模式
}

主要是第二个函数:

//#define GPS_Rev_Buf_Size 30
//u8 GPS_Uart_Rcv_Buf[GPS_Rev_Buf_Size];
void USART3_DMA(void)
{

DMA_InitTypeDef DMA_InitStructure;    
    /*先否定前面的初始化*/
USART_ITConfig(USART3,USART_IT_TC,  DISABLE);//关闭发送中断 
USART_ITConfig(USART3,USART_IT_RXNE,DISABLE);//关闭接收中断!  
USART_ITConfig(USART3,USART_IT_IDLE,ENABLE); //开启总线空闲中断 !
USART_Cmd(USART3, ENABLE);                     // 使能 USART3
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);                      //使能DMA1时钟  
DMA_DeInit(DMA1_Channel3);                                              //初始化DMA1通道3  串口3接收通道
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004804;                  //串口3接收数据的地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)GPS_Uart_Rcv_Buf;      //数据存放的复制
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                      //数据传送方向  串口3作为数据源
DMA_InitStructure.DMA_BufferSize = GPS_Rev_Buf_Size;                    //接收数据个数       
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        //外围设备 串口3 地址不递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                 // DMA存储地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外围设备 串口3 数据宽度 8bits
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         //DMA存储 数据宽度 8bits
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                       
//DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                   //串口3通道优先为中等
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                            //关闭内存到内存
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
 
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);  //使能串口3 DMA功能
DMA_Cmd(DMA1_Channel3, ENABLE);
}

现在就配置好了,用的是DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

也就是中断接收数据:过来0X12,0X34,0XFF这样一串,在一串全部过来以后会掉到中断去,并且这个串已经DMA自动搬运到数组中了!

因为我是一次,下次DMA就无效了,所以服务函数需要再起启动

void USART3_IRQHandler(void)
{
    u8 res,i;   
    if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)        //串口3    总线空闲    
    {
      //USART_ClearITPendingBit(USART3, USART_IT_IDLE);  //清除标记位
        res = USART3->SR;//同上
        res = USART3->DR; //清USART_IT_IDLE标志----------所谓的清空不是int a=0  而是一个数 a=->dr你拿走 它就空了
        DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA1通道        
        Iusart3_received_handle();//去分析数组吧!!
        DMA_SetCurrDataCounter(DMA1_Channel3,GPS_Rev_Buf_Size);  //接收数据个数  
        DMA_Cmd(DMA1_Channel3, ENABLE);                          //开启DMA1通道3    
    }

 

继续可以试试循环模式

https://blog.csdn.net/goldbr/article/details/81193396

你可能感兴趣的:(串口空闲中断接收看这一篇就够)