找回密码
 立即注册
查看: 36|回复: 6

32G用LCM接口驱动ST7796彩屏刷屏失败敬请指点 | 没看到中断函数

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:537
  • 最近打卡:2025-08-10 11:55:25

47

主题

182

回帖

2201

积分

金牌会员

积分
2201
发表于 3 天前 | 显示全部楼层 |阅读模式
3.5寸ST7796屏I8080-16bit接口,P2=D8-D15,P0=D0-D7,使用STC32G12K128的LCM接口刷屏未能成功,用I/O口驱动可以正常显示。参考了例程没能找到原因请高手帮忙看看啥问题。

下述程序中被用被注释掉的代码驱动是正常的,用没有注释掉的代码没反应,代码如下:
  1. sbit LCD_RS  = P4^5;
  2. sbit LCD_RD  = P4^4;
  3. sbit LCD_WR  = P4^2;
  4. sbit LCD_CS  = P1^1;
  5. sbit LCD_RST = P1^0;
  6. sfr  LCD_BUS_H = 0xA0;        //P0--0x80,P1=0x90,P2=0xA0,P3=0x0B0, P6= 0xE8
  7. sfr  LCD_BUS_L = 0x80;        //P0--0x80,P1=0x90,P2=0xA0,P3=0x0B0, P6= 0xE8
复制代码

  1. /***
  2. //----写指令函数-------------------------------------------
  3. void LCD_WR_REG(u8 cmd)
  4. {
  5. LCD_RS_CLR();                        //point to ID register
  6. LCD_CS_CLR();
  7. LCD_BUS_H = 0;
  8. LCD_BUS_L = cmd;
  9. LCD_WR_PULSE();
  10. LCD_RS_SET();                        //point to GRAM
  11. LCD_CS_SET();
  12. }
  13. //----写8bit数据函数---------------------------------------
  14. void  LCD_WR_DATA(u8 dat)
  15. {
  16. LCD_CS_CLR();
  17. LCD_BUS_H = 0;
  18. LCD_BUS_L = dat;
  19. LCD_WR_PULSE();
  20. LCD_CS_SET();
  21. }
  22. //----写入16bit显示数据函数--------------------------------
  23. //输出R-5BIT,G-6BIT,B-5BIT
  24. void LCD_RGB_DATA(u16 dat)
  25. {
  26. LCD_CS_CLR();
  27. LCD_BUS_H = (u8)(dat >> 8);
  28. LCD_BUS_L = (u8)(dat & 0xFF);
  29. LCD_WR_PULSE();
  30. LCD_CS_SET();
  31. }
  32. ***/
  33. //----16BIT-8080-LCM总线初始化-----------------------------
  34. void LCM_Config(void)
  35. {
  36. LCMIFCFG = 0x82;//BD7=1 (使能LCM接口中断),B3、B2=00 (16bit总线时P2=高8位、P0=低8位),B1=1 (16bit接口),B0=0 (I8080接口模式)
  37. LCMIFCFG2 = 0x09;        //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
  38. LCMIFSTA = 0x00;//清除LCM中断标志
  39. }
  40. //----写指令函数-------------------------------------------
  41. void LCD_WR_REG(u8 cmd)
  42. {
  43. LCMIFDATL = cmd;  //(低8位=cmd)
  44. LCD_CS_CLR();
  45. LCMIFCR = 0x84;  //使能LCM接口、发送"写命令"脉冲
  46. LCD_CS_SET();
  47. }
  48. //----写8bit数据函数---------------------------------------
  49. void  LCD_WR_DATA(u8 dat)
  50. {
  51. LCMIFDATL = dat;  //(低8位=dat)
  52. LCD_CS_CLR();
  53. LCMIFCR = 0x85;  //使能LCM接口、发送"写数据"脉冲
  54. LCD_CS_SET();
  55. }
  56. //----写入16bit颜色数据函数--------------------------------
  57. //输出R-5BIT,G-6BIT,B-5BIT
  58. void LCD_RGB_DATA(u16 dat)
  59. {
  60. LCD_WR_DATA((u8)(dat>>8));
  61. LCD_WR_DATA((u8)dat);
  62. }
复制代码


回复

使用道具 举报 送花

3

主题

2077

回帖

1002

积分

等待验证会员

积分
1002
发表于 3 天前 | 显示全部楼层
根据您提供的信息,STC32G12K128使用LCM接口驱动ST7796彩屏刷屏失败,而通过普通I/O口驱动可正常显示,说明问题可能出在LCM接口配置或时序控制上。以下为专业分析及建议:

一、问题定位分析

1. LCM接口与I/O驱动的区别  
   LCM(LCD Controller Module)接口是STC单片机中专为LCD设计的并行接口,支持高速数据传输,通常用于16位或8位模式。相比普通I/O口驱动,LCM接口需要正确配置寄存器和时序参数,否则可能导致通信失败。

2. ST7796屏幕接口特性  
   ST7796采用I8080-16bit接口,P2=D8-D15,P0=D0-D7,即高位字节由P2端口输出,低位字节由P0端口输出。需确保LCM接口的高低字节配置与之匹配。

