• STM32F4的USART1+DMA收发操作


    具体原理我也不是很懂,经过不停的百度查阅资料最后终于成功了。

    废话不多说,上代码:

     

      1 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      2 函数名称:DriveUsart1GpioInit
      3 函数功能:串口1GPIO初始化
      4 输入参数:BaudRate波特率
      5 返回参数:无
      6 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
      7 static void DriveUsart1GpioInit(uint32_t BaudRate)
      8 {
      9     GPIO_InitTypeDef  GPIO_InitStruct;
     10     USART_InitTypeDef  USART_InitStruct;
     11     NVIC_InitTypeDef NVIC_InitStructure;
     12 /****************************************初始化端口***********************************/
     13     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);                                    //使能GPIOA时钟
     14     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);                                    //使能USART1时钟
     15 
     16     GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);                                //将端口进行复用
     17     GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
     18 
     19     GPIO_InitStruct.GPIO_Mode     = GPIO_Mode_AF;
     20     GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;
     21     GPIO_InitStruct.GPIO_Pin         = GPIO_Pin_9 | GPIO_Pin_10;
     22     GPIO_InitStruct.GPIO_PuPd        = GPIO_PuPd_UP;
     23     GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;
     24     GPIO_Init(GPIOA, &GPIO_InitStruct);                                                                            //初始化端口
     25 /****************************************初始化串口***********************************/
     26     USART_StructInit(&USART_InitStruct);
     27     USART_InitStruct.USART_BaudRate = BaudRate;
     28     USART_Init(USART1,&USART_InitStruct);                                                                        //初始化串口
     29     
     30     NVIC_InitStructure.NVIC_IRQChannel                                       = USART1_IRQn;     //IRQ通道
     31     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;                       //主优先级
     32     NVIC_InitStructure.NVIC_IRQChannelSubPriority               = 0;               //从优先级
     33     NVIC_InitStructure.NVIC_IRQChannelCmd                                  = ENABLE;          //使能通道
     34     NVIC_Init(&NVIC_InitStructure);
     35     USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);                                                        //配置串口中断
     36     USART_Cmd(USART1, ENABLE);
     37 }
     38 
     39 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     40 函数名称:DMA_USART1_TX_INIT
     41 函数功能:USART1+DMA发送初始化
     42 输入参数:无
     43 返回参数:无
     44 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
     45 static void  DMA_USART1_TX_INIT(void)
     46 {  
     47       DMA_InitTypeDef  DMA_InitStructure;
     48       NVIC_InitTypeDef NVIC_InitStructure;
     49       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 
     50     
     51       DMA_DeInit(DMA2_Stream7);
     52       while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);//等待DMA可配置 
     53         
     54     /* 配置DMA2 Stream7,USART1发送 */
     55       DMA_InitStructure.DMA_Channel            = DMA_Channel_4;               //通道选择
     56       DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;            //DMA外设地址
     57       DMA_InitStructure.DMA_Memory0BaseAddr    = (u32)DMA_USART1_TX_BUF;      //DMA 存储器0地址
     58      DMA_InitStructure.DMA_DIR                = DMA_DIR_MemoryToPeripheral;  //存储器到外设模式
     59       DMA_InitStructure.DMA_BufferSize         = DMA_USART1_TX_BUF_LEN;       //数据传输量 
     60       DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;   //外设非增量模式
     61       DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;        //存储器增量模式
     62       DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
     63       DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;     //存储器数据长度:8位
     64       DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;             //使用普通模式 
     65       DMA_InitStructure.DMA_Priority           = DMA_Priority_High;             //高等优先级
     66       DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;         
     67       DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_1QuarterFull;
     68       DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;      //存储器突发单次传输
     69       DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;  //外设突发单次传输
     70         
     71       DMA_Init(DMA2_Stream7, &DMA_InitStructure);                             //初始化DMA Stream7
     72         DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE);                                                    //DMA2传输完成中断
     73         USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);                               //使能USART1DMA发送
     74         
     75         NVIC_InitStructure.NVIC_IRQChannel                   = DMA2_Stream7_IRQn ;//串口1发送中断通道
     76         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;                 //抢占优先级
     77         NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;                          //子优先级
     78         NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;                      //IRQ通道使能
     79         NVIC_Init(&NVIC_InitStructure);
     80         
     81         while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE){}
     82         DMA_Cmd(DMA2_Stream7, DISABLE);                                                                                    //不使能
     83 }
     84 
     85 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     86 函数名称:DMA_USART1_RX_INIT
     87 函数功能:USART1+DMA接收初始化
     88 输入参数:无
     89 返回参数:无
     90 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
     91 static void  DMA_USART1_RX_INIT(void)
     92 {
     93         DMA_InitTypeDef  DMA_InitStructure;
     94         NVIC_InitTypeDef NVIC_InitStructure;
     95         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 
     96 
     97       DMA_DeInit(DMA2_Stream5);
     98         while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE);//等待DMA可配置 
     99       /* 配置 DMA2 Stream5,USART1接收 */
    100         DMA_InitStructure.DMA_Channel            = DMA_Channel_4;               //通道选择
    101       DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;            //DMA外设地址
    102       DMA_InitStructure.DMA_Memory0BaseAddr    = (u32)DMA_USART1_RX_BUF;      //DMA 存储器0地址
    103     DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;  //外设到存储器模式
    104       DMA_InitStructure.DMA_BufferSize         = DMA_USART1_RX_BUF_LEN;       //数据传输量 
    105     DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;   //外设非增量模式
    106       DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;        //存储器增量模式
    107       DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
    108       DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;     //存储器数据长度:8位
    109       DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;             //使用普通模式 
    110       DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;        //中等优先级
    111       DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;         
    112       DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_1QuarterFull;
    113       DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;      //存储器突发单次传输
    114       DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;  //外设突发单次传输
    115       DMA_Init(DMA2_Stream5, &DMA_InitStructure);                             //初始化DMA Stream
    116         
    117         USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);                               //使能USART1DMA接收
    118         
    119         while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE){}
    120         DMA_Cmd(DMA2_Stream5, ENABLE);
    121 }
    122 
    123 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    124 函数名称:DriveUsart1Init
    125 函数功能:USART1+DMA初始化
    126 输入参数:BaudRate
    127 返回参数:无
    128 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
    129 void DriveUsart1Init(uint32_t BaudRate)
    130 {
    131         DriveUsart1GpioInit(BaudRate);
    132         DMA_USART1_TX_INIT();
    133         DMA_USART1_RX_INIT();
    134 }
    135 
    136 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    137 函数名称:USART1_IRQHandler
    138 函数功能:USART1中断函数
    139 输入参数:无
    140 返回参数:无
    141 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
    142 void USART1_IRQHandler(void)
    143 {
    144         if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)
    145         {
    146                 u8 clear=clear;
    147                 clear = USART1->SR;
    148                 clear = USART1->DR;       
    149                 DMA_Cmd(DMA2_Stream5, DISABLE);                                                                                                 //关闭DMA,防止处理其间有数据 
    150                 USART_ClearFlag(USART1, USART_FLAG_IDLE);                                                                          //清除IDLE标志
    151                 USART1_RX_LEN = DMA_USART1_RX_BUF_LEN - DMA_GetCurrDataCounter(DMA2_Stream5);
    152                 DMA_ClearFlag(DMA2_Stream5,DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//清除DMA2_Steam5传输完成标志  
    153                 DMA_SetCurrDataCounter(DMA2_Stream5, DMA_USART1_RX_BUF_LEN);
    154                 DMA_Cmd(DMA2_Stream5, ENABLE);
    155         }
    156 
    157       if(USART_GetFlagStatus(USART1,USART_IT_TXE) == RESET)                                                                                //串口发送完成
    158       {
    159                 USART_ITConfig(USART1,USART_IT_TC,DISABLE);
    160         }
    161 }
    162 
    163 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    164 函数名称:DMA2_Stream7_IRQHandler
    165 函数功能:DMA中断
    166 输入参数:无
    167 返回参数:无
    168 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
    169 void DMA2_Stream7_IRQHandler(void)
    170 {
    171     //清除标志
    172     if(DMA_GetFlagStatus(DMA2_Stream7,DMA_FLAG_TCIF7)!=RESET)                                    //等待DMA2_Steam7传输完成
    173     {
    174             DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7);                                                     //清除DMA2_Steam7传输完成标志
    175            DMA_Cmd(DMA2_Stream7,DISABLE);
    176         USART_ITConfig(USART1,USART_IT_TC,ENABLE);                                                      //打开串口发送完成中断
    177     }
    178 }
    179 
    180 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    181 函数名称:DMA_USART1_Send
    182 函数功能:串口发送数据
    183 输入参数:data待发送数据  , size 发送数据字节数
    184 返回参数:无
    185 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
    186 void DMA_USART1_Send(u8 *data,u16 size)
    187 {
    188     memcpy(DMA_USART1_TX_BUF,data,size);                                                                            //复制数据到DMA发送缓存区
    189     while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);                                                //确保DMA可以被设置
    190     DMA_SetCurrDataCounter(DMA2_Stream7,size);                                                                //设置数据传输长度
    191     DMA_Cmd(DMA2_Stream7,ENABLE);                                                                                            //打开DMA数据流,开始发送
    192 }

    不出意外的话直接复制就可以使用。

    参考文章:

      1、(2条消息) STM32F4使用DMA收发数据_u010001130的博客-CSDN博客

      2、(2条消息) STM32F4 USART1 使用DMA发送、接收数据_iTech#51122的博客-CSDN博客

  • 相关阅读:
    前端websocket连接mqtt不能使用1883端口的问题
    关于aws-Lambda的cron周期性计划任务-表达式的定义方式
    千古奇文-寒窑赋/破窑赋-命运赋-吕蒙正
    关于Linux下aws-cli-2版本的安装
    关于WinSCP如何通过Tunnel隧道进行远程连接-进行文件的传输
    python函数-strip&lstrip&rstrip字符串处理函数
    关于计算机或编程中-时间及各单位换算的的方法记录
    python中print函数的使用小技术-使用分隔符和行尾符
    关于pwd命令小技巧-确认当前工作目录的绝对路径中是否包含软链接目录名
    关于Linux-Redhat-7.x系统不能创建纯数字用户名的原因及临时解决方法
  • 原文地址:https://www.cnblogs.com/jiayezi/p/15092739.html
Copyright © 2020-2023  润新知