单片机
返回首页

stm32f103 DMA接收定长数据和不定长数据

2020-08-03 来源:51hei

最近做了DMA接收定长数据和不定长数据的程序,现在来分享一下定长:
#include 'led.h'
#include 'delay.h'
#include 'key.h'
#include 'sys.h'
#include 'lcd.h'
#include 'usart.h'         
#include 'dma.h'


#define USART1_RXBUF_SIZE 200        //发送数据长度,最好等于sizeof(TEXT_TO_SEND)+2的整数倍.

u8 u1rxbuf[USART1_RXBUF_SIZE];        //发送数据缓冲区1
u8 u2rxbuf[USART1_RXBUF_SIZE];        //发送数据缓冲区2
u8 witchbuf=0;                  //标记当前使用的是哪个缓冲区,0,使用u1rxbuf;1,使用u2rxbuf;

u16 rxcnt=0;

//处理DMA1 通道5的接收完成中断
void DMA1_Channel5_IRQHandler(void)
{
                if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET)//DMA接收完成标志
                {
                                DMA_Cmd(DMA1_Channel5, DISABLE );   //关闭USART1 TX DMA1 所指示的通道  
                                if(witchbuf)                        //之前用的u2rxbuf,切换为u1rxbuf
                                {
                                                //printf('use u1rxbufrn');
                                                DMA1_Channel5->CMAR=(u32)u1rxbuf;
                                                witchbuf=0;                     //下一次切换为u2rxbuf
                                }else                               //之前用的u1rxbuf,切换为u2rxbuf
                                {
                                                //printf('use u2rxbufrn');
                                                DMA1_Channel5->CMAR=(u32)u2rxbuf;
                                                witchbuf=1;                     //下一次切换为u1rxbuf
                                }
                                rxcnt+=200;
                                DMA_SetCurrDataCounter(DMA1_Channel5,USART1_RXBUF_SIZE);//DMA通道的DMA缓存的大小
                                DMA_Cmd(DMA1_Channel5, ENABLE);     //使能USART1 TX DMA1 所指示的通道        
                                DMA_ClearITPendingBit(DMA1_IT_TC5); //清除中断标志  
                }
}
//初始化IO 串口2
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率         
void USART2_Init(u32 bound)
{  
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);//使能GPIOA,D时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;        //PA2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位

         
    USART_InitStructure.USART_BaudRate = bound;//波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
    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(USART2, &USART_InitStructure); ; //初始化串口

    USART_Cmd(USART2, ENABLE);                    //使能串口

}


int main(void)
{         
        u16 i;
        u16 pro=0;//进度
  u8 oldsta=0;
  u8 *p;

        delay_init();                     //延时函数初始化         
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(115200);                 //串口初始化为115200
  USART2_Init(115200);
        LED_Init();                                  //初始化与LED连接的硬件接口
        LCD_Init();                                   //初始化LCD         
//        KEY_Init();                                //按键初始化
  POINT_COLOR=RED;//设置字体为红色
        LCD_ShowString(30,50,200,16,16,'WarShip STM32');         

  USART1_DMA_RX_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)u1rxbuf,USART1_RXBUF_SIZE);//设置串口1的DMA接收
  USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);    //使能串口1的DMA接收     

         
        LCD_ShowString(30,70,200,16,16,'DMA TEST');                  
        LCD_ShowString(30,90,200,16,16,'ATOM@ALIENTEK');
        LCD_ShowString(30,110,200,16,16,'2015/1/15');        
         LCD_ShowString(30,130,200,16,16,'KEY0:Start');
                  
        i=0;
        while(1)
        {   
      if(oldsta!=witchbuf)
                        {
                                        oldsta=witchbuf;
                                        if(oldsta)p=u1rxbuf;    //当前正在使用u2rxbuf接收,所以u1rxbuf是有数据的
                                        else p=u2rxbuf;
                                        for(i=0;i                                        {
                                                        USART2->DR=p;  
                                                        while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
                                        }  
                        }               
        }
}



不定长:
#include 'led.h'
#include 'delay.h'
#include 'key.h'
#include 'sys.h'
#include 'lcd.h'
#include 'usart.h'         
#include 'dma.h'

/************************************************
************************************************/



#define USART1_RXBUF_SIZE 200        //发送数据长度,最好等于sizeof(TEXT_TO_SEND)+2的整数倍.

extern u8 receive_data[128];        //发送数据缓冲区1
extern u8 receive_flag;

int main(void)
{         
        delay_init();                     //延时函数初始化         
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(115200);                 //串口初始化为115200
        LED_Init();                                  //初始化与LED连接的硬件接口
        LCD_Init();                                   //初始化LCD         

  USART1_DMA_RX_Config();//设置串口1的DMA接收
        
  POINT_COLOR=RED;//设置字体为红色
        LCD_ShowString(30,50,200,16,16,'WarShip STM32');                     
        LCD_ShowString(30,70,200,16,16,'DMA TEST');                  
        LCD_ShowString(30,90,200,16,16,'ATOM@ALIENTEK');
        LCD_ShowString(30,110,200,16,16,'2015/1/15');        
         LCD_ShowString(30,130,200,16,16,'KEY0:Start');
        while(1)
        {   
                while(receive_flag == 0);
                receive_flag = 0;
                printf('%s',receive_data);
        }
}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章