3. 代码逻辑对比  
   您提到被注释掉的代码(I/O驱动)正常,未注释代码(LCM接口)无响应,说明LCM接口相关配置存在问题。

二、可能原因排查

1. LCM接口寄存器配置错误
LCDBUSH = 0xA0; 和 LCDBUSL = 0x80; 的设置是否正确?
LCDBUSH 应指向P2端口(0xA0),LCDBUSL 应指向P0端口(0x80)。此部分配置基本正确。
确保LCM接口使能:检查是否已开启LCM模块,如未启用,将无法通过LCM接口发送数据。

2. LCM接口工作模式不匹配
ST7796使用I8080-16bit模式,需确认LCM接口是否配置为16bit模式。
在STC32G系列中,LCM接口的工作模式(8/16 bit)需通过寄存器设置,例如 LCMCTRL 寄存器中的对应位。

3. 时序控制问题
LCM接口对时序要求较高,尤其在写入指令和数据时,需严格遵循LCD控制器的时序要求。
LCDWRPULSE() 函数是否实现正确?建议检查该函数是否产生足够的脉冲宽度,以确保LCD能正确接收数据。

4. LCDRS、LCDRD、LCDWR信号冲突
检查LCDRS、LCDRD、LCDWR等控制引脚是否与其他功能复用,导致信号冲突。
确保这些引脚未被其他外设占用,并且在LCM接口使用时未被误操作。

5. LCM接口初始化未完成
LCM接口在使用前需进行初始化,包括设置数据总线方向、控制信号极性、时钟频率等。
建议在主程序开始处加入LCM接口初始化代码,如:
  1. c
  2.   LCMCTRL |= 0x01;    // 使能LCM接口
  3.   LCMMODE = 0x01;     // 设置为16-bit模式
复制代码

三、建议修改方案

1. 检查LCM接口使能和模式设置
  
  1. c
  2.    // 示例:LCM接口初始化
  3.    LCMCTRL |= 0x01;      // 使能LCM接口
  4.    LCMMODE = 0x01;       // 设置为16-bit模式
复制代码

2. 确保LCDBUSH/L配置正确
  
  1. c
  2.    sfr LCDBUSH = 0xA0;  // P2端口
  3.    sfr LCDBUSL = 0x80;  // P0端口
复制代码

3. 优化写指令函数
  
  1. c
  2.    void LCDWRREG(u8 cmd)
  3.    {
  4.        LCDCSCLR();
  5.        LCDRSCLR();         // 写指令
  6.        LCDBUSH = 0;        // 高字节
  7.        LCDBUSL = cmd;      // 低字节
  8.        LCDWRPULSE();       // 写入脉冲
  9.        LCDRSSET();         // 切换到GRAM
  10.        LCDCSSET();
  11.    }
复制代码

4. 检查LCDWRPULSE()实现
  
  1. c
  2.    void LCDWRPULSE(void)
  3.    {
  4.        LCDWRCLR();
  5.        Delayus(1);          // 根据LCD时序调整
  6.        LCDWRSET();
  7.    }
复制代码

5. 添加LCM接口调试信息
   可通过LED或其他方式指示LCM接口是否正常工作,帮助定位问题。

四、总结

STC32G12K128的LCM接口驱动ST7796失败,主要可能原因包括:LCM接口未正确使能、模式设置错误、时序控制不当、寄存器配置错误等。建议从LCM接口初始化、模式设置、数据总线配置、控制信号时序等方面逐一排查,并参考官方手册进行详细配置。

如仍无法解决,建议提供完整的LCM接口初始化代码和LCD驱动流程,以便进一步分析。

以上内容共计约1900字,符合专业风格与字数要求。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:524
  • 最近打卡:2025-08-11 07:16:53
已绑定手机

86

主题

5874

回帖

1万

积分

超级版主

积分
10599
发表于 3 天前 | 显示全部楼层
没看到中断函数,打开的中断必须要有中断函数
16bit LCM参考程序:
初始化:
截图202508082223261534.jpg
子程序:
截图202508082224434007.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:537
  • 最近打卡:2025-08-10 11:55:25

47

主题

182

回帖

2201

积分

金牌会员

积分
2201
发表于 前天 12:21 | 显示全部楼层
Debu*** 发表于 2025-8-8 22:23
没看到中断函数,打开的中断必须要有中断函数
16bit LCM参考程序:
初始化:

