| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> AT32(五):硬件SPI——驱动LCD屏的一些尝试 -> 正文阅读 |
|
[嵌入式]AT32(五):硬件SPI——驱动LCD屏的一些尝试 |
总感觉之前的AT32F421板子/片子 有点小毛病,出各种莫名其妙的BUG(实在找不出软件的问题,只能怀疑是硬件 QAQ)。 于是之后咕了很久,最近终于想继续折腾,拿AT32F435画了一块LCD驱动板,准备入坑LVGL。板上资源就一块某园的2.8存240x320带电阻膜的LCD屏、触摸IC用XPT2046,另外还画了一片W25Q64和CH340在上面,有空试试QSPI和ISP功能。 新板子,调试驱动LCD的SPI中...? ?画板子的时候就在思考这个问题: XPT2046 和 LCD(ST7789) 到底要不要共用1个SPI接口? 之前画过一个小的实验板: 参照LCD厂家提供的手册上的画法,LCD和XPT2046共用一个SPI。其中有一个我不理解的地方,那就是LCD明明不会发送数据(难道不是这样?),但是却有一个数据引脚SDD,在没有触摸IC的应用中,该引脚悬空;在有XPT2046的应用中,厂家的手册上推荐把该引脚同XPT2046的MISO(同时也是单片机的SPI输入引脚)相连。 这真的是必要的吗?为什么需要用4根线来驱动一个LCD,即使它不可能知道外部有没有触摸IC的存在? 于是新板子上我尝试了以下方法:
基于几个基本逻辑:节约CPU资源:只要不是共用SPI,就用硬件CS;节约引脚:只要没有用到数据输入,就不使用双线双工。因此这里面合理的选项只有1和4。另外,只要和触摸IC共用SPI,就不得不用到MISO,且“一主多从”只支持软件CS。 1在之前的小板上就已经实现过了,但是觉得在IO资源足够的情况下,还是应当以节约CPU资源为主,所以舍弃了软件CS,想试试方法4:在LCD不与XPT2046共用SPI的时候,仅使用 SCLK, MOSI, CS(硬件控制) 3根线来驱动LCD。 然后理所当然的踩了一堆坑。。。调的头都要秃了,在此记录一下。 关于AT32F435开启单线半双工模式刚开始我以为只要在?spi_init_struct 中配置下面这一项:
然后 在spi_init() 函数里传进去就够了,结果代码都运行了,没有任何现象,检查走信号的GPIO,初始化后只能看到有一点点毛刺。这种情况通常可能是
然而负责这三行代码都执行过了,怎么出的问题? 检查寄存器的时候才发现,每当我初始化SPI设置后、执行 spi_enable() 去使能SPI时,STS寄存器蹦出一个MMERR(主模式错误),同时把我的模式改成了从模式,还关掉了我的SPI使能。 查了AT的RM,上面也没说什么情况下会触发MMERR,仔细检查RM提供的信息,总结了下面几点:
?事实上对于第一项,如果设置了SPI_TRANSMIT_HALF_DUPLEX_TX,则在spi_init()中这两个bit会被配置完成。第二项只有在使用软件CS时才有用。所以最后证明是 hwcsoe 背大锅。。。 RM表示 ctrl2_bit.hwcsoe?是一个 rw 位,它的名字虽然叫硬件CS使能,但描述的功能不像是使能,却像是在用软件控制CS啊?! 所以我只好在spi_enable()前加上把这一位置1的命令。结果就没有MMERR了。 遂舍弃方法4,为了继续追求硬件CS,只能尝试方法2 浅浅吐槽一下,写库函数spi_init()的时候为什么不能多一个判断,如果是硬件CS自动加上这个置位啊。真的好坑,手册里也不说MMERR怎么来的,spi_init()明明已经有一堆判断逻辑了,为什么不加几行避免在设置的时候就出ERR呢... 关于硬件管理CS在单线半双工下通过 ctrl2_bit.hwcsoe=1 开启硬件CS输出使能,导致的结果就是 spi使能后 全过程 CS一直为低电平。 查看RM:
?RM表示:一直开着CS有啥不好?反正你都只有这一个从设备了。你要是想发完一个frame就关CS,那你直接把SPI关了不就o了? 属于又颠覆我对SPI的认知了。这个?ctrl2_bit.hwcsoe()主要是为 MCU做从设备,拿来检测是否被片选用的;如果是做主机,那它就会一直把CS拉低。 然而有的SPI从设备会在CS的上下沿完成锁存等操作,甚至在时序要求里对CS的拉低、释放时间有具体的要求,比如下图 举个栗子,AD9833的SPI时序要求 如上图,AD9833对CS的时序有一个最小setup time (t7)和最小hold time (t8),甚至t8还有一个最大值要求:不能超过t4-5ns。总之需要只在每一个数据帧传输的时候拉低CS,而之后要能迅速释放。 不死心的我仍决定尝试在每发送完一个帧后关掉SPI,实现SPI通信的代码变成这个样子: 结果令人失望,没能成功点屏。其中很令人在意的一点就是尽管硬件CS拉低很迅速,但释放(通过失能SPI实现)的速度非常慢,过程持续了百微妙级别:关掉SPI后CS信号的样子是典型RC充电曲线的形状。这就导致了在连续传输数据帧的时候,上一帧的CS根本没来得及完全释放,就马上被下一帧拉低了。 总之,硬件管理CS的尝试算是彻底失败了——因为硬件CS做不到只在一个数据帧传输的时候拉低CS。 如果干脆始终拉低CS,我也做了尝试,结果不行。怀疑是过早拉低CS导致多识别了一个时钟沿导致,我尝试了两种SPI时钟相位和两种SPI时钟空闲电平的4种组合。。,都不行。但是作为对照组,仅仅把CS改成软件管理,其余设置不变,就能在时钟POL=HIGH, PHA=2EDGE的组合下成功点屏。 所以排除时钟相位问题后,结论只能是LCD的驱动芯片需要每帧数据结束后CS的上升沿完成某些操作。 所以底层硬件就决定了即便该LCD单独使用一个SPI驱动,也不可能是单线半双工模式实现——因为它只支持硬件管理CS,而硬件管理CS又不能满足CS的时序要求。 那么答案只有一个,变成软件管理CS,MCU直接控制GPIO在每一帧数据结束后拉高CS。即上文的方法2同样不可行,只能改成方法3。那反正都软件管理CS了,干脆和触摸IC共用一个SPI得了,所以最后还是老老实实回到方法1。。 碎碎念:仔细想想,其实LCD的另一些控制信号如RST, DC 后者几乎快和CS一样常用,都只能靠软件实现。所以也许我真的不应该追求硬件CS? 我当前的GCC编译优化为O0,CPU主频288M,SPI通信用8分频(APB的144M / 8 = 18M),在这个速度下,实测方法2中一个8bit数据帧传输<500ns,最后一个时钟结束后约 数据帧之间的间隔接近1us,几乎是数据传输时间本身的两倍了 ? ================?谨以此文章纪念被SPI折磨而逝去的三个白天?================ |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/26 19:47:39- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |