搜索
bottom↓
回复: 151

STM32串口DMA方式接收数据。类似环形FIFO。超省CPU资源!

  [复制链接]

出0入0汤圆

发表于 2013-4-22 17:54:01 | 显示全部楼层 |阅读模式
一直以来都为串口接收数据所困扰:
1:如果用接收中断的话,每接收1byte就得中断一次。这样太消耗CPU资源!
2:如果用DMA方式接收数据,那么如何确定接收数据的长度又不好确定了。(比如GPRS模块AT命令的接收!)
3:DMA方式接收+定时器的超时中断。这样处理也比较复杂,需要开定时器,关定时器。。。。个人不喜欢!(ATMEL的ARM系列的串口倒是有硬件超时中断可以直接使用。我现在用AT91SAM7系列处理GPRS的AT命令就采用这种方式,挺好用。但是STM32就没有了,需要自己加定时器,还要硬件处理:RXD连接定时器的一个触发引脚!)。

所以之前用STM32接收串口数据都是采用接收中断,然后写入一个FIFO队列。然后在主函数里面去查询队列缓冲中是否有数据需要处理。但是这样的话,串口中断服务函数始终是很大的硬件开销。比如我现在用串口下载STM32的升级固件的时候,数据量较大。

废话完毕,今天突然脑子发热想要把DMA和环形的FIFO队列结合一下使用。把想法跟同事交流一下,觉得有可行性!马上动手实验。经过半天调试,结果令人满意。
说说我的思路(本人表达能力有限,描述不清楚的希望大家跟帖):关在在于让DMA来实现“环形队列中往缓冲区写入1byte”的功能!剩下的读取队列就跟普通环形队列没多大区别了。这样我们的程序中拥有了一个不占用CPU资源的“环形队列”后,我们就不用担心CPU频繁中断,我们只需要在适当的时间读取队列中的数据然后慢慢分析处理数据!
A:串口初始化配置串口为DMA方式接收数据。具体配置请看:

        DMA1_Channel5->CCR = DMA_CCR5_PL        //通道优先级最高
                                           | DMA_CCR5_MINC        //MEM地址增量使能
                                           | DMA_CCR5_CIRC        //接收缓冲区循环模式
                                           | DMA_CCR5_TCIE        //传输完成中断
                                           ;
        DMA1->IFCR |= 0x000F0000;
        DMA1_Channel5->CPAR = USART1_BASE + 4;
        // Enable the DMA1_CH5 Interrupt
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

关键,开启DMA循环模式,这样接收完之后会自动回到FIFO缓冲区开头地方,这样能省不少事情。
当然,考虑到可能把缓冲区撑爆的情况,所以开启通道传输完成标志位,在传输完成中断中查询一下队列中有多少数据没有读取出来,如果太多数据没有读取,那么在中断里面处理读取FIFO数据并做相应处理!

B:关于FIFO的一些声明:
#define FIFO_OK                                0
#define FIFO_ERROR_PARAM        -1
#define FIFO_ERROR_MEM                -2
#define FIFO_ERROR_FULL                -3
#define FIFO_ERROR_EMPTY        -4
#define FIFO_ERROR_BUSY                -5

typedef struct _FIFO_TYPE_
{
        INT32U size;                        //FIFO缓冲区大小
        INT32U front;                        //FIFO下一读取位置
        INT32U staraddr;                //FIFO缓冲区起始地址
        INT32U endaddr;                        //FIFO缓冲区结束地址
        INT8U buffer[1];                //实际长度由初始化分配内存!(memloc的时候确定)
}FIFOTYPE;


