找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6515|回复: 5
收起左侧

STM32F030-UART1_DMA使用提示

[复制链接]
ID:276663 发表于 2018-6-27 18:45 | 显示全部楼层 |阅读模式
STM32F030-UART1_DMA使用提示前言:
         今天把STM32F030C8T6的串口DMA学习了一下,为了加快各位研发人员的开发进度,避免浪费大量的时间在硬件平台上,写出个人代码调试的经验。个人水平有限,如有错误,还请指正mr.li.ming@qq.com
提示:使用的内部RC时钟,最大速度48MHz;使用USART1-PA9/PA10.
第一步:初始化端口
/*******************************************************************************
  *@brief  串口1端口初始化
  *@param  None
  * @retvalNone
****************************************************************Author:Liming**/
void USART1_GPIO_Init(void)
{
   GPIO_InitTypeDef   GPIO_Initstructure;
   RCC_AHBPeriphClockCmd(USART1_GPIO_CLK,ENABLE);   
    /*Connect pin to Periph */
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);   // 注意这里是GPIO_PinSource9
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
   GPIO_Initstructure.GPIO_Pin=USART1_TX_PIN;
   GPIO_Initstructure.GPIO_Mode=GPIO_Mode_AF;
   GPIO_Initstructure.GPIO_OType=GPIO_OType_PP;  // 推挽输出
   GPIO_Initstructure.GPIO_PuPd=GPIO_PuPd_UP;
   GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;   
   GPIO_Init(USART1_GPIO_PORT,&GPIO_Initstructure);
   GPIO_Initstructure.GPIO_Pin = USART1_RX_PIN;  // 浮空输入  
   GPIO_Init(USART1_GPIO_PORT,&GPIO_Initstructure);
}
第二步:初始化UART1
/*******************************************************************************
  * @brief  串口1初始化
  * @param  None
  * @retval None
****************************************************************Author:Liming**/
void USART1_Init(uint32_t BaudRate)
{
    USART_InitTypeDef   USART_Initstructure;
   RCC_APB2PeriphClockCmd(USART1_CLK,ENABLE);
   
    USART1_GPIO_Init(); // 调用了上面的端口初始化,故主函数里调用此函数即可。
     
   USART_Initstructure.USART_BaudRate = BaudRate;
   USART_Initstructure.USART_Parity  =USART_Parity_No;
   USART_Initstructure.USART_WordLength =USART_WordLength_8b;  
   USART_Initstructure.USART_StopBits =USART_StopBits_1;
   USART_Initstructure.USART_Mode    = USART_Mode_Rx|USART_Mode_Tx;
   USART_Initstructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;
   USART_Init(USART1,&USART_Initstructure);
   USART_ClearFlag(USART1,USART_FLAG_TC);
   USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
   USART_Cmd(USART1,ENABLE);      // 使能串口
}

第三步:DMA1中断配置
/*******************************************************************************
  * @brief  DMA1中断配置
  * @param  None
  * @retval None
****************************************************************Author:Liming**/
void DMA1_NVIC_Init(void)
{
    NVIC_InitTypeDef    NVIC_InitStructure;
   
   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
   
   NVIC_Init(&NVIC_InitStructure);
}
注意事项:1.    USART1发送数据使用的是DMA1的第二通道。查表可知,为什么还有第四通道呢,那是给USART1端口重映射了之后使用的。
                              

第四步:DMA1配置
/*******************************************************************************
  *@brief  DMA1配置
  *@param  None
  *@retval None
****************************************************************Author:Liming**/
void DMA1_Init(void)
{
   DMA_InitTypeDef DMA_InitStructure;
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
   
   DMA_InitStructure.DMA_BufferSize = 12; // 缓存大小
   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;    // 内存到内存关闭
   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;   // 普通模式
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  // 内存到外设
   DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA通道优先级
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 内存地址递增
   DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&USART1->TDR;   // 外设地址   
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设地址不变
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据长度
   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART1_TXBUFFER;   // 定义内存基地址
   DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte;//外设数据长度
   
   DMA_Init(DMA1_Channel2,&DMA_InitStructure);
   DMA_ClearITPendingBit(DMA1_IT_TC2); // 清除一次DMA中断标志
   DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);// 使能DMA传输完成中断
   
DMA1_NVIC_Init(); // 调用了上面的中断配置,故主函数里调用此函数即可
   DMA_Cmd(DMA1_Channel2,ENABLE);
}
注意事项:1.    缓存大小:就是你一次要发送多长的数据。2.    DMA方向:因为是串口发送数据,所以是从内存到外设,USART1对于单片机来讲是个外设。定义的发送数组是内存。3.    内存地址递增:其实不难理解,从发送数组的UART1_TXBUFFER[0]- UART1_TXBUFFER[n]肯定是递增的。4.    外设地址不递增:所有的数据都是通过串口发送寄存器发出去,所以外设地址不变。5.    内存/外设数据长度:串口发送的数据都是字节为单位,所以长度是Byte6.    DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);注意这一句不要写错。

第五步:DMA1的中断处理函数
/**
  *@brief  DMA1_Channel1中断服务函数
  *@param  
  *@retval
  */
void DMA1_Channel2_3_IRQHandler(void)  
{  
         /*判断DMA传输完成中断*/
         if(DMA_GetITStatus(DMA1_IT_TC2)!= RESET)                        
         {
       UART1_STATE = 2;// send over
         }
         /*清除DMA中断标志位*/   
         DMA_ClearITPendingBit(DMA1_IT_TC2);                     
}
这里使用了一个变量UART1_STATE作为标志位

第六步:使用DMA1发送串口数据
    USART1_Init(115200);
    DMA1_Init();
   
    while(1)
    {
        if(UART1_STATE==2)
        {
            UART1_STATE = 1;
           DMA_Cmd(DMA1_Channel2,DISABLE); // 发送完成先关掉DMA通道
           DMA_SetCurrDataCounter(DMA1_Channel2,12); // 设置需要发送的长度
           DMA_Cmd(DMA1_Channel2,ENABLE); // 再打开DMA通道
        }
       GPIO_SetBits(GPIOA,GPIO_Pin_4);Delay(500);
       GPIO_SetBits(GPIOA,GPIO_Pin_3);Delay(500);
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);Delay(500);
       GPIO_ResetBits(GPIOA,GPIO_Pin_3);Delay(500);
        
    }
注意事项:1.    一定要注意,DMA的传输有个长度计数器,DMA传输完成后,计数器里的值就变成了0;数据是不传了,但是通道并没有关闭。所以想要再次传输就需要修改这个长度计数器的值,但是这个值的修改必须要关闭通道后修改。所以就有了上面的步骤,关闭通道修改计数值打开通道
希望对各位看官有所帮助,并能触类旁通,对于外设到内存啊,内存到内存啊,ADCDMA啊,SPIDMA都能轻松的应用。
STM32F030-UART1_DMA使用提示.pdf (541.38 KB, 下载次数: 71)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:87079 发表于 2018-8-21 14:49 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:276663 发表于 2018-8-23 16:46 | 显示全部楼层
还请大神勿喷啊!如果觉得哪里不对可以提出来,我做改正。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:446581 发表于 2018-12-14 22:22 | 显示全部楼层
學習了
回复

使用道具 举报

ID:622200 发表于 2019-10-16 10:27 | 显示全部楼层
学习了
回复

使用道具 举报

ID:594820 发表于 2019-10-16 13:40 | 显示全部楼层
学习了,51黑不错!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表