18/10/26 随笔

1. 名词解释    

FIFO        先入先出队列

 

2. DMA传输

    DMA:Direct Memory Access,直接内存存取,是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。

    STM32接收串口数据都是采用接收中断,然后写入一个FIFO队列。然后在主函数里面去查询队列缓冲中是否有数据需要处理。但是这样的话,串口中断服务函数始终是很大的硬件开销。

    把DMA和环形的FIFO队列结合一下使用,关键在于让DMA来实现环形队列中往缓冲区写入byte的功能,剩下的读取队列操作与普通环形队列没多大区别。这样,程序中拥有了一个不占用CPU资源的“环形队列”后,就不用频繁中断CPU,只需要在适当的时间读取队列中的数据然后慢慢分析处理数据即可。

    操作可分为一下六个步骤:

(1)串口初始化配置串口为DMA方式接收数据。

(2)关于FIFO的一些声明:

(3)关于FIFO队列的初始化

(4)清空队列缓冲区函数

(5)读取FIFO缓冲区

(6)获取缓冲区的数据量

说明:

    (1):STM32的DMA_CMAR传输地址寄存器不会随传输数据量的变化而真正的指向下一个存储位置,所以需要根据传输数量寄存器DMA_CNDTR来推算下一传输位置寄存器。
    (2):需要注意环形队列写入指针已经重新回到缓冲区开头,而读取指针还在缓冲区尾部的情况。

 

3. 环形FIFO

    (1) FIFO存储器:FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器。

    优点:它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单。

    缺点:只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

    在系统设计中,以增加数据传输率、处理大量数据流、匹配具有不同传输率的系统为目的而广泛使用FIFO存储器,从而提高了系统性能。FIFO存储器是一个先入先出的双口缓冲器,即第一个进入其内的数据第一个被移出,其中一个存储器的输入口,另一个口是存储器的输出口。

 

    (2)环形队列

    有的单片机串口没有FIFO,或者可分配的FIFO大小是非常有限的,如果在程序中需要向外设发送一个很大的数据包,需要很长的时间,为了解决应用程序与外设硬件读写同步的问题,很有必要实现环形FIFO。

    什么是环形队列:环形队列是在实际编程极为有用的数据结构,它是一个首尾相连的FIFO的数据结构,采用数组的线性空间,数据组织简单,能很快知道队列是否满为空,并能以很快速度的来存取数。环形队列简单高效,广泛用于网络数据收发和不同程序间数据交换(比如内核与应用程序大量交换数据,从硬件接收大量数据均使用了环形队列),甚至有些硬件都实现了环形队列。    

    环形队列实现原理:

    内存上没有环形的结构,因此环形队列实上是数组的线性空间来实现。那当数据到了尾部,将重新转回到0位置来处理,这个的转回是通过取模操作(例如C语言用取模运算符“%”进行取模运算。取模运算符“%”的作用是求两个数相除的余数)来执行的。

   因此环列队列的是逻辑上将数组元素q[0]与q[MAXN-1]连接,形成一个存放队列的环形空间。

 cba5f2aad7a33b215b899e394db13dd1b4a.jpg

    为了方便读写,还要用数组下标来指明队列的读写位置。其中head指向可以读的位置,tail指向可以写的位置。

    环形队列的关键是判断队列为空,还是为满。当tail追上head时,队列为满时,当head追上tail时,队列为空。但如何知道谁追上谁。还需要一些辅助的手段来判断。

如何判断环形队列为空,为满有两种判断方法。

一. 是附加一个标志位tag

      当head赶上tail,队列空,则令tag=0,
      当tail赶上head,队列满,则令tag=1,

二. 限制tail赶上head,即队尾结点与队首结点之间至少留有一个元素的空间。

      队列空:   head==tail
      队列满:   (tail+1)% MAXN ==head

 

4. sprintf()用法

#include <stdio.h>
#include <math.h>

int main()
{
   char str[80];

   sprintf(str, "Pi 的值 = %f", M_PI);
   puts(str);
   
   return(0);
}

编译运行结果:

Pi 的值 = 3.141593

 

5. %05d和%5d的区别

%nd 输出的整型宽度至少为n位,右对齐,%5d即宽度至少为5位,位数大于5则输出实际位数
%0nd 用得比较多,表示输出的整型宽度至少为n位,不足n位用0填充
printf("%05d",1)输出:00001
printf("%5d",1)输出:****1(*为空格)

 

6. f_open()

创建/打开一个用于访问文件的文件对象

用法:f_read(&file,(const TCHAR *)File_path,FA_READ)

如果f_open返回FR_NO_FILE,意味着读到的数据为0。

转载于:https://my.oschina.net/u/4005274/blog/2253194

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值