C:关于FIFO队列的初始化,具体配置
// **************************************************************
//函数:FIFO_Init
//参数:FIFO类型的指针地址,队列大小
//返回:>=0初始化成功
//描述:初始化FIFO队列
// **************************************************************
Int32S FIFO_Init(FIFOTYPE * *fifo,INT32U fifosize)
{
        volatile INT32U da;
        if(fifo==NULL || fifosize == 0)
        {
                return FIFO_ERROR_PARAM;
        }
        (*fifo) = malloc(16+fifosize);
        if((*fifo) == NULL)               
        {
                //已经在堆里面申请了地址
                return FIFO_ERROR_MEM;
        }
        (*fifo)->size = fifosize;
        (*fifo)->staraddr = (INT32U)(&(*fifo)->buffer[0]);                        //记录FIFO缓冲区起始地址
        (*fifo)->endaddr = (INT32U)(&(*fifo)->buffer[fifosize-1]);        //记录FIFO缓冲区结束地址
        (*fifo)->front = (*fifo)->staraddr;                                                        //FIFO下一读取数据地址
        memset((*fifo)->buffer,0,(*fifo)->size);                                        //清除缓冲区里面的数据,可省略

        DMA1_Channel5->CCR &= ~DMA_CCR5_EN;
        DMA1_Channel5->CMAR = (INT32U)(*fifo)->staraddr;                        //配置DMA传输地址
        DMA1_Channel5->CNDTR = (*fifo)->size;                                                //配置DMA传输数据量
        da = USART1->DR;
        da = da;
        DMA1->IFCR |= 0x000F0000;
        DMA1_Channel5->CCR |= DMA_CCR5_EN;
       
        return FIFO_OK;
}

D:清空队列缓冲区函数
// **************************************************************
//函数:FIFO_Clear
//参数:无
//返回:无
//描述:清空FIFO队列
// **************************************************************
Int32S FIFO_Clear(FIFOTYPE *fifo)
{
        volatile INT32U da;
        if(fifo == NULL)
                return FIFO_ERROR_PARAM;
        fifo->front = fifo->staraddr;                                                                //将下一读取地址设置为FIFO缓冲开始
        DMA1_Channel5->CCR &= ~DMA_CCR5_EN;
        DMA1_Channel5->CMAR = fifo->staraddr;                                                //重新配置DMA地址
        DMA1_Channel5->CNDTR = fifo->size;                                                        //重新配置DMA传输数据量
        memset(fifo->buffer,0,fifo->size);
        da = USART1->DR;
        da = da;
        DMA1->IFCR |= 0x000F0000;
        DMA1_Channel5->CCR |= DMA_CCR5_EN;
       
        return FIFO_OK;
}

E:读取FIFO缓冲区,这个跟标准的环形队列基本没区别
// **************************************************************
//函数:FIFO_Read
//参数:队列指针,1byte数据指针
//返回:>=0读取成功
//描述:从FIFO队列中读出1byte数据
// **************************************************************
Int32S FIFO_Read(FIFOTYPE *fifo,INT8U *data)
{
        if(fifo == NULL )
                return FIFO_ERROR_PARAM;
        if(FIFO_Status(fifo)==0)
        {
                return FIFO_ERROR_EMPTY;
        }
        *data = (INT8U)(*((INT8U *)(fifo->front)));
        if(fifo->front == fifo->endaddr)
    {
                fifo->front = fifo->staraddr;
    }
    else
    {
        fifo->front++;
    }
        return FIFO_OK;
}

F:获取缓冲区的数据量
// **************************************************************
//函数:FIFO_Status
//参数:队列指针
//返回:>0队列中有未读出数据
//描述:获取FIFO队列状态
// **************************************************************
INT32S FIFO_Status(FIFOTYPE *fifo)
{
        INT32S res;
        INT32S nextsave = (INT32S)fifo->endaddr + 1 - (INT32S)DMA1_Channel5->CNDTR;
        res = nextsave- (INT32S)(fifo->front);
        if(res < 0)
        {
                res = ( (INT32S)(fifo->endaddr)+1 - (INT32S)(fifo->front) ) + (nextsave - (INT32S)fifo->staraddr);
        }
        return res;
}
说明:
1:STM32的DMA_CMAR传输地址寄存器不会随传输数据量的变化而真正的指向下一个存储位置(AT91SAM就是总是指向下一个存储地址的)。所以我需要根据传输数量寄存器DMA_CNDTR来推算下一传输位置寄存器!
2:需要考虑环形队列写入指针已经重新回到缓冲区开头了,而读取指针还在缓冲区尾部的情况!

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-4-22 17:54:44 | 显示全部楼层
本帖最后由 chaled 于 2013-4-22 23:01 编辑

