搜索
bottom↓
回复: 18

STM32用DMA方式发送串口数据写了个函数比较蛋疼,长度,指针...?

[复制链接]

出0入0汤圆

发表于 2015-1-12 12:28:42 | 显示全部楼层 |阅读模式
void USART1_Send(s8 *buf,u16 len)
{
        DMA_InitTypeDef DMA_InitStructure;
       
       
        DMA_DeInit(DMA1_Channel4);
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)( &(USART1->DR));
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32) buf;         
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
        DMA_InitStructure.DMA_BufferSize = len;
        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_InitStructure.DMA_Priority = DMA_Priority_Medium;
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel4, &DMA_InitStructure);
        DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
        USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
        DMA_Cmd(DMA1_Channel4, ENABLE);       
       
       
}

虽然发送都可以成功,但比较蛋疼 有简洁点的方式不?????

出0入17汤圆

发表于 2015-1-12 13:02:41 | 显示全部楼层
默默的看了下我的
  1. /*
  2. * 函数名:USART1_DMA_Config
  3. * 描述  :串口1的DMA 的初始化配置
  4. * 输入  :无
  5. * 输出  : 无
  6. * 调用  :在USART1_INIT()中被调用
  7. */
  8. void USART1_DMA_Config(void)
  9. {
  10.     DMA_InitTypeDef DMA_InitStructure;

  11.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //开启DMA时钟

  12. //配置串口1发送DMA
  13.          DMA_DeInit(DMA1_Channel4);
  14.         /*设置DMA源:内存地址&串口数据寄存器地址*/
  15.     DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;          

  16.         /*内存地址(要传输的变量的指针)*/
  17.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Txd1Buffer;         //发送的内存地址任意,请参考发送函数
  18.        
  19.         /*方向:从内存到外设*/               
  20.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;       
  21.        
  22.         /*传输大小DMA_BufferSize=0*/       
  23.     DMA_InitStructure.DMA_BufferSize = 0;                     //发送的数据个数任意,请参考发送函数
  24.        
  25.         /*外设地址不增*/            
  26.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  27.        
  28.         /*内存地址自增*/
  29.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;       
  30.        
  31.         /*外设数据单位*/       
  32.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  33.        
  34.         /*内存数据单位 8bit*/
  35.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         
  36.        
  37.         /*DMA模式:一次传输,循环*/
  38.     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;         
  39.        
  40.         /*优先级:中*/       
  41.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  //DMA_Priority_VeryHigh;
  42.        
  43.         /*禁止内存到内存的传输        */
  44.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  45.     DMA_Init(DMA1_Channel4, &DMA_InitStructure);
  46.                
  47.         /*配置DMA1的4通道*/                     
  48.         DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);   //配置DMA发送完成后产生中断
  49.         DMA_Cmd (DMA1_Channel4,DISABLE);


  50. //配置串口1接收DMA


  51.         /*设置DMA源:内存地址&串口数据寄存器地址*/
  52.         DMA_DeInit(DMA1_Channel5);
  53.     DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;          

  54.         /*内存地址(要传输的变量的指针)*/
  55.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Rcv1Buffer;         //接收缓存是固定不变的
  56.        
  57.         /*方向:从内存到外设*/               
  58.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;       
  59.        
  60.         /*传输大小DMA_BufferSize=BUFFSIZE*/       
  61.     DMA_InitStructure.DMA_BufferSize = Rcv1_BUFFSIZE;          //必须这样设置
  62.        
  63.         /*外设地址不增*/            
  64.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  65.        
  66.         /*内存地址自增*/
  67.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;       
  68.        
  69.         /*外设数据单位*/       
  70.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  71.        
  72.         /*内存数据单位 8bit*/
  73.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         
  74.        
  75.         /*DMA模式:一次传输,循环*/
  76.     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;         

  77.         /*优先级:中*/       
  78.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; // DMA_Priority_VeryHigh;
  79.        
  80.         /*禁止内存到内存的传输        */
  81.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  82.        
  83.         /*配置DMA1的5通道*/                  
  84.     DMA_Init(DMA1_Channel5, &DMA_InitStructure);           
  85.         DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,DISABLE);   //DMA接收不产生中断
  86.         DMA_Cmd (DMA1_Channel5,ENABLE);

  87. }
复制代码

出0入17汤圆

发表于 2015-1-12 13:08:58 | 显示全部楼层
  1. /*
  2. * 函数名:USART1_Send
  3. * 描述  :串口1发送数据函数
  4. * 输入  :要发送数据的首地址,发送数据的个数。发送数据的地址任意,并不用固定为Txd1Buffer
  5. * 输出  : 无
  6. * 举例         :Usart1_Send("Hello word!",11); Usart1_Send(Txd1Buffer,11);
  7. */

  8. void USART1_Send(uint8_t *pbuffer, uint32_t size)
  9. {
  10.   
  11.    DMA_Cmd (DMA1_Channel4,DISABLE);
  12.    DMA1_Channel4->CMAR =  (u32)pbuffer;
  13.    DMA1_Channel4->CNDTR = size;
  14.    DMA_Cmd (DMA1_Channel4,ENABLE);                                        //使能DMA,开始发送
  15.    Txd1_Flag=1;                                                                                //数据发送中
  16.   // LED1(ON);                                                                                //灯亮
  17. }
