找回密码
 立即注册
查看: 2285|回复: 12

使用AI8051U和SPI驱动ST7796的问题

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:52
  • 最近打卡:2025-04-08 20:05:04
已绑定手机

13

主题

79

回帖

438

积分

荣誉版主

积分
438
发表于 2024-11-27 18:11:34 | 显示全部楼层 |阅读模式
之前用ESP32S3的TFT-ESPI和LVGL驱动过这块屏幕,使用STM32F4、以及配合LVGL也驱动过这块屏幕。

但是这几天学习AI8051U时,我使用AI8051U和普通SPI驱动ST7796一直没有亮屏,按照官方视频和有关代码。


现有一般都是DMA+SPI或者是高速SPI点屏,正常来说使用最基础的方式也能够驱动啊,但屏幕就还只是白色(BL亮),展示不了其他东西。

我的硬件没有PSRAM和SPIFLASH,就只是简单的驱动点屏。源代码上传了,请大佬给指导指导。


截图202411271811217334.jpg
08_AI8051U_ST7796SPI.zip (10.61 MB, 下载次数: 86)






君子知命不惑,日日自新。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:481
  • 最近打卡:2025-06-29 12:34:20
已绑定手机

81

主题

5219

回帖

9302

积分

超级版主

DebugLab

积分
9302
发表于 2024-11-27 18:27:59 | 显示全部楼层
示波器或逻辑分析仪看看信号正常不
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:52
  • 最近打卡:2025-04-08 20:05:04
已绑定手机

13

主题

79

回帖

438

积分

荣誉版主

积分
438
发表于 2024-11-27 18:56:44 来自手机 | 显示全部楼层
DebugLab 发表于 2024-11-27 18:27
示波器或逻辑分析仪看看信号正常不

业余玩家没有{:5_276:}
君子知命不惑,日日自新。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:52
  • 最近打卡:2025-04-08 20:05:04
已绑定手机

13

主题

79

回帖

438

积分

荣誉版主

积分
438
发表于 2024-11-27 21:59:21 | 显示全部楼层
又改了一个多小时,还是没办法点亮。是支持不了SPI的ST7796吗?
AI8051U的SPI驱动屏有点难搞,还是要必须配合DMA和PSRAM使用才可以?

08_AI8051U_ST7796SPI.zip

10.62 MB, 下载次数: 70

君子知命不惑,日日自新。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2025-06-29 00:35:48

741

主题

1万

回帖

1万

积分

管理员

积分
17190
发表于 2024-11-27 22:21:52 | 显示全部楼层
谁有这个屏,寄2块给我们,我们来帮忙测试下
或者告诉我们在哪买,我们买了来测试下
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:52
  • 最近打卡:2025-04-08 20:05:04
已绑定手机

13

主题

79

回帖

438

积分

荣誉版主

积分
438
发表于 2024-11-27 23:26:58 | 显示全部楼层
截图202411272326551513.jpg
君子知命不惑,日日自新。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:52
  • 最近打卡:2025-04-08 20:05:04
已绑定手机

13

主题

79

回帖

438

积分

荣誉版主

积分
438
发表于 2024-12-1 21:02:44 | 显示全部楼层
AI8051U可能驱动不了 SPI的4寸ST7796显示屏。


同样使用试验箱程序包的第76号文件,尝试驱动了2.8寸7789和4寸7796显示屏。

同样的代码,连屏幕分辨率都没改变,只是两者驱动部分改变了(7796的驱动代码在stm可以正常驱动),结果是7789可以驱动,7796无显示。

截图202412012102049973.jpg