占楼,预留升级空间

编辑:
我仔细思考了一晚上,这样写好像还有一个好处就是能不存在临界段的问题了吧。(不用考虑刚好在读取FIFO数据的过程中,产生接收数据中断了!)

出0入0汤圆

 楼主| 发表于 2013-4-22 17:55:03 | 显示全部楼层
占楼,预留升级空间

出0入0汤圆

发表于 2013-4-22 18:13:04 | 显示全部楼层
楼主赶紧写,关注中

出0入0汤圆

发表于 2013-4-22 18:39:40 | 显示全部楼层
恩,DMA肯定是比原来的方法快很多,就是编程复杂一点。

出0入0汤圆

 楼主| 发表于 2013-4-22 18:56:06 | 显示全部楼层
sgzzour 发表于 2013-4-22 18:39
恩,DMA肯定是比原来的方法快很多,就是编程复杂一点。

不觉得DMA方式复杂呀.也就是几个寄存器而已.这样我觉得最大的好处是我串口通信的波特率能跑得更高!如果中断方式的话,速度高了担心丢数据.
我的AT91SAM7S256跑9M频率(为了降低功耗).串口用115200的速度就完全处理不过来了!用DMA就没任何问题了!

出0入0汤圆

 楼主| 发表于 2013-4-22 18:58:22 | 显示全部楼层
badboy.tao 发表于 2013-4-22 18:13
楼主赶紧写,关注中

已经写完了呀.我只是提供一个DMA接收不定长度数据的思路而已.

出0入17汤圆

发表于 2013-4-22 19:41:42 | 显示全部楼层
楼主的思路很好,学习了。

PS:stm32串口有一个空闲中断,省一个定时器,可以实现DMA接受不定长数据,坛子里有相关介绍。

出0入0汤圆

发表于 2013-4-22 19:45:51 | 显示全部楼层
这个要学习一下。

出0入0汤圆

发表于 2013-4-22 19:50:08 | 显示全部楼层
没看明白楼主如何解决DMA固定的传输数量与每次传输数量变化之间的矛盾。

出0入0汤圆

发表于 2013-4-22 20:03:46 | 显示全部楼层
关于fifo,所看到的代码来源都是Linux kfifo.c,整合比较好的是ST的Apple IAP代码,封装很好,与具体应用无关。楼主的几个函数把fifo跟应用混在一起了。

出0入0汤圆

 楼主| 发表于 2013-4-22 20:14:53 | 显示全部楼层
tiancaigao7 发表于 2013-4-22 19:50
没看明白楼主如何解决DMA固定的传输数量与每次传输数量变化之间的矛盾。

我没有去判断数据的长度,只要有数据我就往FIFO里面装。至于是什么数据需要自己读出FIFO来做判断处理。当然,这个时候你已经有足够的时间来处理数据了!

出0入0汤圆

 楼主| 发表于 2013-4-22 20:15:41 | 显示全部楼层
wicy001 发表于 2013-4-22 19:41
楼主的思路很好,学习了。

PS:stm32串口有一个空闲中断,省一个定时器,可以实现DMA接受不定长数据,坛子 ...

真的么?看来我没有把STM32的串口研究透彻呀。只知道ATMEL的有一个串口超时中断很好用。
谢谢提示,我仔细看看这个空闲中断去!

出0入0汤圆

 楼主| 发表于 2013-4-22 20:17:28 | 显示全部楼层
kaimpf 发表于 2013-4-22 20:03
关于fifo,所看到的代码来源都是Linux kfifo.c,整合比较好的是ST的Apple IAP代码,封装很好,与具体应用无 ...

我在前面也说了,我这个是改装过的"环形队列"。所谓的修改就是跟DMA结合起来了。
另外,本人菜鸟一个。没接触过Linux。回头学习学习你所说到的Linux下的FIFO实现!

出0入0汤圆

发表于 2013-4-22 21:15:24 来自手机 | 显示全部楼层
看看O(∩_∩)O~

出0入0汤圆

发表于 2013-4-22 21:58:18 | 显示全部楼层
占楼,预留升级空间

