STM32F103ZE 串口1TX-DMA多次发送并且可停止,使用V3.5.0库

                                           STM32F103ZE 串口1发送DMA

       最近在使用stm32f103ze-144pin做一个案子,记录一下,毕竟网上有些人也在寻找,或许和我遇到的问题相同,供好学者参考,减少时间。以下程序都基于V3.5.0在野火串口TX-DMA例程基础上进行调整改动,以实现能够软件可控DMA-TX

       案子需要使用串口TX-DMA功能,使用这个的原因在于:不需要用死循环等待发送完成标志位,程序如下:

      (while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);),

       我们都知道,死循环会导致mcu在main函数里面占有很大的无用时间,只能通过中断可以介入触发,而现实中,中断也不是无穷多,并且中断触发过多和中断内容过多,会导致打乱main函数程序,因此在我看来,定时中断函数内容尽可能短,触发时间我一般定为100us,时间长短每个人各不相同,可以根据需要设定。

       进入正题,设定串口DMA程序,我直接贴下:

1,开RCC-DMA时钟,程序:

       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

2,开NVIC中断,用于在发送一次完成后,DMA触发中断,以此来停止多次循环(DMA_Mode_Circular),程序:

      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//组0

      NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;  //DMA1通道4     
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;         //优先级
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;               
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);

3,设定DMA相关函数,程序:

     #define USART1_DR_Base  0x40013804  //串口1TX寄存器地址
     #define SENDBUFF_SIZE 10          //10个byte
     uint8_t SendBuff[SENDBUFF_SIZE];//数组存放数据

      DMA_DeInit(DMA1_Channel4);//缺省
      DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;    // 串口1寄存器地址
      DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;//变量指针空间地址
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//方向,从内存到外设
      DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输大小
      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;    //内存数据单位,8bit
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ;    //循环发送,此处如果为normal模式,只会发一次,后面不会再发
      DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,中
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止内存到内存的传输
      DMA_Init(DMA1_Channel4, &DMA_InitStructure);     //  配置DMA1通道 4
      DMA_Cmd (DMA1_Channel4,ENABLE);                    //使能DMA1通道4
      DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);  //DMA发送完后产生中断

     对于为什么串口1发送地址是  0x40013804 ,在《stm32f103数据手册》中有提到,截图如下:

       然后在《stm32f10xxxxx使用手册》中提到了串口发送寄存器USART-DR的相关偏移地址:

       对于选择DMA1通道4的理由在于,32已经规定了DMA1-Channel4是几种外设资源的DMA,而UART1-TX就是其中一种,这一点《stm32f10xxxxx使用手册》也提到了,因此在调用ADC或者是UART2等资源的DMA时候就要注意了。

4,主函数,程序:

    main()

  {

        //初始化;

        while(1)

       {

             //1s定时器标志位,每1s进入一次,使用定时中断,或者delay

             {

                    for(i=0;i<10;i++)//发10个
                   {
                      SendBuff[i]     = i;
                   }

                   USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//启动发送DMA请求

            }

       }

   }

以上就是将数据i内容压入SendBuff,就可以让DMA发送啦

5,中断函数,程序:

void DMA1_Channel4_IRQHandler(void)
{    
   if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET) //判断是否DMA-TX发送完毕
   {  
         USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);//失能TX请求,让DMA不再循环发送,没有这句,会一直不断循环发送
       DMA_ClearFlag(DMA1_FLAG_TC4); //清除中断标志位,下次不再进入
     }    
}

        串口相关程序已被我省略,烦请调通串口轮循发送模式后,再看此份文章,谢谢。以上就是我在调试DMA-TX中的设置程序,目前每秒只发送固定10个byte,可通过修改SENDBUFF_SIZE来改变传输数据量。

        仅供参考。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值