截图202412012102135107.jpg

  1. /*************  功能说明    **************
  2. 本例程基于AI8051U为主控芯片的实验箱V1.1版本进行编写测试。
  3. 使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
  4. edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
  5. 彩色SPI接口TFT LCD240x240的显示程序,通过SPI DMA将3200字节的图片数据送到彩屏,传送时不占用CPU时间。
  6. 显示图形,汉字,英文,数字. TFT LCD240X240使用中景园的液晶屏,主控IC型号为ST7789V3。
  7. 其中图形显示发送命令使用SPI查询方式(11字节),图片数据使用SPI DMA操作,本例运行于40MHz, 每次SPI DMA传输总时间1.52ms. 整屏刷新55mms.
  8. 将要显示的内容放在1024字节的显存中,启动DMA传输即可。
  9. 下载时, 选择时钟 40MHz (用户可自行修改频率后重新编译即可).
  10. ******************************************/
  11.         #define        FOSC        40000000UL
  12.         #include        "AI8051U.h"
  13.         #include         "LCD.h"
  14.         #include        "lcdfont.h"
  15.         #include         "pic.h"
  16. //-----------------LCD端口定义----------------
  17. /*        定义接口        */
  18.                                                         //GND        AI8051U实验箱 V1.1
  19.                                                         //VCC        3~5V
  20. //sbit P_LCD_CLK        =          P3^2;        //D0        SPI or II2 的时钟脚
  21. //sbit P_LCD_SDA        =   P3^3;        //D1        SPI or II2 的数据脚
  22. //sbit P_LCD_RST        =          P4^7;        //RES        复位脚, 低电平复位
  23. //sbit P_LCD_DC        =          P1^1;        //DC        数据或命令脚
  24. //sbit P_LCD_CS        =        P3^5;        //CS        片选脚
  25. sbit P_LCD_CLK        =          P1^7;        //D0        SPI or II2 的时钟脚
  26. sbit P_LCD_SDA        =   P1^5;        //D1        SPI or II2 的数据脚
  27. sbit P_LCD_RST        =          P4^7;        //RES        复位脚, 低电平复位
  28. sbit P_LCD_DC                =          P1^1;        //DC        数据或命令脚
  29. sbit P_LCD_CS                =                P1^4;        //CS        片选脚
  30. // 显示定义
  31. #define USE_HORIZONTAL 3 //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏
  32. #define LCD_W 320
  33. #define LCD_H 240
  34. //-----------------变量定义----------------
  35. bit        B_SPI_DMA_busy;                //SPI DMA忙标志, 1标志SPI-DMA忙,SPI DMA中断中清除此标志,使用SPI DMA前要确认此标志为0
  36. u16        SPI_TxAddr;                        //SPI DMA要发送数据的首地址
  37. u8        xdata DisTmp[3200];        //显示缓冲,将要显示的内容放在显存里,启动DMA即可. 由于LCM DMA有4字节对齐问题,所以这里定位对地址为4的倍数
  38. //N ms延时函数
  39. void delay_ms(u16 ms)        // 1~65535 ms
  40. {
  41.         u16 i;
  42.         do
  43.         {
  44.                 i = FOSC / 6000;        //STC32系列
  45.                 while(--i)        ;
  46.         }while(--ms);
  47. }
  48. //========================================================================
  49. // 函数: void  SPI_Config(u8 SPI_io, u8 SPI_speed)
  50. // 描述: SPI初始化函数。
  51. // 参数: io: 切换到的IO,            SS  MOSI MISO SCLK
  52. //                       0: 切换到 P1.4 P1.5 P1.6 P1.7
  53. //                       1: 切换到 P2.4 P2.5 P2.6 P2.7
  54. //                       2: 切换到 P4.0 P4.1 P4.2 P4.3
  55. //                       3: 切换到 P3.5 P3.4 P3.3 P3.2
  56. //       SPI_speed: SPI的速度, 0: fosc/4,  1: fosc/8,  2: fosc/16,  3: fosc/2
  57. // 返回: none.
  58. // 版本: VER1.0
  59. // 日期: 2024-8-13
  60. // 备注:
  61. //========================================================================
  62. void  SPI_Config(u8 SPI_io, u8 SPI_speed)
  63. {
  64.         SPI_io &= 3;
  65.         SPCTL = SPI_speed & 3;        //配置SPI 速度, 这条指令先执行, 顺便Bit7~Bit2清0
  66.         SSIG = 1;        //1: 忽略SS脚,由MSTR位决定主机还是从机                0: SS脚用于决定主机还是从机。
  67.         SPEN = 1;        //1: 允许SPI,                                                                0:禁止SPI,所有SPI管脚均为普通IO
  68.         DORD = 0;        //1:LSB先发,                                                                0:MSB先发
  69.         MSTR = 1;        //1:设为主机                                                                0:设为从机
  70.         CPOL = 1;        //1: 空闲时SCLK为高电平,                                        0:空闲时SCLK为低电平
  71.         CPHA = 1;        //1: 数据在SCLK前沿驱动,后沿采样.                        0: 数据在SCLK前沿采样,后沿驱动.
  72. //        SPR1 = 0;        //SPR1,SPR0   00: fosc/4,     01: fosc/8
  73. //        SPR0 = 0;        //            10: fosc/16,    11: fosc/2
  74.         P_SW1 = (P_SW1 & ~0x0c) | ((SPI_io<<2) & 0x0c);                //切换IO
  75.         HSCLKDIV   = 1;                                        //HSCLKDIV主时钟分频
  76.         SPI_CLKDIV = 1;                                        //SPI_CLKDIV主时钟分频
  77.         SPSTAT = 0x80 + 0x40;                        //清0 SPIF和WCOL标志
  78.         if(SPI_io == 0)
  79.         {
  80.                 P1n_standard(0xf0);                        //切换到 P1.4(SS) P1.5(MOSI) P1.6(MISO) P1.7(SCLK), 设置为准双向口
  81.                 PullUpEnable(P1PU, 0xf0);        //设置上拉电阻    允许端口内部上拉电阻   PxPU, 要设置的端口对应位为1
  82.                 P1n_push_pull(Pin7+Pin5);        //MOSI SCLK设置为推挽输出
  83.                 SlewRateHigh(P1SR, Pin7+Pin5);        //MOSI SCLK端口输出设置为高速模式   PxSR, 要设置的端口对应位为1.    高速模式在3.3V供电时速度可以到13.5MHz(27MHz主频,SPI速度2分频)
  84.         }
  85.         else if(SPI_io == 1)
  86.         {
  87.                 P2n_standard(0xf0);                        //切换到P2.4(SS) P2.5(MOSI) P2.6(MISO) P2.7(SCLK), 设置为准双向口
  88.                 PullUpEnable(P2PU, 0xf0);        //设置上拉电阻    允许端口内部上拉电阻   PxPU, 要设置的端口对应位为1
  89.                 P2n_push_pull(Pin7+Pin5);        //MOSI SCLK设置为推挽输出
  90.                 SlewRateHigh(P2SR, Pin7+Pin5);        //MOSI SCLK端口输出设置为高速模式   PxSR, 要设置的端口对应位为1.    高速模式在3.3V供电时速度可以到13.5MHz(27MHz主频,SPI速度2分频)
  91.         }
  92.         else if(SPI_io == 2)
  93.         {
  94.                 P4n_standard(0x0f);                        //切换到P4.0(SS) P4.1(MOSI) P4.2(MISO) P4.3(SCLK), 设置为准双向口
  95.                 PullUpEnable(P4PU, 0x0f);        //设置上拉电阻    允许端口内部上拉电阻   PxPU, 要设置的端口对应位为1
  96.                 P4n_push_pull(Pin3+Pin1);        //MOSI SCLK设置为推挽输出
  97.                 SlewRateHigh(P4SR, Pin3+Pin1);        //MOSI SCLK端口输出设置为高速模式   PxSR, 要设置的端口对应位为1.    高速模式在3.3V供电时速度可以到13.5MHz(27MHz主频,SPI速度2分频)
  98.         }
  99.         else if(SPI_io == 3)
  100.         {
  101.                 P3n_standard(0x3C);                //切换到P3.5(SS) P3.4(MOSI) P3.3(MISO) P3.2(SCLK), 设置为准双向口
  102.                 PullUpEnable(P3PU, 0x3c);        //设置上拉电阻    允许端口内部上拉电阻   PxPU, 要设置的端口对应位为1
  103.                 P3n_push_pull(Pin4+Pin2);        //MOSI SCLK设置为推挽输出
  104.                 SlewRateHigh(P3SR, Pin4+Pin2);        //MOSI SCLK端口输出设置为高速模式   PxSR, 要设置的端口对应位为1.    高速模式在3.3V供电时速度可以到13.5MHz(27MHz主频,SPI速度2分频)
  105.         }
  106. }
  107. //========================================================================
  108. // 描述: 写SPI一个字节函数
  109. // 参数: 无.
  110. // 返回: 无
  111. //========================================================================
  112. void        LCD_SendByte(u8 dat)
  113. {
  114.         SPDAT = dat;        //发送一个字节
  115.         while(SPIF == 0)        ;                        //等待发送完成
  116.         SPSTAT = 0x80 + 0x40;                        //清0 SPIF和WCOL标志
  117. }
  118. /******************************************************************************
  119.       函数说明:LCD写入数据
  120.       入口数据:dat 写入的数据
  121.       返回值:  无
  122. ******************************************************************************/
  123. void LCD_WR_DATA8(u8 dat)
  124. {
  125.         P_LCD_CS = 0;
  126.         LCD_SendByte(dat);
  127.         P_LCD_CS = 1;
  128. }
  129. /******************************************************************************
  130.       函数说明:LCD写入数据
  131.       入口数据:dat 写入的数据
  132.       返回值:  无
  133. ******************************************************************************/
  134. void LCD_WR_DATA16(u16 dat)
  135. {
  136.         P_LCD_CS = 0;
  137.         LCD_SendByte((u8)(dat>>8));
  138.         LCD_SendByte((u8)dat);
  139.         P_LCD_CS = 1;
  140. }
  141. /******************************************************************************
  142.       函数说明:LCD写入命令
  143.       入口数据:dat 写入的命令
  144.       返回值:  无
  145. ******************************************************************************/
  146. void LCD_WR_REG(u8 dat)
  147. {
  148.         P_LCD_DC = 0;//写命令
  149.         P_LCD_CS = 0;
  150.         LCD_SendByte(dat);
  151.         P_LCD_CS = 1;
  152.         P_LCD_DC = 1;//写数据
  153. }
  154. /******************************************************************************
  155.       函数说明:设置起始和结束地址
  156.       入口数据:x1,x2 设置列的起始和结束地址
  157.                 y1,y2 设置行的起始和结束地址
  158.       返回值:  无
  159. ******************************************************************************/
  160. void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
  161. {
  162.         if(USE_HORIZONTAL == 1)
  163.         {
  164.                 y1 += 80;
  165.                 y2 += 80;
  166.         }
  167.         else if(USE_HORIZONTAL == 3)
  168.         {
  169.                 x1 += 80;
  170.                 x2 += 80;
  171.         }
  172.         LCD_WR_REG(0x2a);//列地址设置
  173.         LCD_WR_DATA16(x1);
  174.         LCD_WR_DATA16(x2);
  175.         LCD_WR_REG(0x2b);//行地址设置
  176.         LCD_WR_DATA16(y1);
  177.         LCD_WR_DATA16(y2);
  178.         LCD_WR_REG(0x2c);//储存器写
  179. }
  180. /******************************************************************************
  181.       函数说明:LCD初始化函数
  182.       入口数据:无
  183.       返回值:  无
  184. ******************************************************************************/
  185. void LCD_Init(u8 LCDdriver)
  186. {
  187.         P_LCD_CLK = 1;//SCLK
  188.         P_LCD_SDA = 1;//MOSI
  189.         P_LCD_RST = 1;//RES
  190.         P_LCD_DC  = 1;//DC
  191.         P_LCD_CS  = 1;//CS
  192.         P_LCD_RST = 0;
  193.         delay_ms(100);
  194.         P_LCD_RST = 1;
  195.         delay_ms(100);
  196.         if(LCDdriver==0)
  197.         {
  198.                 LCD_WR_REG(0x11);         //Sleep out 退出睡眠
  199.                 delay_ms(120);                //Delay 120ms
  200.                 LCD_WR_REG(0x36);        //显存访问控制
  201.                  if(USE_HORIZONTAL == 0)        LCD_WR_DATA8(0x00);
  202.                 else if(USE_HORIZONTAL == 1)        LCD_WR_DATA8(0xC0);
  203.                 else if(USE_HORIZONTAL == 2)        LCD_WR_DATA8(0x70);
  204.                 else LCD_WR_DATA8(0xA0);
  205.                 LCD_WR_REG(0x3A);        //接口格式
  206.                 LCD_WR_DATA8(0x05);
  207.                 LCD_WR_REG(0xB2);
  208.                 LCD_WR_DATA8(0x1F);
  209.                 LCD_WR_DATA8(0x1F);
  210.                 LCD_WR_DATA8(0x00);
  211.                 LCD_WR_DATA8(0x33);
  212.                 LCD_WR_DATA8(0x33);
  213.                 LCD_WR_REG(0xB7);
  214.                 LCD_WR_DATA8(0x35);
  215.                 LCD_WR_REG(0xBB);
  216.                 LCD_WR_DATA8(0x20);   //2b
  217.                 LCD_WR_REG(0xC0);
  218.                 LCD_WR_DATA8(0x2C);
  219.                 LCD_WR_REG(0xC2);
  220.                 LCD_WR_DATA8(0x01);
  221.                 LCD_WR_REG(0xC3);
  222.                 LCD_WR_DATA8(0x01);
  223.                 LCD_WR_REG(0xC4);
  224.                 LCD_WR_DATA8(0x18);   //VDV, 0x20:0v
  225.                 LCD_WR_REG(0xC6);
  226.                 LCD_WR_DATA8(0x13);   //0x13:60Hz
  227.                 LCD_WR_REG(0xD0);
  228.                 LCD_WR_DATA8(0xA4);
  229.                 LCD_WR_DATA8(0xA1);
  230.                 LCD_WR_REG(0xD6);
  231.                 LCD_WR_DATA8(0xA1);   //sleep in后,gate输出为GND
  232.                 //---------------ST7789V gamma setting-------------//
  233.                 LCD_WR_REG(0xE0);        //Set Gamma
  234.                 LCD_WR_DATA8(0xF0);
  235.                 LCD_WR_DATA8(0x04);
  236.                 LCD_WR_DATA8(0x07);
  237.                 LCD_WR_DATA8(0x04);
  238.                 LCD_WR_DATA8(0x04);
  239.                 LCD_WR_DATA8(0x04);
  240.                 LCD_WR_DATA8(0x25);
  241.                 LCD_WR_DATA8(0x33);
  242.                 LCD_WR_DATA8(0x3C);
  243.                 LCD_WR_DATA8(0x36);
  244.                 LCD_WR_DATA8(0x14);
  245.                 LCD_WR_DATA8(0x12);
  246.                 LCD_WR_DATA8(0x29);
  247.                 LCD_WR_DATA8(0x30);
  248.                 LCD_WR_REG(0xE1);        //Set Gamma
  249.                 LCD_WR_DATA8(0xF0);
  250.                 LCD_WR_DATA8(0x02);
  251.                 LCD_WR_DATA8(0x04);
  252.                 LCD_WR_DATA8(0x05);
  253.                 LCD_WR_DATA8(0x05);
  254.                 LCD_WR_DATA8(0x21);
  255.                 LCD_WR_DATA8(0x25);
  256.                 LCD_WR_DATA8(0x32);
  257.                 LCD_WR_DATA8(0x3B);
  258.                 LCD_WR_DATA8(0x38);
  259.                 LCD_WR_DATA8(0x12);
  260.                 LCD_WR_DATA8(0x14);
  261.                 LCD_WR_DATA8(0x27);
  262.                 LCD_WR_DATA8(0x31);
  263.                 LCD_WR_REG(0xE4);
  264.                 LCD_WR_DATA8(0x1D);   //使用240根gate  (N+1)*8
  265.                 LCD_WR_DATA8(0x00);   //设定gate起点位置
  266.                 LCD_WR_DATA8(0x00);   //当gate没有用完时,bit4(TMG)设为0
  267.                 LCD_WR_REG(0x20);
  268.                 LCD_WR_REG(0x29);        //开启显示
  269.         }
  270.         else
  271.         {
  272.                 /****        ST7796S IPS初始化        ****/       
  273.                 LCD_WR_REG(0x11);         //Sleep out 退出睡眠
  274.                 delay_ms(120);                //Delay 120ms
  275.                 LCD_WR_REG(0x36);        //显存访问控制
  276.                 LCD_WR_DATA8(0x48);   
  277.                 LCD_WR_REG(0x3A);     
  278.                 LCD_WR_DATA8(0x55);   //LCD_WR_DATA8(0x66);
  279.                 LCD_WR_REG(0xF0);     // Command Set Control
  280.                 LCD_WR_DATA8(0xC3);   
  281.                 LCD_WR_REG(0xF0);     
  282.                 LCD_WR_DATA8(0x96);   
  283.                 LCD_WR_REG(0xB4);     
  284.                 LCD_WR_DATA8(0x01);   
  285.                 LCD_WR_REG(0xB7);     
  286.                 LCD_WR_DATA8(0xC6);   
  287.                 //LCD_WR_REG(0xB9);     
  288.                 //LCD_WR_DATA8(0x02);
  289.                 //LCD_WR_DATA8(0xE0);
  290.                 LCD_WR_REG(0xC0);     
  291.                 LCD_WR_DATA8(0x80);   
  292.                 LCD_WR_DATA8(0x45);   
  293.                 LCD_WR_REG(0xC1);     
  294.                 LCD_WR_DATA8(0x13);   //18  //00
  295.                 LCD_WR_REG(0xC2);     
  296.                 LCD_WR_DATA8(0xA7);   
  297.                 LCD_WR_REG(0xC5);     
  298.                 LCD_WR_DATA8(0x0A);   
  299.                 LCD_WR_REG(0xE8);     
  300.                 LCD_WR_DATA8(0x40);
  301.                 LCD_WR_DATA8(0x8A);
  302.                 LCD_WR_DATA8(0x00);
  303.                 LCD_WR_DATA8(0x00);
  304.                 LCD_WR_DATA8(0x29);
  305.                 LCD_WR_DATA8(0x19);
  306.                 LCD_WR_DATA8(0xA5);
  307.                 LCD_WR_DATA8(0x33);
  308.                 LCD_WR_REG(0xE0);
  309.                 LCD_WR_DATA8(0xD0);
  310.                 LCD_WR_DATA8(0x08);
  311.                 LCD_WR_DATA8(0x0F);
  312.                 LCD_WR_DATA8(0x06);
  313.                 LCD_WR_DATA8(0x06);
  314.                 LCD_WR_DATA8(0x33);
  315.                 LCD_WR_DATA8(0x30);
  316.                 LCD_WR_DATA8(0x33);
  317.                 LCD_WR_DATA8(0x47);
  318.                 LCD_WR_DATA8(0x17);
  319.                 LCD_WR_DATA8(0x13);
  320.                 LCD_WR_DATA8(0x13);
  321.                 LCD_WR_DATA8(0x2B);
  322.                 LCD_WR_DATA8(0x31);
  323.                 LCD_WR_REG(0xE1);
  324.                 LCD_WR_DATA8(0xD0);
  325.                 LCD_WR_DATA8(0x0A);
  326.                 LCD_WR_DATA8(0x11);
  327.                 LCD_WR_DATA8(0x0B);
  328.                 LCD_WR_DATA8(0x09);
  329.                 LCD_WR_DATA8(0x07);
  330.                 LCD_WR_DATA8(0x2F);
  331.                 LCD_WR_DATA8(0x33);
  332.                 LCD_WR_DATA8(0x47);
  333.                 LCD_WR_DATA8(0x38);
  334.                 LCD_WR_DATA8(0x15);
  335.                 LCD_WR_DATA8(0x16);
  336.                 LCD_WR_DATA8(0x2C);
  337.                 LCD_WR_DATA8(0x32);
  338.                  
  339.                 LCD_WR_REG(0xF0);     
  340.                 LCD_WR_DATA8(0x3C);   
  341.                 LCD_WR_REG(0xF0);     
  342.                 LCD_WR_DATA8(0x69);   
  343.                 delay_ms(120);               
  344.                 LCD_WR_REG(0x20);     
  345.                 LCD_WR_REG(0x29);
  346.                
  347.                 P1M0 |= 0x01;                //BL推挽输出
  348.                 P1M1 &= ~0x01;
  349.                
  350.                 P10=1;
  351.         }
  352. }
  353. /******************************************************************************
  354.       函数说明:在指定区域填充颜色
  355.       入口数据:xsta,ysta   起始坐标
  356.                 xend,yend   终止坐标
  357.                                                                 color       要填充的颜色
  358.       返回值:  无
  359. ******************************************************************************/
  360. void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
  361. {
  362.         u16 i,j;
  363.         LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
  364.         for(i=ysta;i<yend;i++)
  365.         {
  366.                 for(j=xsta;j<xend;j++)
  367.                 {
  368.                         LCD_WR_DATA16(color);
  369.                 }
  370.         }
  371. }
  372. /******************************************************************************
  373.       函数说明:在指定位置画点
  374.       入口数据:x,y 画点坐标
  375.                 color 点的颜色
  376.       返回值:  无
  377. ******************************************************************************/
  378. void LCD_DrawPoint(u16 x,u16 y,u16 color)
  379. {
  380.         LCD_Address_Set(x,y,x,y);//设置光标位置
  381.         LCD_WR_DATA16(color);
  382. }
  383. /******************************************************************************
  384.       函数说明:显示单个12x12汉字
  385.       入口数据:x,y显示坐标
  386.                 *s 要显示的汉字
  387.                 fc 字的颜色
  388.                 bc 字的背景色
  389.                 sizey 字号
  390.                 mode:  0非叠加模式  1叠加模式
  391.       返回值:  无
  392. ******************************************************************************/
  393. void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  394. {
  395.         u8 i,j,m=0;
  396.         u16 k;
  397.         u16 HZnum;//汉字数目
  398.         u16 TypefaceNum;//一个字符所占字节大小
  399.         u16 x0=x;
  400.         TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
  401.         HZnum=sizeof(tfont12)/sizeof(typFNT_GB12);        //统计汉字数目
  402.         for(k=0;k<HZnum;k++)
  403.         {
  404.                 if((tfont12[k].Index[0]==*(s))&&(tfont12[k].Index[1]==*(s+1)))
  405.                 {
  406.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  407.                         for(i=0;i<TypefaceNum;i++)
  408.                         {
  409.                                 for(j=0;j<8;j++)
  410.                                 {
  411.                                         if(!mode)//非叠加方式
  412.                                         {
  413.                                                 if(tfont12[k].Msk[i]&(0x01<<j))                LCD_WR_DATA16(fc);
  414.                                                 else LCD_WR_DATA16(bc);
  415.                                                 m++;
  416.                                                 if(m%sizey==0)
  417.                                                 {
  418.                                                         m=0;
  419.                                                         break;
  420.                                                 }
  421.                                         }
  422.                                         else//叠加方式
  423.                                         {
  424.                                                 if(tfont12[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  425.                                                 x++;
  426.                                                 if((x-x0)==sizey)
  427.                                                 {
  428.                                                         x=x0;
  429.                                                         y++;
  430.                                                         break;
  431.                                                 }
  432.                                         }
  433.                                 }
  434.                         }
  435.                 }
  436.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  437.         }
  438. }
  439. /******************************************************************************
  440.       函数说明:显示单个16x16汉字
  441.       入口数据:x,y显示坐标
  442.                 *s 要显示的汉字
  443.                 fc 字的颜色
  444.                 bc 字的背景色
  445.                 sizey 字号
  446.                 mode:  0非叠加模式  1叠加模式
  447.       返回值:  无
  448. ******************************************************************************/
  449. void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  450. {
  451.         u8 i,j,m=0;
  452.         u16 k;
  453.         u16 HZnum;//汉字数目
  454.         u16 TypefaceNum;//一个字符所占字节大小
  455.         u16 x0=x;
  456.   TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
  457.         HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);        //统计汉字数目
  458.         for(k=0;k<HZnum;k++)
  459.         {
  460.                 if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
  461.                 {
  462.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  463.                         for(i=0;i<TypefaceNum;i++)
  464.                         {
  465.                                 for(j=0;j<8;j++)
  466.                                 {
  467.                                         if(!mode)//非叠加方式
  468.                                         {
  469.                                                 if(tfont16[k].Msk[i]&(0x01<<j))        LCD_WR_DATA16(fc);
  470.                                                 else LCD_WR_DATA16(bc);
  471.                                                 m++;
  472.                                                 if(m%sizey==0)
  473.                                                 {
  474.                                                         m=0;
  475.                                                         break;
  476.                                                 }
  477.                                         }
  478.                                         else//叠加方式
  479.                                         {
  480.                                                 if(tfont16[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  481.                                                 x++;
  482.                                                 if((x-x0)==sizey)
  483.                                                 {
  484.                                                         x=x0;
  485.                                                         y++;
  486.                                                         break;
  487.                                                 }
  488.                                         }
  489.                                 }
  490.                         }
  491.                 }
  492.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  493.         }
  494. }
  495. /******************************************************************************
  496.       函数说明:显示单个24x24汉字
  497.       入口数据:x,y显示坐标
  498.                 *s 要显示的汉字
  499.                 fc 字的颜色
  500.                 bc 字的背景色
  501.                 sizey 字号
  502.                 mode:  0非叠加模式  1叠加模式
  503.       返回值:  无
  504. ******************************************************************************/
  505. void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  506. {
  507.         u8 i,j,m=0;
  508.         u16 k;
  509.         u16 HZnum;//汉字数目
  510.         u16 TypefaceNum;//一个字符所占字节大小
  511.         u16 x0=x;
  512.         TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
  513.         HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);        //统计汉字数目
  514.         for(k=0;k<HZnum;k++)
  515.         {
  516.                 if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
  517.                 {
  518.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  519.                         for(i=0;i<TypefaceNum;i++)
  520.                         {
  521.                                 for(j=0;j<8;j++)
  522.                                 {
  523.                                         if(!mode)//非叠加方式
  524.                                         {
  525.                                                 if(tfont24[k].Msk[i]&(0x01<<j))        LCD_WR_DATA16(fc);
  526.                                                 else LCD_WR_DATA16(bc);
  527.                                                 m++;
  528.                                                 if(m%sizey==0)
  529.                                                 {
  530.                                                         m=0;
  531.                                                         break;
  532.                                                 }
  533.                                         }
  534.                                         else//叠加方式
  535.                                         {
  536.                                                 if(tfont24[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  537.                                                 x++;
  538.                                                 if((x-x0)==sizey)
  539.                                                 {
  540.                                                         x=x0;
  541.                                                         y++;
  542.                                                         break;
  543.                                                 }
  544.                                         }
  545.                                 }
  546.                         }
  547.                 }
  548.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  549.         }
  550. }
  551. /******************************************************************************
  552.       函数说明:显示单个32x32汉字
  553.       入口数据:x,y显示坐标
  554.                 *s 要显示的汉字
  555.                 fc 字的颜色
  556.                 bc 字的背景色
  557.                 sizey 字号
  558.                 mode:  0非叠加模式  1叠加模式
  559.       返回值:  无
  560. ******************************************************************************/
  561. void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  562. {
  563.         u8 i,j,m=0;
  564.         u16 k;
  565.         u16 HZnum;//汉字数目
  566.         u16 TypefaceNum;//一个字符所占字节大小
  567.         u16 x0=x;
  568.         TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
  569.         HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);        //统计汉字数目
  570.         for(k=0;k<HZnum;k++)
  571.         {
  572.                 if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1)))
  573.                 {
  574.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  575.                         for(i=0;i<TypefaceNum;i++)
  576.                         {
  577.                                 for(j=0;j<8;j++)
  578.                                 {
  579.                                         if(!mode)//非叠加方式
  580.                                         {
  581.                                                 if(tfont32[k].Msk[i]&(0x01<<j))        LCD_WR_DATA16(fc);
  582.                                                 else LCD_WR_DATA16(bc);
  583.                                                 m++;
  584.                                                 if(m%sizey==0)
  585.                                                 {
  586.                                                         m=0;
  587.                                                         break;
  588.                                                 }
  589.                                         }
  590.                                         else//叠加方式
  591.                                         {
  592.                                                 if(tfont32[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  593.                                                 x++;
  594.                                                 if((x-x0)==sizey)
  595.                                                 {
  596.                                                         x=x0;
  597.                                                         y++;
  598.                                                         break;
  599.                                                 }
  600.                                         }
  601.                                 }
  602.                         }
  603.                 }
  604.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  605.         }
  606. }
  607. /******************************************************************************
  608.       函数说明:显示单个字符
  609.       入口数据:x,y显示坐标
  610.                 num 要显示的字符
  611.                 fc 字的颜色
  612.                 bc 字的背景色
  613.                 sizey 字号
  614.                 mode:  0非叠加模式  1叠加模式
  615.       返回值:  无
  616. ******************************************************************************/
  617. void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
  618. {
  619.         u8 temp,sizex,t,m=0;
  620.         u16 i,TypefaceNum;//一个字符所占字节大小
  621.         u16 x0=x;
  622.         sizex=sizey/2;
  623.         TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
  624.         num=num-' ';    //得到偏移后的值
  625.         LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);  //设置光标位置
  626.         for(i=0;i<TypefaceNum;i++)
  627.         {
  628.                 if(sizey==12)temp=ascii_1206[num][i];                       //调用6x12字体
  629.                 else if(sizey==16)temp=ascii_1608[num][i];                 //调用8x16字体
  630.                 else if(sizey==24)temp=ascii_2412[num][i];                 //调用12x24字体
  631.                 else if(sizey==32)temp=ascii_3216[num][i];                 //调用16x32字体
  632.                 else return;
  633.                 for(t=0;t<8;t++)
  634.                 {
  635.                         if(!mode)//非叠加模式
  636.                         {
  637.                                 if(temp&(0x01<<t))        LCD_WR_DATA16(fc);
  638.                                 else LCD_WR_DATA16(bc);
  639.                                 m++;
  640.                                 if(m%sizex==0)
  641.                                 {
  642.                                         m=0;
  643.                                         break;
  644.                                 }
  645.                         }
  646.                         else//叠加模式
  647.                         {
  648.                                 if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
  649.                                 x++;
  650.                                 if((x-x0)==sizex)
  651.                                 {
  652.                                         x=x0;
  653.                                         y++;
  654.                                         break;
  655.                                 }
  656.                         }
  657.                 }
  658.         }
  659. }
  660. /******************************************************************************
  661.       函数说明:显示汉字串
  662.       入口数据:x,y显示坐标
  663.                 *s 要显示的汉字串
  664.                 fc 字的颜色
  665.                 bc 字的背景色
  666.                 sizey 字号 可选 16 24 32
  667.                 mode:  0非叠加模式  1叠加模式
  668.       返回值:  无
  669. ******************************************************************************/
  670. void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  671. {
  672.         while(*s!=0)
  673.         {
  674.                          if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
  675.                 else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
  676.                 else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
  677.                 else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
  678.                 else return;
  679.                 s+=2;
  680.                 x+=sizey;
  681.         }
  682. }
  683. /******************************************************************************
  684.       函数说明:显示字符串
  685.       入口数据:x,y显示坐标
  686.                 *p 要显示的字符串
  687.                 fc 字的颜色
  688.                 bc 字的背景色
  689.                 sizey 字号
  690.                 mode:  0非叠加模式  1叠加模式
  691.       返回值:  无
  692. ******************************************************************************/
  693. void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
  694. {
  695.         while(*p!='\0')
  696.         {
  697.                 LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
  698.                 x+=sizey/2;
  699.                 p++;
  700.         }
  701. }
  702. /******************************************************************************
  703.       函数说明:显示数字
  704.       入口数据:m底数,n指数
  705.       返回值:  无
  706. ******************************************************************************/
  707. u32 mypow(u8 m,u8 n)
  708. {
  709.         u32 result=1;
  710.         while(n--)result*=m;
  711.         return result;
  712. }
  713. /******************************************************************************
  714.       函数说明:显示整数变量
  715.       入口数据:x,y显示坐标
  716.                 num 要显示整数变量
  717.                 len 要显示的位数
  718.                 fc 字的颜色
  719.                 bc 字的背景色
  720.                 sizey 字号
  721.       返回值:  无
  722. ******************************************************************************/
  723. void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
  724. {
  725.         u8 t,temp;
  726.         u8 enshow=0;
  727.         u8 sizex=sizey/2;
  728.         for(t=0;t<len;t++)
  729.         {
  730.                 temp = (num/mypow(10, (u8)(len-t-1)))%10;
  731.                 if(enshow==0&&t<(len-1))
  732.                 {
  733.                         if(temp==0)
  734.                         {
  735.                                 LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
  736.                                 continue;
  737.                         }else enshow=1;
  738.                 }
  739.                  LCD_ShowChar(x+t*sizex,y, (u8)(temp+48),fc,bc,sizey,0);
  740.         }
  741. }
  742. /******************************************************************************
  743.       函数说明:显示两位小数变量
  744.       入口数据:x,y显示坐标
  745.                 num 要显示小数变量
  746.                 len 要显示的位数
  747.                 fc 字的颜色
  748.                 bc 字的背景色
  749.                 sizey 字号
  750.       返回值:  无
  751. ******************************************************************************/
  752. void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
  753. {
  754.         u8 t,temp,sizex;
  755.         u16 num1;
  756.         sizex=sizey/2;
  757.         num1=num*100;
  758.         for(t=0;t<len;t++)
  759.         {
  760.                 temp=(num1/mypow(10, (u8)(len-t-1)))%10;
  761.                 if(t==(len-2))
  762.                 {
  763.                         LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);
  764.                         t++;
  765.                         len+=1;
  766.                 }
  767.                  LCD_ShowChar(x+t*sizex,y,(u8)(temp+48),fc,bc,sizey,0);
  768.         }
  769. }
  770. /******************************************************************************
  771.       函数说明:显示图片
  772.       入口数据:x,y起点坐标
  773.                 length 图片长度
  774.                 width  图片宽度
  775.                 pic[]  图片数组
  776.       返回值:  无
  777. ******************************************************************************/
  778. void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width, u8 xdata *pic)
  779. {
  780.         LCD_Address_Set(x,y,x+length-1,y+width-1);
  781.         SPI_DMA_TRIG(pic);        //触发SPI DAM发送一个图片
  782.         while(B_SPI_DMA_busy);        //等待图片发送完毕
  783. }
  784. //DMA_SPI_CR         SPI_DMA控制寄存器
  785. #define                DMA_ENSPI                (1<<7)        // SPI DMA功能使能控制位,    bit7, 0:禁止SPI DMA功能,  1:允许SPI DMA功能。
  786. #define                SPI_TRIG_M                (1<<6)        // SPI DMA主机模式触发控制位,bit6, 0:写0无效,          1:写1开始SPI DMA主机模式操作。
  787. #define                SPI_TRIG_S                (0<<5)        // SPI DMA从机模式触发控制位,bit5, 0:写0无效,          1:写1开始SPI DMA从机模式操作。
  788. #define                SPI_CLRFIFO                1                // 清除SPI DMA接收FIFO控制位,bit0, 0:写0无效,          1:写1复位FIFO指针。
  789. //DMA_SPI_CFG         SPI_DMA配置寄存器
  790. #define                DMA_SPIIE        (1<<7)        // SPI DMA中断使能控制位,bit7, 0:禁止SPI DMA中断,     1:允许中断。
  791. #define                SPI_ACT_TX        (1<<6)        // SPI DMA发送数据控制位,bit6, 0:禁止SPI DMA发送数据,主机只发时钟不发数据,从机也不发. 1:允许发送。
  792. #define                SPI_ACT_RX        (0<<5)        // SPI DMA接收数据控制位,bit5, 0:禁止SPI DMA接收数据,主机只发时钟不收数据,从机也不收. 1:允许接收。
  793. #define                DMA_SPIIP        (0<<2)        // SPI DMA中断优先级控制位,bit3~bit2, (最低)0~3(最高).
  794. #define                DMA_SPIPTY        0                // SPI DMA数据总线访问优先级控制位,bit1~bit0, (最低)0~3(最高).
  795. //DMA_SPI_CFG2         SPI_DMA配置寄存器2
  796. #define                SPI_WRPSS        (0<<2)        // SPI DMA过程中使能SS脚控制位,bit2, 0: SPI DMA传输过程不自动控制SS脚。  1:自动拉低SS脚。
  797. #define                SPI_SSS            3                // SPI DMA过程中自动控制SS脚选择位,bit1~bit0, 0: P1.4,  1:P2.4,  2: P4.0,  3:P3.5。
  798. //DMA_SPI_STA         SPI_DMA状态寄存器
  799. #define                SPI_TXOVW        (1<<2)        // SPI DMA数据覆盖标志位,bit2, 软件清0.
  800. #define                SPI_RXLOSS        (1<<1)        // SPI DMA接收数据丢弃标志位,bit1, 软件清0.
  801. #define                DMA_SPIIF        1                // SPI DMA中断请求标志位,bit0, 软件清0.
  802. //HSSPI_CFG  高速SPI配置寄存器
  803. #define                SS_HOLD                (0<<4)        //高速模式时SS控制信号的HOLD时间, 0~15, 默认3. 在DMA中会增加N个系统时钟,当SPI速度为系统时钟/2时执行DMA,SS_HOLD、SS_SETUP和SS_DACT都必须设置大于2的值.
  804. #define                SS_SETUP                3        //高速模式时SS控制信号的SETUP时间,0~15, 默认3. 在DMA中不影响时间,       当SPI速度为系统时钟/2时执行DMA,SS_HOLD、SS_SETUP和SS_DACT都必须设置大于2的值.
  805. //HSSPI_CFG2  高速SPI配置寄存器2
  806. #define                SPI_IOSW        (1<<6)        //bit6:交换MOSI和MISO脚位,0:不交换,1:交换
  807. #define                HSSPIEN                (0<<5)        //bit5:高速SPI使能位,0:关闭高速模式,1:使能高速模式
  808. #define                FIFOEN                (1<<4)        //bit4:高速SPI的FIFO模式使能位,0:关闭FIFO模式,1:使能FIFO模式,使能FIFO模式在DMA中减少13个系统时间。
  809. #define                SS_DACT                        3        //bit3~0:高速模式时SS控制信号的DEACTIVE时间,0~15, 默认3, 不影响DMA时间.  当SPI速度为系统时钟/2时执行DMA,SS_HOLD、SS_SETUP和SS_DACT都必须设置大于2的值.
  810. void        SPI_DMA_TRIG(u8 xdata *TxBuf)
  811. {
  812.                                 //@40MHz, Fosc/4, 200字节258us,100字节  130us,50字节66us,N个字节耗时 N*1.280+2 us, 51T一个字节,其中状态机19T, 传输耗时32T.
  813.                                 //@40MHz, Fosc/2, 200字节177us,100字节 89.5us,50字节46us,N个字节耗时 N*0.875+2 us, 35T一个字节,其中状态机19T, 传输耗时16T.
  814.                                 //@40MHz, Fosc/2, SPI DMA传输一个字节, FIFO=1, HOLD=0,耗时16+3=19T(0.475us), HOLD=3,耗时16+6=22T(0.55us).
  815.                                 //@40MHz, Fosc/4, SPI DMA传输一个字节, FIFO=1, HOLD=0,耗时32+3=35T(0.875us), HOLD=3,耗时32+6=38T(0.95us).
  816.         HSSPI_CFG  = SS_HOLD | SS_SETUP;        //SS_HOLD会增加N个系统时钟, SS_SETUP没有增加时钟。驱动OLED 40MHz时SS_HOLD可以设置为0,
  817.         HSSPI_CFG2 = SPI_IOSW | FIFOEN | SS_DACT;        //FIFOEN允许FIFO会减小13个时钟.
  818.         P_LCD_DC  = 1;        //写数据
  819.         P_LCD_CS  = 0;        //片选
  820.         B_SPI_DMA_busy = 1;        //标志SPI-DMA忙,SPI DMA中断中清除此标志,使用SPI DMA前要确认此标志为0
  821.         SPI_TxAddr   = (u16)TxBuf;                //要发送数据的首地址
  822.         DMA_SPI_TXAH = (u8)(SPI_TxAddr >> 8);                //发送地址寄存器高字节
  823.         DMA_SPI_TXAL = (u8)SPI_TxAddr;                                //发送地址寄存器低字节
  824.         DMA_SPI_AMTH = (u8)((3200-1)/256);                //设置传输总字节数(高8位),        设置传输总字节数 = N+1
  825.         DMA_SPI_AMT  = (u8)(3200-1);                        //设置传输总字节数(低8位).
  826.         DMA_SPI_ITVH = 0;
  827.         DMA_SPI_ITVL = 0;
  828.         DMA_SPI_STA  = 0x00;
  829.         DMA_SPI_CFG  = DMA_SPIIE | SPI_ACT_TX | SPI_ACT_RX | DMA_SPIIP | DMA_SPIPTY;
  830.         DMA_SPI_CFG2 = SPI_WRPSS | SPI_SSS;
  831.         DMA_SPI_CR   = DMA_ENSPI | SPI_TRIG_M | SPI_TRIG_S | SPI_CLRFIFO;        //启动SPI DMA发送命令
  832. }
  833. //========================================================================
  834. // 函数: void SPI_DMA_ISR (void) interrupt DMA_SPI_VECTOR
  835. // 描述:  SPI_DMA中断函数.
  836. // 参数: none.
  837. // 返回: none.
  838. // 版本: V1.0, 2024-1-5
  839. //========================================================================
  840. void SPI_DMA_ISR (void) interrupt DMA_SPI_VECTOR
  841. {
  842.         DMA_SPI_CR = 0;                        //关闭SPI DMA
  843.         B_SPI_DMA_busy = 0;                //清除SPI-DMA忙标志,SPI DMA中断中清除此标志,使用SPI DMA前要确认此标志为0
  844.         SPSTAT = 0x80 + 0x40;        //清0 SPIF和WCOL标志
  845.         HSSPI_CFG2 = SPI_IOSW | SS_DACT;        //使用SPI查询或中断方式时,要禁止FIFO
  846.         P_LCD_CS = 1;
  847.         DMA_SPI_STA = 0;                //清除中断标志
  848. }
  849. void main(void)
  850. {
  851.         u16 i;
  852.         u8        j;
  853.         float t=0;
  854.         EAXFR = 1;        //允许访问扩展寄存器
  855.         WTST  = 0;
  856.         CKCON = 0;
  857.         P0M1 = 0;        P0M0 = 0;        //设置为准双向口
  858.         P1M1 = 0;        P1M0 = 0;        //设置为准双向口
  859.         P2M1 = 0;        P2M0 = 0;        //设置为准双向口
  860.         P3M1 = 0;        P3M0 = 0;        //设置为准双向口
  861.         P4M1 = 0;        P4M0 = 0;        //设置为准双向口
  862.         P5M1 = 0;        P5M0 = 0;        //设置为准双向口
  863.         P6M1 = 0;        P6M0 = 0;        //设置为准双向口
  864.         P7M1 = 0;        P7M0 = 0;        //设置为准双向口
  865.         //==================== SPI初始化 ==================================
  866.         SPI_Config(0, 3);        //(SPI_io, SPI_speed), 参数:         SPI_io: 切换IO(SS MOSI MISO SCLK), 0: 切换到P1.4 P1.5 P1.6 P1.7,  1: 切换到P2.4 P2.5 P2.6 P2.7, 2: 切换到P4.0 P4.1 P4.2 P4.3,  3: 切换到P3.5 P3.4 P3.3 P3.2,
  867.                                                 //                                                                SPI_speed: SPI的速度, 0: fosc/4,  1: fosc/8,  2: fosc/16,  3: fosc/2
  868. //        HSSPI_CFG2 = 0x40;        //交换MOSI MISO, P3.3是MOSI
  869.         P1n_standard(Pin1);                        //SPI引脚设置为准双向口, SPI和控制信号
  870.         PullUpEnable(P1PU, Pin1);        // 允许端口内部上拉电阻     PxPU, 要设置的端口对应位为1
  871.         P3n_standard(0x2c);                        //SPI引脚设置为准双向口, SPI和控制信号
  872.         PullUpEnable(P3PU, 0x2c);        // 允许端口内部上拉电阻     PxPU, 要设置的端口对应位为1
  873.         P4n_standard(Pin7);                        //SPI引脚设置为准双向口, SPI和控制信号
  874.         PullUpEnable(P4PU, Pin7);        // 允许端口内部上拉电阻     PxPU, 要设置的端口对应位为1
  875.         //=================================================================
  876.         LCD_Init(0);//LCD初始化
  877.         LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
  878.         EA = 1;
  879.         while(1)
  880.         {
  881. //                LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
  882.                 LCD_ShowChinese(0,0,"深圳国芯人工智能",RED,WHITE,24,0);
  883. //                LCD_ShowString(0,40,"LCD_W:",RED,WHITE,16,0);
  884. //                LCD_ShowIntNum(48,40,LCD_W,3,RED,WHITE,16);
  885. //                LCD_ShowString(80,40,"LCD_H:",RED,WHITE,16,0);
  886. //                LCD_ShowIntNum(128,40,LCD_H,3,RED,WHITE,16);
  887. //                LCD_ShowString(80,40,"LCD_H:",RED,WHITE,16,0);
  888. //                LCD_ShowString(0,70,"Increaseing Nun:",RED,WHITE,16,0);
  889.                 LCD_ShowFloatNum1(128,70,t,4,RED,WHITE,16);
  890.                 t+=0.11;
  891.                 delay_ms(3000);        // 1~65535 ms
  892. //                for(i=0; i<3200; i++)        DisTmp[i] = Image_1[i];        //将图片装载到显存
  893. //                for(j=0; j<6; j++)                //6行图片, 整屏36个图片 @40MHz FIFOEN=1, SS_HOLD=0时55ms @2T
  894. //                {
  895. //                        for(i=0; i<6; i++)        //一行6个图片
  896. //                        {
  897. //                                LCD_ShowPicture(40*i, j*40, 40, 40, DisTmp);        //触发SPI DMA显示一个图片, 3200字节 1.52ms @40MHz
  898. //                        }
  899. //                }
  900. //                delay_ms(3000);        // 1~65535 ms
  901. //                for(i=0; i<3200; i++)        DisTmp[i] = Image_2[i];        //将图片装载到显存
  902. //                for(j=0; j<6; j++)                //6行图片, 整屏36个图片 @40MHz FIFOEN=1, SS_HOLD=0时55ms @2T
  903. //                {
  904. //                        for(i=0; i<6; i++)        //一行6个图片
  905. //                        {
  906. //                                LCD_ShowPicture(40*i, j*40, 40, 40, DisTmp);        //触发SPI DMA显示一个图片, 3200字节 1.52ms @40MHz
  907. //                        }
  908. //                }
  909. //                delay_ms(3000);
  910.         }
  911. }
