大家好,最近刚开始学习C2000,在尝试driverlib关于SCI例子的时候,遇到了一些问题,下面是SCI例子的连接:
这个例子的功能是:1. 发送字符串到PC,请求用户键入一个0-9的数字,
2. SCI读取用户键入的数字,根据这个数字调整LED的闪烁频率,同时,再把接收到的数字发送回PC,通过Terminal显示,并再次请求键入新的数字。
例子提供的源码,键入数字设定LED闪烁频率这部分功能没有问题。但是,SCI发送字符串存在下面的问题:
期望的显示的结果为:
(这里使用的是修改过,可以正常运行的代码,其中x为用户键入的数字)
即:" LED set to blink rate x" + " \r\nEnter a number 0-9>"
但实际的显示结果为
(这里使用的是例子提供的代码)
即:" LED set" + " r a number 0-9:"
两个应该显示的字符串分别只显示了一部分。
主函数如下(我把源代码里面用来设定闪烁频率的时钟和LED Toggle删除了,因为这里我想只考虑SCI的功能):
SCI A设置为8位数据,1位停止,无奇偶校验,启用FIFO。
发送字符串使用的是 SCI_writeCharArray(SCIA_BASE,(uint16_t*)msg,len) 函数(/driverlib/sci.c)。
上面函数中,利用while判断 TX FIFO中是否仍有可用的空间,问题在于判别式
ti提供的代码中判别式使用的是SCI_FIFO_TX15,但我自己实验的时候,除了将判断设置为 SCI_FIFO_TX16,能够顺利实现正确的echo功能之外,
SCI_FIFO_TX0 - SCI_FIFO_TX15 都会出现上面的问题,区别在于不同的设置,漏掉的字符不同:
" LED set to blink rate" + "r a number 0-9:" @ SCI_FIFO_TX1
" LED set to blink rat" + "r a number 0-9:" @ SCI_FIFO_TX2
" LED set to blink ra" + "r a number 0-9:" @ SCI_FIFO_TX3
" LED set to blink r" + "r a number 0-9:" @ SCI_FIFO_TX4
...
" LED set"+ "r a number 0-9:" @ SCI_FIFO_TX15
第一个问题是:
我不明白的是,这里FIFO到底起的什么作用,因为,例子中并没有使用 SCI中断,也没有设置发送FIFO中断层级 TXFFIL(默认为00000b),16x8 bit 的TX FIFO单纯作为缓冲来说,为什么会因为不同的判断条件,对发送结果产生不同的影响?为什么只有当判断条件中使用 SCI_FIFO_TX16时才能正常运行,而其他的不行?
第二个问题是:
有没有大神能够详细的讲解一下这个增强 FIFO的发送过程。
发送FIFO的机制到底是什么,可不可以理解为CPU将TX FIFO装满之后,才会开始从TX FIFO中向TXSHF转移并从引脚依次发送?
如果需要发送的数据数N小于16个words,CPU将TX FIFO装满N个words,之后从TX FIFO每移出一位,TXFFST就减1,当TXFFST=TXFFIL就会置位TXFFINT?
(这是不是也是,TXFFIL默认值为00000b,TXFFST小于等于TXFFIL时,TXFFINT才会置位的原因? 意味着TX FIFO中还剩TXFFIL个words(默认为0),同时,也说明已经发出了 (N - TXFFIL)个words(默认为N)?)
如果需要发送的数据大于等于16个words,CPU将TX FIFO装满16个words,之后从TX FIFO每移出一位,TXFFST就减1,之后CPU再向TX FIFO装填1个word,TXFFST又加1,一直保持TXFFST=16,直到没有新的数据需要发送为止,之后TXFFST开始减少,最终为0?
如果我上面说的没错,那是怎样判定TX FIFO装填结束,可以开始从TX FIFO向TXSHF移动的呢? 是TX FIFO_0 被装填吗? 上电初始化后TX FIFO中的每一层都为空吗?
还望大家能不吝赐教,提前谢过。
///////////////////////////////////////////////////更新/////////////////////////////////////
今天又试了一下, 发现真正的问题 并不是 SCI_writeCharArray 函数 判别式的问题, 而是 因为SCI_writeCharArray() 库函数与 SCI_writeCharBlockingFIFO() 库函数 被交叉着连续调用.
原因在于: SCI_writeCharArray()中, 判别式使用的是 SCI_FIFO_TX15, 而 SCI_writeCharBlockingFIFO() 使用的是 SCI_FIFO_TX16.
如果这两个函数while判断使用的是相同的值,那就不会出现任何问题。
具体为什么两个函数使用不一样的比较值会造成发送结果的不一样,我还没有答案。
下面是我得到的一些思路。
单独连续调用SCI_writeCharArray() 或 SCI_writeCharBlockingFIFO()不论使用的是SCI_FIFO_TX1-15中的哪一个, 作为比较条件,都不会出现问题.

上面已经将SCI_writeCharArray()中使用的值改为SCI_FIFO_TX1,仍可以正常发送。

SCI_writeCharBlockingFIFO() 里使用的也修改为SCI_FIFO_TX1,也可以正常发送。
但是,如果进行下面形式的交叉连续调用,则会出现问题:

例如,使用SCI_writeCharArray()发送63个字符,设SCI_FIFO_TX15, 则只会发送前48个字符。使用SCI_writeCharBlockingFIFO() ,设SCI_FIFO_TX16,发送的单个字符会丢失,并且再次使用SCI_writeCharArray()发送63个字符,只会发出最后的16个字符,之前的全部会丢失,这里发出的字符数量与while判断值无关,总是16个 (刚好也是TX FIFO 的深度)。
但是,如果SCI_writeCharArray(), SCI_writeCharBlockingFIFO() 使用相同的while判断条件,交叉连续调用不会出现问题:

上面的代码,我把库函数复制到main.c里了(所以拷贝的库函数后面都有个“1”),上面两个函数共用一个global变量SCI_FIFO作为while比较值,PC接收到的与发送的一致。
我会继续研究的,如果有答案了会再更新的,如果有人能解释一些,就再好不过了。