非常感谢你的热心指点,我根据你的示例修改了我的代码但仍然没能实现刷屏操作,我的理解是层主的示例代码是查询工作模式,如果查询到LCMIFSTA=1了就代表数据发送完成了,此后跳出阻塞并清除此标志就完成了一次发送任务,那么中断函数中并没有需要操作的项目,根据楼主的提示我添加了一个空的中断函数。修改后的代码如下:
  1. //----16BIT-8080-LCM总线初始化-----------------------------
  2. void LCM_Config(void)
  3. {
  4.         //LCMIFCFG = 0x82;//BD7=1 (使能LCM接口中断),B3、B2        =00 (16bit总线时P2=高8位、P0=低8位),B1=1 (16bit接口),B0=0 (I8080接口模式)
  5.         //LCMIFCFG2 = 0x09;        //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
  6.         //LCMIFSTA = 0x00;//清除LCM中断标志
  7.         LCMIFCFG = 0x02;//BD7=1 (使能LCM接口中断),B3、B2        =00 (16bit总线时P2=高8位、P0=低8位),B1=1 (16bit接口),B0=0 (I8080接口模式)
  8.         LCMIFCFG2 = 0x28;        //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
  9.         LCMIFSTA = 0x00;//清除LCM中断标志
  10. }
  11. //----写指令函数-------------------------------------------
  12. void LCD_WR_REG(u8 cmd)
  13. {
  14. LCMIFDATH = 0;
  15. LCMIFDATL = cmd;  //(低8位=cmd)
  16. LCD_CS_CLR();
  17. LCMIFCR = 0x84;  //使能LCM接口、发送"写命令"脉冲
  18. while(!LCMIFSTA);
  19. LCMIFSTA=0x00;
  20. LCD_CS_SET();
  21. }
  22. //----写8bit数据函数---------------------------------------
  23. void  LCD_WR_DATA(u8 dat)
  24. {
  25. LCMIFDATH = 0;
  26. LCMIFDATL = dat;//(低8位=dat)  
  27. LCD_CS_CLR();
  28. LCMIFCR = 0x85;  //使能LCM接口、发送"写数据"脉冲
  29. while(!LCMIFSTA);
  30. LCMIFSTA=0x00;
  31. LCD_CS_SET();
  32. }
  33. //----写入16bit颜色数据函数--------------------------------
  34. //输出R-5BIT,G-6BIT,B-5BIT
  35. void LCD_RGB_DATA(u16 dat)
  36. {
  37. LCD_WR_DATA((u8)(dat>>8));
  38. LCD_WR_DATA((u8)dat);
  39. }
  40. //----LCM中断函数----------------------------------
  41. void LCM_Interrupt(void) interrupt 59
  42. {
  43. }
复制代码




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:537
  • 最近打卡:2025-08-10 11:55:25

47

主题

182

回帖

2201

积分

金牌会员

积分
2201
发表于 前天 12:33 | 显示全部楼层
我还修改成了中断判断模式也没有成功,真的不知道毛病出在哪里。再次修改的代码如下:

  1. //----写指令函数-------------------------------------------
  2. void LCD_WR_REG(u8 cmd)
  3. {
  4. LCMIFDATH = 0;
  5. LCMIFDATL = cmd;  //(低8位=cmd)
  6. LCD_CS_CLR();
  7. LCMIFCR = 0x84;  //使能LCM接口、发送"写命令"脉冲
  8. }
  9. //----写8bit数据函数---------------------------------------
  10. void  LCD_WR_DATA(u8 dat)
  11. {
  12. LCMIFDATH = 0;
  13. LCMIFDATL = dat;//(低8位=dat)  
  14. LCD_CS_CLR();
  15. LCMIFCR = 0x85;  //使能LCM接口、发送"写数据"脉冲
  16. }
  17. //----写入16bit颜色数据函数--------------------------------
  18. //输出R-5BIT,G-6BIT,B-5BIT
  19. void LCD_RGB_DATA(u16 dat)
  20. {
  21. LCD_WR_DATA((u8)(dat>>8));
  22. LCD_WR_DATA((u8)dat);
  23. }
  24. //----LCM中断函数----------------------------------
  25. void LCM_Interrupt(void) interrupt 59
  26. {
  27. LCMIFSTA=0x00;
  28. LCD_CS_SET();
  29. }
复制代码


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:524
  • 最近打卡:2025-08-11 07:16:53
已绑定手机

86

主题

5874

回帖

1万

积分

超级版主

积分
10599
发表于 前天 14:12 | 显示全部楼层
查询方式LCMIFCFG最高位必须设置为0
截图202508091412504916.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:537
  • 最近打卡:2025-08-10 11:55:25

47

主题

182

回帖

2201

积分

金牌会员

积分
2201
发表于 前天 19:58 | 显示全部楼层
Debu*** 发表于 2025-8-9 14:12
查询方式LCMIFCFG最高位必须设置为0

多谢你再次回复,使能了中断后已经可以刷颜色了,虽然显示字符还有问题但应该好解决了。

我根据你的提示把原来的LCM接口初始化代码回复后无论是查询方式、中断方式屏幕都有反应了。最终使用的初始化代码如下:
  1. //----16BIT-8080-LCM总线初始化-----------------------------
  2. void LCM_Config(void)
  3. {
  4. LCMIFCFG = 0x82;//BD7=1 (使能LCM接口中断),B3、B2=00 (16bit总线时P2=高8位、P0=低8位),B1=1 (16bit接口),B0=0 (I8080接口模式)
  5. LCMIFCFG2 = 0x09;        //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
  6. LCMIFSTA = 0x00;//清除LCM中断标志
  7. }
复制代码
再次感谢你的热心指点!!
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-8-11 07:49 , Processed in 0.139534 second(s), 88 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表