新闻中心

首页 > 嵌入式系统 > 牛人业话 > 从一张示波器截图谈FIFO

从一张示波器截图谈FIFO

作者:Jobs时间:2021-04-22来源:EEPW太阳城BG视讯

概要:SPI外设具有协议通用性强,高速串行通讯,操作简便等优点。本文讲述了在使用SPI外设驱动LCD屏时,由于功能遇到的“异步”发送数据,导致LCD屏驱动异常,从而屏幕显示失败的问题。借助示波器观察引脚信号,分析信号时序等方法的解决过程,并最终实现SPI外设驱动LCD屏。

本文引用地址:http://tycbgsx.997sj.com/article/202104/424757.htm

本人的一个项目,项目使用公司的LPC11U68微处理器作为主控芯片,其设计功能之一是驱动TFT LCD屏。TFT LCD屏为SPI接口,于是使用LPC11U68芯片的SSP0外设接口来驱动。

很简单的三两行字,却让我在调试的时候一度深陷困境。先上一张示波器截图,我们慢慢道来。

图片.png

这张示波器截图对应的是下面这段代码实现:

void ssp0_send_byte(uint8_t data)

{

uint16_t tmp = data;

LCD_DESELECT();

LCD_CMD();

while((Chip_SSP_GetStatus(LPC_SSP0, SSP_STAT_TNF) == RESET));

Chip_SSP_SendFrame(LPC_SSP0, tmp);

while((Chip_SSP_GetStatus(LPC_SSP0, SSP_STAT_TFE) != SET));

LCD_SELECT();

}

LCD驱动对于寄存器或数据的写入流程还是比较清晰、简单。如上述源代码所示:

step1:将片选CS信号拉低

step2:配置本条发送数据是命令or数据

step3:发送8位串行数据

step4:将片选CS信号拉高

图片.png

上图为TFT LCD驱动datasheet中的引脚时序参考图。代码的编写也是完全符号时序的要求。可是就是这么简单的6行代码出现了问题!

我将代码编译后烧录入LPC11U68芯片后开始运行,发现LCD屏驱动异常,屏幕没有任何显示。

考虑到代码是从示例程序移植过来,也不排除出现问题——也许原例程亦无法实现呢!我将代码更换为GPIO模拟SPI方式实现驱动LCD屏——这次显示成功了,只是页面刷新要慢好多了。再次换回SPI外设方式,故障依旧——这也充分说明了硬件是完好的,而问题就出在了软件设计上面了。

刚刚开始以为配置LPC11U68芯片的SSP0外设出现了问题,经过反复验证后,也未能定位原因所在。在软件分析无果后,请出来了示波器,便有了文章开头的那一张截图。

截图中,蓝线CH1为SPI外设的SCK引脚,黄线CH2为LCD的片选CS信号。从示波器上面可以清晰看到片选CS信号并没有在发送一帧数据后才拉高,而是提前拉高了。当片选CS引脚为高时,LCD屏忽略SDA上面传输的数据,自然LCD屏不会有正确的显示。

通过示波器的 介入,我们观察到了控制信号与数据信号的传输过程,并发现了LCD屏未能正确的显示的症结所在。下面我们就分析一下其中的原因。

示例的例程是基于STM32系列单片机,阅读两者的datasheet,对比所使用的微处理器LPC11U68的SPI外设,可以看到STM32系列单片机没有发送。那发送为何物呢?

“FIFO是先进先出的意思,队列的方式。”

“FIFO是一个硬件环形的缓冲队列,物理上不可寻址,不可见,仅SSPDR这个FIFO出口可见。”

“SSP接口向SPI总线发送数据时,数据先存到SSPDR当中,由Tx FIFO的状态及总线是否空闲决定已经存入到SSPDR当中的数据何时进行发送。”

因为Tx FIFO的深度是有限的,每次发送过程中都是将现有FIFO中所有数据一起发送,所以SSPDR可以理解为发送过程当中的数据缓冲寄存器。”

以上我从网络上面摘录下来的。通过FIFO的介绍可以得出,当程序执行到Chip_SSP_SendFrame()时,仅将数据“塞入”FIFO,并在成功“塞入”后即返回。而此时数据并未成功发送,但片选CS信号 却在Chip_SSP_SendFrame()返回后,误认为其成功执行而对片选CS信号进行了释放拉高操作,待SPI外设真正发送数据时,此时片选CS信号已经释放,LCD驱动芯片也就不会再接收其数据了。没有了正确的输入数据,屏幕也就“漆黑一片”了。

分析问题已经完成,那么下面我们就着手解决问题。

通过阅读官方技术手册,可以查询到BUSY标志位代表SPI外设正在发送操作,所以我们仅需要在此标志位清零后再执行片选CS释放即可。源代码如下:

void ssp0_send_byte(uint8_t data)

{

uint16_t tmp = data;

LCD_DESELECT();

LCD_CMD();

while((Chip_SSP_GetStatus(LPC_SSP0, SSP_STAT_TNF) == RESET));

Chip_SSP_SendFrame(LPC_SSP0, tmp);

while((Chip_SSP_GetStatus(LPC_SSP0, SSP_STAT_TFE) != SET));

while((Chip_SSP_GetStatus(LPC_SSP0, SSP_STAT_BSY) == SET));

LCD_SELECT();

}

公司旗下LPC系列微处理器对外设增加FIFO可以减少数据中断的调用,提高整体通讯效率,而这也恰恰营造了一种“异步”指令处理的环境。这时,也就出现了我们的微处理器在代码执行顺序上面出现了没有按“顺序”执行的问题。

在增加了等待指令后,软件的操作顺序与期望顺序一致,TFT LCD驱动显示正常。我们在软件设计时,合理使用硬件外设提供的FIFO功能,充分利用其优势,规避其使用过程中的副作用。虽然本次FIFO带来了一些困扰,但从整体的系统角度来讲,仍然提升了我们的系统效率。




关键词: NXP FIFO

评论


相关推荐

技术专区

关闭
网站地图 蒙特卡罗娱乐旗舰厅 百合娱乐欧博视讯 大家旺娱乐场快3
菲律宾沙龙国际 太阳城菲律宾官网申博 申博138娱官网开户
好彩票黑龙江时时彩 玩彩票游戏 亚洲必赢766.net 天天音乐沙龙直营网
太阳城江苏骰宝 云顶MG视讯 申博网址直营网 云顶HB电子
万达娱乐mg老虎机 云顶DG视讯 太阳城旗舰厅 大三巴娱乐BBIN视讯
868XTD.COM XSB345.COM 1115118.COM 638PT.COM 967SUN.COM
8QZS.COM 555xsb.com 1112936.COM 588TGP.COM 997sj.com
768XTD.COM 272SUN.COM bq138.com 1777DZ.COM 81ib.com
729tt.com 616jbs.com 8DQS.COM 8888XSB.COM 8QHDS.COM