出0入0汤圆

发表于 2013-4-22 22:06:09 | 显示全部楼层
思路很新颖, 学习了

出0入0汤圆

发表于 2013-4-23 22:21:37 | 显示全部楼层
这么好的,收藏了!

出0入24汤圆

发表于 2013-4-23 23:08:34 | 显示全部楼层
显然LZ不知道STM32的总线空闲中断
一帧数据中断一次,节省CPU资源,而且在串口接收数据上不会产生延迟。

出0入0汤圆

发表于 2013-4-23 23:53:52 | 显示全部楼层
这么好的质量贴,赶快占座位

出0入0汤圆

发表于 2013-8-1 14:07:15 | 显示全部楼层
20061002838 发表于 2013-4-23 23:08
显然LZ不知道STM32的总线空闲中断
一帧数据中断一次,节省CPU资源,而且在串口接收数据上不会产生延迟。 ...

此言差矣,我之前发布了使用超时中断进行DMA接收的文档,但是楼主这个应用不同,这个更灵活,较之前者复杂但是较之前者功能强大,试想 你要使用串口往SD卡或者flash里面写10K数据,使用前者,你的缓冲要开多大?我今天本来也想写一个关于环形FIFO使用DMA接收的例子,不过楼主先我一步啊!呵呵。人才,绝对的人才。
不过楼主的写作风格有待提高,多数人首次接触环形fifo还是很难看懂的!呵呵
支持一下!

出0入0汤圆

发表于 2013-8-1 14:32:37 | 显示全部楼层
收藏.感谢楼主无私奉献!

出0入0汤圆

发表于 2013-8-1 18:42:24 | 显示全部楼层
1个字符长度的空闲标志中断太快了。能够编程空闲检测字符长度就好了。Modbus-RTU需要3.5个字符长度才判断一帧数据结束。

出0入0汤圆

发表于 2013-8-2 10:09:57 | 显示全部楼层
本菜鸟没怎么看明白

出0入0汤圆

发表于 2013-8-2 10:16:09 | 显示全部楼层
ehello 发表于 2013-8-1 14:07
此言差矣,我之前发布了使用超时中断进行DMA接收的文档,但是楼主这个应用不同,这个更灵活,较之前者复 ...

请详细讲解一下

出0入0汤圆

发表于 2013-9-3 16:59:49 | 显示全部楼层
这个感觉很给力啊,不知道楼主有没有一个比较简单的DEMO例程分享一下呢?我是新手,自己写感觉不太写得好,多谢啦

出0入0汤圆

发表于 2013-9-8 15:31:51 | 显示全部楼层
STM32串口DMA超时接收方法,可大大节约CPU时间
http://www.amobbs.com/thread-5539706-1-1.html

出0入0汤圆

发表于 2013-9-8 15:33:11 | 显示全部楼层
本帖最后由 32MCU 于 2013-9-8 15:34 编辑

ehello 您写的是这个吗?

出0入0汤圆

发表于 2013-9-8 18:45:53 | 显示全部楼层
收藏了~~谢谢

出0入0汤圆

发表于 2013-9-9 08:38:27 | 显示全部楼层
kaimpf 发表于 2013-4-22 20:03
关于fifo,所看到的代码来源都是Linux kfifo.c,整合比较好的是ST的Apple IAP代码,封装很好,与具体应用无 ...

整合比较好的是ST的Apple IAP代码,我想问下,你指的是什么。具体点,是IAP升级方案,还是什么?那里面也有FIFO处理吗?

出0入0汤圆

发表于 2013-9-9 08:41:29 | 显示全部楼层
楼主奉献下你的工程吧,让小弟我可以学习请教下,谢谢

出0入0汤圆

发表于 2013-9-9 09:01:02 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2013-9-9 23:04:18 | 显示全部楼层
MARK,学习了..

出0入8汤圆

发表于 2013-9-10 01:26:13 来自手机 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2013-9-10 08:42:38 | 显示全部楼层
stm32 的 uart 没有硬件FIFO真是一个缺陷。

出0入0汤圆

发表于 2013-9-10 09:16:43 | 显示全部楼层
学习了,收藏。

