[PIC®/AVR®/dsPIC®产品] 大家一起来攻克PIC18F单片机的MCC配置SPI驱动TFT难题——已经搞定

[复制链接]
 楼主| gaoyang9992006 发表于 2024-7-22 15:57 | 显示全部楼层 |阅读模式
本帖最后由 gaoyang9992006 于 2024-7-30 21:57 编辑

不好意思,我在用MCC配置SPI驱动TFT显示屏(ST7735S)的时候,失手了。
没能驱动起来。
我用的是PIC18F16Q41 curiosity NANO开发板
为了方便供电和插飞线,我用IO代替的VCC给小屏供电,以及给背光供电。

有问题的工程放这个附件压缩包里了。大家可以下载测试,找出问题在哪儿
程序结构讲解
ST7735的相关文件有4个,其中2个是关键文件st7735.c 和 st7735.h
.h中仅仅用于引入MCC配置的系统文件头文件和延时函数头文件。
在.c中实现了接口

  1. void ST7735_delay(uint8_t i)
  2. {
  3.         DELAY_microseconds(i);
  4. }

  5. void ST7735_SPI_SendByte(uint8_t byte)
  6. {
  7.     SPI1_ByteWrite(byte);
  8.     while (SPI1_IsTxReady()==false);
  9. }

  10. void ST7735_SPI_RST_SetLow(void)
  11. {
  12.     RST_SetLow();
  13. }
  14. void ST7735_SPI_RST_SetHigh(void)
  15. {
  16.     RST_SetHigh();
  17. }

  18. void ST7735_SPI_CS_SetLow(void)
  19. {
  20.     CS_SetLow();
  21. }
  22. void ST7735_SPI_CS_SetHigh(void)
  23. {
  24.     CS_SetHigh();
  25. }

  26. void ST7735_SPI_DC_SetLow(void)
  27. {
  28.     DC_SetLow();
  29. }
  30. void ST7735_SPI_DC_SetHigh(void)
  31. {
  32.     DC_SetHigh();
  33. }
复制代码
目前运行的时候会卡在函数
  1. void ST7735_SPI_SendByte(uint8_t byte)
  2. {
  3.     SPI1_ByteWrite(byte);
  4.     while (SPI1_IsTxReady()==false);
  5. }
复制代码
的while循环里。
不知道为何?
另外在MCC配置SPI的时候确实不知道4个模式是什么意思,如下:

默认的是Mode1,我也尝试切换到其他模式,也是卡死,无法正常点亮屏幕。
我在其他ARM核心单片机测试过这个ST7735的库,是可以用的。

搞定方法:https://bbs.21ic.com/icview-3393320-1-1.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| gaoyang9992006 发表于 2024-7-22 15:58 | 显示全部楼层
恳求各位大佬有条件的测试一下,帮忙检查一下,看看如何在MCC里使用好PIC18F的SPI来驱动显示屏。
 楼主| gaoyang9992006 发表于 2024-7-22 16:34 | 显示全部楼层
ST7735的程序本身是没问题的,我将SPI发送函数换成IO模拟就可以正常点亮。
所以问题应该是SPI没有配置正确
  1. void LCD_Writ_Bus(uint8_t dat)
  2. {       
  3.         uint8_t i;
  4.         for(i=0;i<8;i++)
  5.         {                          
  6.         SCK_SetLow();
  7.                 if(dat&0x80)
  8.                 {
  9.            SDO_SetHigh();
  10.                 }
  11.                 else
  12.                 {
  13.            SDO_SetLow();
  14.                 }
  15.         SCK_SetHigh();
  16.                 dat<<=1;
  17.         }
  18. }

  19. void ST7735_SPI_SendByte(uint8_t byte)
  20. {
  21. //    SPI1_ByteWrite(byte);
  22. //    while (SPI1_IsTxReady()==false);
  23.     LCD_Writ_Bus(byte);
  24. }
复制代码
上述是切换成IO模拟的实现代码,是可以正常工作的。

lcczg 发表于 2024-7-22 17:38 | 显示全部楼层
4个模式选择的是SPI CON1里的CKE CKP:
      CKE      CKP
0:   1         0
1:   0         0
2:   1         1
3:   0         1
控制采样时钟,可以看数据手册图35-7  35-9

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| gaoyang9992006 发表于 2024-7-22 19:21 | 显示全部楼层
lcczg 发表于 2024-7-22 17:38
4个模式选择的是SPI CON1里的CKE CKP:
      CKE      CKP
0:   1         0

再看看为何发送函数一直卡,
wanduzi 发表于 2024-7-22 20:52 | 显示全部楼层
期待楼主能解决这个问题。
xinxianshi 发表于 2024-7-22 22:26 | 显示全部楼层
SPI(Serial Peripheral Interface)是一种常见的串行通信协议,用于在微控制器、传感器、存储器等设备之间进行通信。SPI控制器支持的主要模式包括模式0到模式3,它们主要区别在于时钟极性(CPOL)和时钟相位(CPHA)的不同设置。

这里是对SPI控制器支持的模式0到模式3的简要介绍:

模式0:

CPOL = 0,CPHA = 0
时钟极性为低电平(时钟信号空闲时为低电平),时钟相位在第一个时钟边沿进行数据采样。
数据在时钟的上升沿采样,下降沿更新。
模式1:

CPOL = 0,CPHA = 1
时钟极性为低电平,时钟相位在第二个时钟边沿进行数据采样。
数据在时钟的下降沿采样,上升沿更新。
模式2:

