美文网首页
stm32F1---串口空闲中断+DMA,接收不定长数据

stm32F1---串口空闲中断+DMA,接收不定长数据

作者: 飞向深空 | 来源:发表于2019-12-02 11:39 被阅读0次

    参考博客:https://blog.csdn.net/jiejiemcu/article/details/82743945

    F1_DMA通道.PNG

    main.c

    
    
    #include "system.h"
    #include "SysTick.h"
    #include "led.h"
    #include "usart.h"
    #include "dma.h"
    
    /*******************************************************************************
    * 函 数 名         : main
    * 函数功能         : 主函数
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    int main()
    {
        u8 i=0;
        
        SysTick_Init(72);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
        LED_Init();
        USART1_Init(9600);
        DMAx_Init((u32)&USART1->DR,(u32)send_buf,10);
        
        printf("开始");
        while(1)
        {
            if(flag)
            {
                for(i=0;i<10;i++)
                {
                    printf("0x%02X",send_buf[i]);
                }
                flag=0;
            }
        }
    }
    
    

    usart.c

    
    #include "usart.h"       
    u8 flag=0;
    u32 USART_Rx_Sta;
    
    u8 send_buf[send_buf_len];
    
    int fputc(int ch,FILE *p)  //函数默认的,在使用printf函数时自动调用
    {
        USART_SendData(USART1,(u8)ch);  
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
        return ch;
    }
    
    /*******************************************************************************
    * 函 数 名         : USART1_Init
    * 函数功能         : USART1初始化函数
    * 输    入         : bound:波特率
    * 输    出         : 无
    *******************************************************************************/ 
    void USART1_Init(u32 bound)
    {
       //GPIO端口设置
        NVIC_InitTypeDef NVIC_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
        USART_Init(USART1,&USART_InitStructure);
        
        USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
        USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
        USART_Cmd(USART1,ENABLE);
        //USART_ClearFlag(USART1, USART_FLAG_TC);
    }
    
    /*******************************************************************************
    * 函 数 名         : USART1_IRQHandler
    * 函数功能         : USART1中断函数
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/ 
    void USART1_IRQHandler(void)                    //串口1中断服务程序
    {
    
        if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //接收中断
        {
            u32 buff_len;
            
            USART1->SR;
            USART1->DR;
            
            DMA_Cmd(DMA1_Channel5,DISABLE);
            
            DMA_ClearFlag(DMA1_FLAG_TC5);
            
            buff_len = send_buf_len - DMA_GetCurrDataCounter(DMA1_Channel5);
            USART_Rx_Sta = buff_len;
            printf("数据长度是%d\n",buff_len);
            DMA_SetCurrDataCounter(DMA1_Channel5,send_buf_len);
            
            DMA_Cmd(DMA1_Channel5,ENABLE);
            flag=1;
        } 
        USART_ClearFlag(USART1,USART_FLAG_TC);
    }   
    

    usart.h

    #ifndef __usart_H
    #define __usart_H
    
    #include "system.h" 
    #include "stdio.h" 
    #define send_buf_len 10
    extern u8 flag;
    void USART1_Init(u32 bound);
    extern u8 send_buf[send_buf_len];
    #endif
    
    

    dma.c

    #include "dma.h"
    
    /*******************************************************************************
    * 函 数 名         : DMAx_Init
    * 函数功能         : DMA初始化函数
    * 输    入         : 
                         DMAy_Channelx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
                         par:外设地址
                         mar:存储器地址
                         ndtr:数据传输量
    * 输    出         : 无
    *******************************************************************************/ 
    void DMAx_Init(u32 par,u32 mar,u16 ndtr)
    {
        DMA_InitTypeDef DMA_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //DMA1 时钟使能
        DMA_DeInit(DMA1_Channel5);
        DMA_InitStructure.DMA_MemoryBaseAddr = mar;
        DMA_InitStructure.DMA_PeripheralBaseAddr = par;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize = ndtr;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA_Mode_Normal
        DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel5,&DMA_InitStructure);
        
        DMA_ClearFlag(DMA1_FLAG_TC5);
        DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);
        DMA_Cmd(DMA1_Channel5,ENABLE);
        
    }
    
    

    相关文章

      网友评论

          本文标题:stm32F1---串口空闲中断+DMA,接收不定长数据

          本文链接:https://www.haomeiwen.com/subject/eavxgctx.html