出0入0汤圆

发表于 2013-9-10 09:23:26 | 显示全部楼层
     学习了

出0入0汤圆

发表于 2013-9-10 09:43:08 | 显示全部楼层
学习了,以后会用到,参考下

出0入0汤圆

发表于 2013-9-10 09:45:22 | 显示全部楼层
用DMA+串口超时中断更方便。

出0入0汤圆

发表于 2013-9-10 10:18:26 | 显示全部楼层
楼主思路很好,学习了。

出0入0汤圆

 楼主| 发表于 2013-9-10 15:50:09 | 显示全部楼层
athena_min 发表于 2013-9-10 09:45
用DMA+串口超时中断更方便。

关键是STM32芯片没有自己的串口超时中断。需要配合定时器使用。但是我觉得配合定时器太麻烦了。需要在收到第一个字节后,开启定时器等等。

ATMEL的ARM就是现成的串口超时配置,很灵活很舒服。可以直接配置为至少收到一个字节后才启用超时。


当然这种方式也有一个不太好的地方,需要一个线程定时的去读缓冲区。同时还要考虑最大数据量的时候线程是否能处理得过来。
同时优点也很明显,不需要任何的中断参与。对于stm32这种内存比较大的片子我觉得还是挺实用的!

出0入0汤圆

发表于 2013-9-10 15:53:41 | 显示全部楼层
XUEXI!MARK

出0入0汤圆

发表于 2013-9-10 15:57:51 | 显示全部楼层
这个机制n年前就在产品上用了……

stm32没fifo就是为了节省成本,因为已经有dma配合缓冲区跟空闲中断,比fifo好多了……

出0入0汤圆

 楼主| 发表于 2013-9-10 16:11:14 | 显示全部楼层
windrarara 发表于 2013-9-10 15:57
这个机制n年前就在产品上用了……

stm32没fifo就是为了节省成本,因为已经有dma配合缓冲区跟空闲中断,比f ...

用了怎么不见共享一下思路呢。我之前只知道有人共享了用定时去做超市中断的思路。

出0入0汤圆

发表于 2013-9-10 16:33:26 | 显示全部楼层
占楼学习。。。。最近正好要用的串口接收数据。

出0入0汤圆

发表于 2013-9-10 16:38:40 | 显示全部楼层
ST有基于DMA的环形缓冲区设计的应用指南

出0入0汤圆

发表于 2013-9-10 17:17:04 | 显示全部楼层
chaled 发表于 2013-9-10 16:11
用了怎么不见共享一下思路呢。我之前只知道有人共享了用定时去做超市中断的思路。 ...

我以为大家都知道这么用啊,你肯定没看st的application note,看了stm32这些外设的功能,基本上就能了解它的一些设计思想,有dma了就不用fifo了,fifo是很贵的,所以stm32才搞得这么便宜……

出0入0汤圆

发表于 2013-9-10 18:50:16 | 显示全部楼层
强烈要求上工程

出0入0汤圆

发表于 2013-10-5 10:28:19 | 显示全部楼层
思路很好    学习了!

出0入0汤圆

发表于 2013-10-6 17:19:41 | 显示全部楼层
MARK  STM32 串口  加DMA

出0入0汤圆

发表于 2013-10-21 17:09:06 | 显示全部楼层
这个有必要试下 可以解决不少问题

出0入0汤圆

发表于 2013-10-21 20:24:52 | 显示全部楼层
mark 下!

出0入0汤圆

发表于 2013-11-20 11:47:16 | 显示全部楼层
这种思路不错,如果加上串口空闲中断去检测数据长度就完美了

出0入0汤圆

发表于 2013-11-20 12:09:22 来自手机 | 显示全部楼层
支持楼上

出0入0汤圆

发表于 2013-11-20 12:22:42 来自手机 | 显示全部楼层
楼主思路很好,学习了

出0入0汤圆

发表于 2013-11-20 13:19:25 | 显示全部楼层
INT8U buffer[1];                //实际长度由初始化分配内存!(memloc的时候确定)

这样做会不会出现在某些情况下,buffer[1]地址后面 作为缓冲的数据被不小心被覆盖?