CPOL = 1,CPHA = 0
时钟极性为高电平(时钟信号空闲时为高电平),时钟相位在第一个时钟边沿进行数据采样。
数据在时钟的下降沿采样,上升沿更新。
模式3:

CPOL = 1,CPHA = 1
时钟极性为高电平,时钟相位在第二个时钟边沿进行数据采样。
数据在时钟的上升沿采样,下降沿更新。
在SPI通信中,选择使用哪种模式取决于具体的硬件和通信需求。不同的设备可能要求不同的模式来进行正确的通信,特别是在速率高、数据精确性要求高的情况下。
xinxianshi 发表于 2024-7-22 22:26 | 显示全部楼层
我猜模式可能是上面这个内容。不过怎么卡死,不知道。
lcczg 发表于 2024-7-23 09:39 | 显示全部楼层
本帖最后由 lcczg 于 2024-7-23 09:49 编辑
gaoyang9992006 发表于 2024-7-22 19:21
再看看为何发送函数一直卡,

卡死有两种可能。EN和TXIF的问题。
bool SPI1_IsTxReady(void)
{
        bool returnValue = false;
        if(true == SPI1CON0bits.EN)
        {
                returnValue = PIR3bits.SPI1TXIF;
        }
        else
        {
                returnValue = false;
        }
        return returnValue;
}
假设是发送FIFO满的时候SPI TXIF清零的情况导致堵塞。但理论上最终也会发出去的,堵塞会清除。

你测一下看看是EN还是TXIF的问题?
 楼主| gaoyang9992006 发表于 2024-7-23 10:20 | 显示全部楼层
lcczg 发表于 2024-7-23 09:39
卡死有两种可能。EN和TXIF的问题。
bool SPI1_IsTxReady(void)
{

TXIF一直是0
我用MCC配置的,工程在附件里,你看看。
lcczg 发表于 2024-7-23 16:41 | 显示全部楼层
本帖最后由 lcczg 于 2024-7-23 16:42 编辑
gaoyang9992006 发表于 2024-7-23 10:20
TXIF一直是0
我用MCC配置的,工程在附件里,你看看。

我重现了这个现象。
调试发现根本的原因在于模式的设置, 在函数void SPI1_ByteWrite(uint8_t byteData)中,
SPI1CON2 = SPI1CON2 | _SPI1CON2_SPI1RXR_MASK | _SPI1CON2_SPI1TXR_MASK;
上述代码使能了发送和接收的FIFO。即便你只使用了发送FIFO,仍然需要处理接收FIFO。
堵塞的原因在于没有处理接收FIFO,导致满了FULL,导致传输中断,发送也就中断了。
数据手册里有描述:

在你的应用中只有发送,所以只需使能发送FIFO即可。
SPI1CON2 = SPI1CON2 | _SPI1CON2_SPI1TXR_MASK;

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| gaoyang9992006 发表于 2024-7-23 17:02 | 显示全部楼层
lcczg 发表于 2024-7-23 16:41
我重现了这个现象。
调试发现根本的原因在于模式的设置, 在函数void SPI1_ByteWrite(uint8_t byteData)中 ...

好,我试试看,那个函数体是MCC自动生成的。发现新版的MCC里面配置这个SPI,几乎没什么选项可配置的。
 楼主| gaoyang9992006 发表于 2024-7-23 19:39 | 显示全部楼层
lcczg 发表于 2024-7-23 16:41
我重现了这个现象。
调试发现根本的原因在于模式的设置, 在函数void SPI1_ByteWrite(uint8_t byteData)中 ...

试了一下,这个设置确实可以解决卡死。
但是没点亮屏幕。电路不变,程序其他都不变,换成IO模拟的就可以。不知道问题在哪儿了。
稳稳の幸福 发表于 2024-7-23 21:08 | 显示全部楼层
什么时候点亮屏幕分享一下啊。
guijial511 发表于 2024-7-24 08:04 来自手机 | 显示全部楼层
没点亮屏幕,说明驱动时序或者寄存器配置还是有点问题。
lcczg 发表于 2024-7-24 10:00 | 显示全部楼层
gaoyang9992006 发表于 2024-7-23 19:39
试了一下,这个设置确实可以解决卡死。
但是没点亮屏幕。电路不变,程序其他都不变,换成IO模拟的就可以 ...

比较下两种配置下SPI输出的波形。
 楼主| gaoyang9992006 发表于 2024-7-24 10:50 | 显示全部楼层
guijial511 发表于 2024-7-24 08:04
没点亮屏幕,说明驱动时序或者寄存器配置还是有点问题。

没有问题,只是SPI发送函数本身没发出来任何东西。。。换成IO模拟的函数就可以正常,工作,在STM32,新唐,CW,等多种单片机上测试过都是一次点亮。
 楼主| gaoyang9992006 发表于 2024-7-24 10:50 | 显示全部楼层
lcczg 发表于 2024-7-24 10:00
比较下两种配置下SPI输出的波形。

示波器观察了,没有波形输出。。。
lcczg 发表于 2024-7-24 14:40 | 显示全部楼层
本帖最后由 lcczg 于 2024-7-24 14:54 编辑

gaoyang9992006 发表于 2024-7-24 10:50
示波器观察了,没有波形输出。。。

我这里可以看到的。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| gaoyang9992006 发表于 2024-7-24 15:12 | 显示全部楼层
lcczg 发表于 2024-7-24 14:40
我这里可以看到的。

你的工程打包分享一下我对比一下。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2049

主题

16371

帖子

221

粉丝
快速回复 在线客服 返回列表 返回顶部