复制代码

出0入17汤圆

发表于 2015-1-12 12:28:43 | 显示全部楼层
  1. /*
  2. * 函数名:USART1_SendOK_IQ
  3. * 描述  :串口1发送数据完毕后,会调用的中断函数,将发送标志置0
  4. * 输入  :无
  5. * 输出  : 无
  6. * 调用         :此函数需在stm32f10x_it.c 的 DMA1_Channel4_IRQHandler()中被调用
  7. */
  8. void USART1_SendOK_IQ(void)
  9. {
  10. //判断是否为DMA发送完成中断
  11.         if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)
  12.         {  
  13.                 DMA_ClearITPendingBit(DMA1_IT_GL4);
  14.                 DMA_ClearFlag(DMA1_FLAG_TC4);
  15.                 DMA_Cmd (DMA1_Channel4,DISABLE);
  16.                 Txd1_Flag = 0;                                                    //数据发送完毕
  17.                 //LED关闭   
  18.         //        LED1(OFF);       

  19.         }
  20.        
  21. }
复制代码

出0入0汤圆

发表于 2015-1-12 23:16:47 | 显示全部楼层
楼上的代码写的不错 ,nice

出0入0汤圆

发表于 2015-1-12 23:46:12 来自手机 | 显示全部楼层
学习了谢谢

出0入0汤圆

发表于 2015-1-12 23:47:57 | 显示全部楼层
先收藏了,有时间慢慢看,前端时间也是这个在纠结…………

出0入0汤圆

发表于 2015-1-12 23:55:17 | 显示全部楼层
本帖最后由 wuzhujian 于 2015-1-12 23:57 编辑

先初始DMA通道和USARTr(包括DMA允许),要发送数据的时候,只要填上数据缓冲区地址和发送的数量就可以了。
没必要每天都去填这些参数。

另外,代码不要写的太长,看起来头痛的。
注释与代码最好左右分开。

代码与注释混在一起,让人难爱的,自己也难受。

出0入0汤圆

发表于 2015-1-13 08:47:43 | 显示全部楼层

出0入0汤圆

发表于 2015-1-13 09:17:05 | 显示全部楼层
果然都是高手啊,学习了

出0入10汤圆

发表于 2015-1-25 21:21:50 | 显示全部楼层

你没有配置优先级,还是把优先级放在其他地方进行配置了,NVIC

出0入17汤圆

发表于 2015-1-26 08:21:18 | 显示全部楼层
10xjzheng 发表于 2015-1-25 21:21
你没有配置优先级,还是把优先级放在其他地方进行配置了,NVIC

有单独NVIC函数  USART1_NVIC_Config()

  1. /*
  2. * 函数名:USART1_INIT
  3. * 描述  :串口1初始化函数,包括引脚配置,串口配置,DMA配置及中断优先级配置
  4. * 输入  :无
  5. * 输出  : 无
  6. */
  7. void USART1_INIT(void)
  8. {
  9.          USART1_Config();
  10.          USART1_DMA_Config();
  11.          USART1_NVIC_Config();

  12.          Rcv1Counter = 0;
  13.          Rcv1_Flag = 0;
  14.          Txd1_Flag = 0;
  15. }
复制代码

出0入10汤圆

发表于 2015-1-26 08:41:13 | 显示全部楼层
wicy001 发表于 2015-1-26 08:21
有单独NVIC函数  USART1_NVIC_Config()

可否发个工程给我,我是调USART2,然后一直很奇怪,比如你打印“abc”,他只会打印“aaa”

出0入0汤圆

发表于 2015-1-26 09:01:23 | 显示全部楼层
10xjzheng 发表于 2015-1-26 08:41
可否发个工程给我,我是调USART2,然后一直很奇怪,比如你打印“abc”,他只会打印“aaa” ...

配置错了吧,设置为指针递增模式

出0入10汤圆

发表于 2015-1-26 09:07:39 | 显示全部楼层
DiaoMao_Huang 发表于 2015-1-26 09:01
配置错了吧,设置为指针递增模式

有配置好啊,麻烦帮忙看下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-1-26 09:35:46 | 显示全部楼层
  DMA_InitStructure_TX.DMA_MemoryBaseAddr = (uint32_t)USART1_TxBuffer;
  DMA_InitStructure_TX.DMA_BufferSize = len;           (这一个,你要配置为3)
然后单片机自动就发出去了

出0入17汤圆

发表于 2015-1-26 13:07:06 | 显示全部楼层
10xjzheng 发表于 2015-1-26 08:41
可否发个工程给我,我是调USART2,然后一直很奇怪,比如你打印“abc”,他只会打印“aaa” ...

工程就免了,给你个完整的驱动吧。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-4-17 17:50:12 | 显示全部楼层
正在写UART+DMA 的Debug方式,谢谢帮忙!

出0入0汤圆

发表于 2015-4-17 20:53:22 | 显示全部楼层
可以参考这个帖子里的源代码,里边有所有的USART的DMA不定长度收发代码
http://www.amobbs.com/thread-5613322-1-1.html
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-4 14:49

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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