出0入0汤圆

 楼主| 发表于 2013-11-22 10:14:57 | 显示全部楼层
hxke 发表于 2013-11-20 13:19
INT8U buffer[1];                //实际长度由初始化分配内存!(memloc的时候确定)

这样做会不会出现在某 ...

理论上不会。如果真出现了,那肯定是你程序里面的野指针造成的!

出0入0汤圆

发表于 2013-12-5 09:08:37 | 显示全部楼层
关在在于让DMA来实现“环形队列中往缓冲区写入1byte”的功能


请问如何能做到让DMA只传1byte数据?只要有数据发送过来就立刻会被传送给缓冲区,这个过程是不可控的

出0入0汤圆

发表于 2013-12-8 00:11:02 | 显示全部楼层
感觉挺难的,我看了几遍才有点头绪

出0入0汤圆

发表于 2013-12-8 00:13:21 | 显示全部楼层
有一点没有明白,关于环形fifo的读取,我想用尽量少的次数去读取,但是我不知道你这个思路怎么去实现

出0入0汤圆

发表于 2013-12-8 20:51:00 | 显示全部楼层
不错,楼主的方法对我有很大的帮助。谢谢共享。

出0入0汤圆

发表于 2013-12-9 16:55:14 | 显示全部楼层
好帖收藏                                   

出0入0汤圆

发表于 2013-12-11 20:18:46 | 显示全部楼层
学习了...............

出0入0汤圆

发表于 2013-12-17 22:24:10 来自手机 | 显示全部楼层
前来。学习

出0入0汤圆

发表于 2013-12-17 22:57:03 | 显示全部楼层
关注   
好帖啊

出0入0汤圆

发表于 2013-12-19 20:15:54 | 显示全部楼层
工程在哪里啊   格就是就是

出0入0汤圆

发表于 2014-1-5 11:17:25 | 显示全部楼层
mark   整在为串口犯愁呢

出0入0汤圆

发表于 2014-1-5 11:51:37 | 显示全部楼层
kaimpf 发表于 2013-4-22 20:03
关于fifo,所看到的代码来源都是Linux kfifo.c,整合比较好的是ST的Apple IAP代码,封装很好,与具体应用无 ...

可以将ST的APPLE IAP代码工程上传一下吗?我在ST官网找不到相关代码

出0入0汤圆

发表于 2014-2-14 20:30:13 | 显示全部楼层
mark            

出0入8汤圆

发表于 2014-2-14 21:35:27 来自手机 | 显示全部楼层
完全看不懂

出0入0汤圆

发表于 2014-3-10 10:29:57 | 显示全部楼层
兄弟,能否把工程发上来学习下,谢谢!

出0入0汤圆

发表于 2014-3-13 16:45:44 | 显示全部楼层
styleno1 发表于 2013-9-10 16:38
ST有基于DMA的环形缓冲区设计的应用指南

求文档链接.....

出0入0汤圆

发表于 2014-3-13 20:47:07 | 显示全部楼层
mark, UART DMA

出0入0汤圆

发表于 2014-4-15 11:39:15 | 显示全部楼层
32MCU 发表于 2013-9-8 15:33
ehello 您写的是这个吗?

不是这个,你再搜搜!

出0入0汤圆

发表于 2014-4-18 07:24:10 | 显示全部楼层
好东西啊,谢谢了

出0入0汤圆

发表于 2014-5-6 22:25:26 | 显示全部楼层
看来得学习寄存器版本了~还是F4的。。。。

出0入0汤圆

发表于 2014-5-8 12:58:44 | 显示全部楼层
好东西,学习了

出0入0汤圆

发表于 2014-5-15 10:46:49 | 显示全部楼层
本来就有应用笔记讲这个东西。。。

出0入0汤圆

发表于 2014-7-28 18:51:28 | 显示全部楼层
楼主问一下,有没有什么FIFO入门的电子文档或者例程,我现在想做个数据转发,但感觉必须得用缓冲,可是不知到底该怎么写

出0入0汤圆

发表于 2014-7-28 19:59:59 | 显示全部楼层

精典中的经典!学习了。