复制代码



为什么呢???
君子知命不惑,日日自新。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:52
  • 最近打卡:2025-04-08 20:05:04
已绑定手机

13

主题

79

回帖

438

积分

荣誉版主

积分
438
发表于 2024-12-1 21:08:48 | 显示全部楼层
明天抽空用STM驱动试试,再排除下是不是硬件问题
君子知命不惑,日日自新。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:354
  • 最近打卡:2025-06-28 07:52:44
已绑定手机

4

主题

404

回帖

1963

积分

金牌会员

积分
1963
发表于 2024-12-2 13:41:27 | 显示全部楼层
27276*** 发表于 2024-12-1 21:02
AI8051U可能驱动不了 SPI的4寸ST7796显示屏。

频率搞小点,延时搞长点试试
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:235
  • 最近打卡:2025-05-26 23:18:18

83

主题

695

回帖

1319

积分

金牌会员

积分
1319
发表于 2025-1-11 11:47:49 | 显示全部楼层
楼主你试过楼上这位大佬说的方法了吗? 会不会和频率和延时有关呢?  我之前搞过其他,就在这里出的问题。

点评

我后来用同一套代码(不包括驱动)点亮了st7789 320*240,大佬说的频率和延迟没太搞清楚  详情 回复 发表于 2025-1-13 21:09
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-29 15:59 , Processed in 0.140652 second(s), 100 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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