出0入42汤圆

发表于 2014-7-30 19:06:04 | 显示全部楼层
楼上好多人说熟,用过。怎么不见分享?楼主英明!

出0入0汤圆

发表于 2014-10-6 21:31:32 | 显示全部楼层
有没有DMA+FIFO写一个字节的思路,我现在用的是USART中断+FIFO。

出0入0汤圆

发表于 2014-10-6 21:31:56 | 显示全部楼层
有没有DMA+FIFO写一个字节的思路,我现在用的是USART中断+FIFO。

出0入0汤圆

发表于 2014-10-7 00:12:35 | 显示全部楼层
mark,STM32串口DMA方式接收数据

出0入0汤圆

发表于 2014-10-7 01:20:09 | 显示全部楼层
mark     STM32串口DMA方式接收数据

出0入0汤圆

发表于 2014-10-17 22:45:01 | 显示全部楼层
windrarara 发表于 2013-9-10 17:17
我以为大家都知道这么用啊,你肯定没看st的application note,看了stm32这些外设的功能,基本上就能了解 ...

楼主的办法不错。但是你提到的Application Notes 也想看看。
可否共享下这篇ST的Application Note;贴个链接即可。去搜索搜不到。

出0入10汤圆

发表于 2014-10-24 22:45:01 | 显示全部楼层
略懂,只不过Int32S FIFO_Init(FIFOTYPE * *fifo,INT32U fifosize)这里应该改为Int32S FIFO_Init(FIFOTYPE *fifo,INT32U fifosize)

出0入0汤圆

发表于 2014-10-25 12:01:27 | 显示全部楼层
不错的资料,学习了

出0入8汤圆

发表于 2014-11-1 10:56:04 | 显示全部楼层
先记下来,以后再细看~

出0入0汤圆

发表于 2014-11-11 18:06:25 | 显示全部楼层
最近接触DMA有些东西不很明白,慢慢研读一下。。。。
                                                                                    
                                                                        
                                       

出0入0汤圆

发表于 2014-11-11 18:49:06 | 显示全部楼层
谢谢分享!!!!!!

出0入0汤圆

发表于 2014-11-11 20:18:07 | 显示全部楼层
Mark一下,有空研究!

出0入0汤圆

发表于 2014-11-11 21:03:41 | 显示全部楼层
好资料,要收藏!

出0入0汤圆

发表于 2014-11-11 21:41:00 | 显示全部楼层
有机会用一下,赞

出0入0汤圆

发表于 2014-11-28 10:00:32 | 显示全部楼层
我觉得lz的做法就是将dma改造成硬件fifo的做法,也有半满、全满等等操作,其实dma的灵活性是非常高的,改造成硬件fifo分分钟的事情

出0入0汤圆

发表于 2015-1-12 17:13:54 | 显示全部楼层
mark...STM32  DMA+FIFO

出0入0汤圆

发表于 2015-2-12 23:50:34 | 显示全部楼层
wicy001 发表于 2013-4-22 19:41
楼主的思路很好,学习了。

PS:stm32串口有一个空闲中断,省一个定时器,可以实现DMA接受不定长数据,坛子 ...

哪里有啊?可以帮忙找下?找不到。

出0入0汤圆

发表于 2015-2-13 10:46:29 | 显示全部楼层
windrarara 发表于 2013-9-10 17:17
我以为大家都知道这么用啊,你肯定没看st的application note,看了stm32这些外设的功能,基本上就能了解 ...

可以上传下文档嘛?想学习下

出0入0汤圆

发表于 2015-2-13 10:47:51 | 显示全部楼层
wyq200704 发表于 2014-5-15 10:46
本来就有应用笔记讲这个东西。。。

应用笔记在哪里有啊,我想看看,谢啦

出0入0汤圆

发表于 2015-2-13 10:51:20 | 显示全部楼层
谢谢楼主啦,我来总结下。DMA插入数据本来就跟平常用软件搞FIFO插入是一样地,后面根据DMA的一个CNDTR来查看数据插入到什么地方,进一步判断FIFO中有没有数据,读取的其他是跟软件FIFO是一样地
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-3-29 19:07

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

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