找回密码
 立即注册
查看: 54|回复: 2

用AI8051,直接驱动480*272分辨率,RGB接口屏,

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:386
  • 最近打卡:2025-10-15 10:19:23

7

主题

25

回帖

1425

积分

金牌会员

积分
1425
发表于 2025-9-27 23:20:48 | 显示全部楼层 |阅读模式
屏幕是标准40pin的RGB接口屏,频率22.1184Mhz,用DE模式驱动,本来单纯想学学这种屏幕的时序,没想到显示个汉字啥的,还能接受,因为是用24位RGB,所以用的32bit模式,8位対long的兼容不好,程序写的不好,希望大家指正。
为了显示汉字,数字之类的,实在不知道怎么写这个函数,因为每次都要全屏刷新像素,就用了最粗暴的方式,建立整屏缓存,然后把需要显示的汉字或者数字数组,替换掉全屏缓存内对应的字节。

  1. #include <AI8051U.H>
  2. #include "intrins.h"
  3. // 引脚定义
  4. sbit CLK   = P5^7;
  5. sbit DE    = P4^0;
  6. //sbit DISP  = P1^5;
  7. sbit LED    = P5^6;
  8. #define port_r   P1
  9. #define port_g   P0
  10. #define port_b   P2
  11. // 屏幕参数
  12. #define H_ACTIVE      480     // 水平有效像素
  13. #define V_ACTIVE      272     // 垂直有效行数
  14. #define H_BLANK       45      // 水平消隐期(前廊+同步+后廊)
  15. #define V_BLANK       14      // 垂直消隐期(前廊+同步+后廊)
  16. #define H_TOTAL (H_ACTIVE + H_BLANK)
  17. #define V_TOTAL (V_ACTIVE + V_BLANK)
  18. #define FOSC               22118400UL
  19. #define BRT         (65536 - FOSC / 115200 / 4)
  20. #define bai                 0xffffff
  21. #define hong                 0xff0000
  22. #define lv                        0x00ff00
  23. #define huang                 0xffff00
  24. #define hei                 0x000000
  25. #define qianhuang         0xffffbe
  26. #define lan                 0x0000ff
  27. unsigned char xdata full[16320]={0};
  28. unsigned char xdata shan[128]={
  29. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x10,0x18,0x00, /* 0 */
  30.        0x0f,0xf8,0x18,0x00,0x0c,0x30,0x18,0x00,0x0c,0x20,0x18,0x60,0x0c,0x67,0xff,0xf0,
  31.        0x0c,0x40,0x18,0x00,0x04,0x40,0x18,0x00,0x04,0x82,0x18,0xc0,0x04,0x83,0x10,0xc0,
  32.        0x04,0x83,0x10,0x80,0x04,0x41,0x91,0x00,0x04,0x21,0x91,0x00,0x04,0x11,0x12,0x00,
  33.        0x04,0x10,0x10,0x10,0x04,0x1f,0xff,0xf8,0x04,0x18,0x34,0x00,0x04,0x18,0x34,0x00,
  34.        0x07,0xf0,0x24,0x00,0x04,0xe0,0x62,0x00,0x0c,0x00,0x43,0x00,0x0c,0x00,0xc1,0x00,
  35.        0x0c,0x01,0x81,0xc0,0x0c,0x03,0x00,0xe0,0x0c,0x06,0x00,0x78,0x0c,0x18,0x00,0x30,
  36.        0x08,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  37. };
  38. unsigned char xdata xi[128]={
  39. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, /* 1 */
  40.        0x1f,0xff,0xff,0xf0,0x00,0x0c,0x30,0x00,0x00,0x0c,0x30,0x00,0x00,0x0c,0x30,0x00,
  41.        0x00,0x0c,0x30,0x00,0x04,0x0c,0x30,0x40,0x07,0xff,0xff,0xf0,0x06,0x0c,0x30,0x60,
  42.        0x06,0x0c,0x30,0x60,0x06,0x0c,0x30,0x60,0x06,0x0c,0x30,0x60,0x06,0x08,0x30,0x60,
  43.        0x06,0x08,0x30,0x60,0x06,0x18,0x30,0x60,0x06,0x10,0x31,0x60,0x06,0x30,0x1f,0xe0,
  44.        0x06,0x20,0x00,0x60,0x06,0x40,0x00,0x60,0x06,0x80,0x00,0x60,0x06,0x00,0x00,0x60,
  45.        0x07,0xff,0xff,0xe0,0x06,0x00,0x00,0x60,0x06,0x00,0x00,0x60,0x04,0x00,0x00,0x00,
  46.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  47. };
  48. unsigned char xdata sheng[128]={
  49. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x80,0x00, /* 2 */
  50.        0x00,0x41,0x00,0x00,0x00,0x71,0x03,0x80,0x00,0xc1,0x00,0xc0,0x01,0x81,0x0c,0x70,
  51.        0x01,0x81,0x1c,0x30,0x03,0x01,0x30,0x30,0x06,0x02,0xe0,0x10,0x08,0x01,0xc0,0x00,
  52.        0x10,0x03,0x00,0x00,0x00,0x0e,0x01,0x00,0x00,0x3f,0xff,0x80,0x00,0x70,0x03,0x00,
  53.        0x00,0xe0,0x03,0x00,0x07,0x20,0x03,0x00,0x08,0x3f,0xff,0x00,0x00,0x20,0x03,0x00,
  54.        0x00,0x20,0x03,0x00,0x00,0x20,0x03,0x00,0x00,0x3f,0xff,0x00,0x00,0x20,0x03,0x00,
  55.        0x00,0x20,0x03,0x00,0x00,0x3f,0xff,0x00,0x00,0x20,0x03,0x00,0x00,0x20,0x03,0x00,
  56.        0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  57. };
  58. unsigned char xdata shuzi1632[] =
  59. {
  60. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xc0,0x0e,0x60,0x1c,0x70, /* 0 */
  61.        0x38,0x38,0x38,0x38,0x38,0x18,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,
  62.        0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x30,0x18,0x38,0x38,0x38,0x38,0x1c,0x70,
  63.        0x0e,0x60,0x07,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  64. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xc0,0x0f,0xc0, /* 1 */
  65.        0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
  66.        0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
  67.        0x01,0xe0,0x0f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  68. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x0c,0x78,0x18,0x38, /* 2 */
  69.        0x30,0x1c,0x30,0x1c,0x38,0x1c,0x38,0x1c,0x00,0x1c,0x00,0x38,0x00,0x30,0x00,0x70,
  70.        0x00,0xe0,0x01,0xc0,0x03,0x80,0x07,0x00,0x0e,0x00,0x0c,0x0c,0x18,0x0c,0x30,0x1c,
  71.        0x3f,0xfc,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  72. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x18,0xf0,0x38,0x70, /* 3 */
  73.        0x38,0x38,0x38,0x38,0x38,0x38,0x00,0x38,0x00,0x70,0x00,0xe0,0x03,0xc0,0x00,0x70,
  74.        0x00,0x38,0x00,0x18,0x00,0x1c,0x00,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x38,
  75.        0x18,0x70,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  76. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0xf0, /* 4 */
  77.        0x00,0xf0,0x01,0xf0,0x03,0x70,0x03,0x70,0x06,0x70,0x0e,0x70,0x0c,0x70,0x18,0x70,
  78.        0x18,0x70,0x30,0x70,0x60,0x70,0x7f,0xfe,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,
  79.        0x00,0x70,0x03,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  80. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x1f,0xfc,0x18,0x00, /* 5 */
  81.        0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x1b,0xe0,0x1e,0x78,0x1c,0x38,
  82.        0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x38,0x1c,0x38,0x1c,0x30,0x38,0x30,0x38,
  83.        0x1c,0x70,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  84. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xe0,0x0e,0x38,0x1c,0x38, /* 6 */
  85.        0x18,0x38,0x38,0x00,0x30,0x00,0x30,0x00,0x70,0x00,0x77,0xe0,0x7e,0x70,0x78,0x38,
  86.        0x78,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x38,0x1c,0x38,0x18,0x1c,0x38,
  87.        0x1e,0x70,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  88. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xfc,0x1f,0xfc,0x38,0x18, /* 7 */
  89.        0x30,0x30,0x30,0x30,0x00,0x60,0x00,0x60,0x00,0xc0,0x00,0xc0,0x01,0x80,0x01,0x80,
  90.        0x01,0x80,0x03,0x00,0x03,0x00,0x03,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
  91.        0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  92. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x1c,0x70,0x38,0x38, /* 8 */
  93.        0x70,0x1c,0x70,0x1c,0x70,0x1c,0x78,0x1c,0x3c,0x38,0x1e,0x30,0x0f,0xe0,0x0f,0xe0,
  94.        0x18,0xf0,0x38,0x78,0x70,0x3c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x38,0x38,
  95.        0x1c,0x70,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  96. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x1c,0x70,0x38,0x30, /* 9 */
  97.        0x38,0x38,0x70,0x18,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x1c,0x70,0x3c,0x38,0x3c,
  98.        0x3c,0xfc,0x0f,0xdc,0x00,0x1c,0x00,0x38,0x00,0x38,0x00,0x38,0x38,0x70,0x38,0x70,
  99.        0x38,0xe0,0x1f,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  100. };
  101. void Delayms(unsigned int x)        //@22.1184MHz
  102. {
  103.         unsigned long edata i;
  104.         while(x--)
  105.         {
  106.         _nop_();
  107.         i = 5528UL;
  108.         while (i) i--;
  109.         }
  110. }
  111. void UartInit()                //定时器1(模式0)做串口1波特率发生器
  112. {
  113.         SCON = 0x50;                //8位数据,可变波特率
  114.         AUXR |= 0x40;                //定时器时钟1T模式
  115.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  116.         TMOD &= 0x0F;                //设置定时器模式
  117.         TL1 =  BRT;                        //设置定时初始值
  118.         TH1 = BRT >> 8;                        //设置定时初始值
  119.         ET1 = 0;                        //禁止定时器中断
  120.         TR1 = 1;                        //定时器1开始计时
  121.     ES = 1;        //打开串口中断
  122.     EA = 1;        //打开总中断
  123. }
  124. void UartSend(unsigned char dat)        //单片机发送一个字节
  125. {
  126.     SBUF = dat;
  127.         while(TI==0);
  128.         TI=0;
  129. }
  130. void CheckCustomCmd(unsigned char dat)                   //检测命令序列:"@STCISP#"
  131. {
  132.         unsigned char bStage;
  133.         
  134.     switch (bStage++)
  135.     {
  136.     default:
  137.         L_Check1st:
  138.     case 0:                                     //检测命令头
  139.         bStage = (dat == '@');
  140.         break;
  141.     case 1:
  142.         if (dat != 'S') goto L_Check1st;
  143.         break;
  144.     case 2:
  145.         if (dat != 'T') goto L_Check1st;
  146.         break;
  147.     case 3:
  148.         if (dat != 'C') goto L_Check1st;
  149.         break;
  150.     case 4:
  151.         if (dat != 'I') goto L_Check1st;
  152.         break;
  153.     case 5:
  154.         if (dat != 'S') goto L_Check1st;
  155.         break;
  156.     case 6:
  157.         if (dat != 'P') goto L_Check1st;
  158.         break;
  159.     case 7:
  160.         if (dat != '#') goto L_Check1st;
  161.         Delayms(5);                           //检测到正确的命令序列后复位到系统区,此处的延时可省去
  162.         IAP_CONTR = 0x60;                       //复位到系统区
  163.         break;
  164.     }
  165. }
  166. void UartSendStr(unsigned char *p)//单片机发送字符串
  167. {
  168.     while (*p)
  169.     {
  170.         UartSend(*p++);
  171.     }
  172. }
  173. void Delayus(unsigned int x)        //@20.000MHz
  174. {
  175.         unsigned long edata i;
  176.         while(x--)
  177. {
  178.         _nop_();
  179.         _nop_();
  180.         _nop_();
  181.         i = 3UL;
  182.         while (i) i--;
  183. }
  184. }
  185. void Full_RGB_Display(unsigned long color)
  186. {
  187.     unsigned int line, pixel;
  188.         for(line = 0; line < V_ACTIVE; line++)            // 逐行显示        272
  189.         {
  190.             DE = 1;  // 行有效期开始
  191.             
  192.             for(pixel = 0; pixel < H_ACTIVE; pixel++)            // 生成一行像素时钟        480
  193.             {
  194. //                                Delayus(100);
  195.                                 port_r=color>>16;
  196.                                 port_g=color>>8;
  197.                                 port_b=color;
  198.                 CLK = 1;
  199.                 CLK = 0;
  200.             }
  201.             
  202.             DE = 0;  // 行有效期结束
  203.             
  204.            
  205.             for(pixel = 0; pixel < H_BLANK; pixel++) // 行消隐期
  206.             {
  207.                 CLK = 1;
  208.                 CLK = 0;
  209.             }
  210.         }
  211.         
  212.         // 帧消隐期
  213.         for(line = 0; line < V_BLANK; line++)
  214.         {
  215.             for(pixel = 0; pixel < H_TOTAL; pixel++)
  216.             {
  217.                 CLK = 1;
  218.                 CLK = 0;
  219.             }
  220.         }
  221. }
  222. void Simple_RGB_Display(unsigned long x,unsigned long y)        //竖向条文
  223. {
  224.     unsigned int line, pixel;
  225.         unsigned char i;
  226.         for(line = 0; line < V_ACTIVE; line++)            // 逐行显示        272
  227.         {
  228.             DE = 1;  // 行有效期开始
  229.             
  230.             for(pixel = 0; pixel < 10; pixel++)            // 生成一行像素时钟        480
  231.             {
  232.                                 for(i = 0; i < 24; i++)
  233.                                 {
  234.                                 port_r=x>>16;
  235.                                 port_g=x>>8;
  236.                                 port_b=x;
  237.                 CLK = 1;
  238.                 CLK = 0;
  239.                                 }
  240.                                 for(i = 0; i < 24; i++)
  241.                                 {
  242.                                 port_r=y>>16;
  243.                                 port_g=y>>8;
  244.                                 port_b=y;
  245.                 CLK = 1;
  246.                 CLK = 0;
  247.                                 }
  248.             }
  249.             
  250.             DE = 0;  // 行有效期结束
  251.             
  252.            
  253.             for(pixel = 0; pixel < H_BLANK; pixel++) // 行消隐期
  254.             {
  255.                 CLK = 1;
  256.                 CLK = 0;
  257.             }
  258.         }
  259.         
  260.         // 帧消隐期
  261.         for(line = 0; line < V_BLANK; line++)
  262.         {
  263.             for(pixel = 0; pixel < H_TOTAL; pixel++)
  264.             {
  265.                 CLK = 1;
  266.                 CLK = 0;
  267.             }
  268.         }
  269. }
  270. void pic480272(unsigned long x,unsigned long y)        //图片
  271. {
  272.     unsigned int line, pixel;
  273.         unsigned char a,b,i;
  274.         for(line = 0; line < V_ACTIVE; line++)            // 逐行显示        272
  275.         {
  276.             DE = 1;  // 行有效期开始
  277.             
  278.             for(pixel = 0; pixel < 60; pixel++)            // 生成一行像素时钟        480
  279.             {
  280.                                 a=full[pixel+(long)(60*line)];
  281.                                 for(i=0;i<8;i++)
  282.                                 {
  283.                                         b=a&0x80;
  284.                                         if(b==0)
  285.                                         {
  286.                                         port_r=y>>16;
  287.                                         port_g=y>>8;
  288.                                         port_b=y;
  289.                                         CLK = 1;
  290.                                         CLK = 0;
  291.                                         }
  292.                                         else
  293.                                         {
  294.                                         port_r=x>>16;
  295.                                         port_g=x>>8;
  296.                                         port_b=x;
  297.                                         CLK = 1;
  298.                                         CLK = 0;
  299.                                         }
  300.                                 a=a<<1;
  301.                                 }
  302.             }
  303.             
  304.             DE = 0;  // 行有效期结束
  305.             
  306.            
  307.             for(pixel = 0; pixel < H_BLANK; pixel++) // 行消隐期
  308.             {
  309.                 CLK = 1;
  310.                 CLK = 0;
  311.             }
  312.         }
  313.         
  314.         // 帧消隐期
  315.         for(line = 0; line < V_BLANK; line++)
  316.         {
  317.             for(pixel = 0; pixel < H_TOTAL; pixel++)
  318.             {
  319.                 CLK = 1;
  320.                 CLK = 0;
  321.             }
  322.         }
  323. }
  324. //void display_3232 (unsigned char x,unsigned char y,unsigned char *p,unsigned long bfcolor, unsigned long bhcolor)        //x的范围0-272   y的范围0-60
  325. void display_3232 (unsigned char y,unsigned char x,unsigned char *p)
  326. {
  327.         unsigned char i,j;
  328.         for(i=0;i<32;i++)                //一行480/8个字节
  329.         {
  330.                 for(j=0;j<4;j++)        //32*32汉字,汉字一行32/4个字节
  331.                 {
  332.                         full[(y*60+x)+(j+i*60)]=p[j+i*4];
  333.                 }
  334.         
  335.         }
  336. //        pic480272(bfcolor,bhcolor);
  337. }
  338. void displayNum_1632 (unsigned char y,unsigned char x,unsigned char a)
  339. {
  340.         unsigned char i,j;
  341.         unsigned char num;
  342.         num=a/100;
  343.         for(i=0;i<32;i++)                //一行480/8个字节
  344.         {
  345.                 for(j=0;j<2;j++)        //16*32数字,数字一行16/8  2个字节
  346.                 {
  347.                         full[(y*60+x)+(j+i*60)]=shuzi1632[64*num+j+i*2];
  348.                 }
  349.         }
  350.         x=x+2;
  351.         num=(a % 100) / 10;
  352.         for(i=0;i<32;i++)                //一行480/8个字节
  353.         {
  354.                 for(j=0;j<2;j++)        //16*32数字,数字一行16/8  2个字节
  355.                 {
  356.                         full[(y*60+x)+(j+i*60)]=shuzi1632[64*num+j+i*2];
  357.                 }
  358.         }
  359.         x=x+2;
  360.         num=a%10;
  361.         for(i=0;i<32;i++)                //一行480/8个字节
  362.         {
  363.                 for(j=0;j<2;j++)        //16*32数字,数字一行16/8  2个字节
  364.                 {
  365.                         full[(y*60+x)+(j+i*60)]=shuzi1632[64*num+j+i*2];
  366.                 }
  367.         }
  368. //        pic480272(bfcolor,bhcolor);
  369. }
  370. // 主函数
  371. void main(void)
  372. {
  373.         unsigned char a;
  374.     // P0P1P2口推挽输出
  375.     P0M0 = 0xff;         //不推挽输出也行
  376.         P0M1 = 0x00;
  377.     P1M0 = 0xff;
  378.     P1M1 = 0x00;
  379.     P2M0 = 0xff;
  380.         P2M1 = 0x00;
  381.     P3M0 = 0x00;
  382.         P3M1 = 0xc0;
  383.     P4M0 = 0x00;
  384.         P4M1 = 0x00;
  385.     P5M0 = 0x00;
  386.         P5M1 = 0x00;
  387.         UartInit();
  388.         Delayms(5);
  389. //    DISP = 1;  // 打开显示  直接接3.3v的时候,可以不要这句
  390.    
  391.     while(1)
  392.     {
  393.         // 主循环空闲,所有工作由中断处理
  394.         // 可以在这里添加其他功能
  395. Full_RGB_Display(hong);
  396.         Delayms(300);                //整屏显示后,大概可以维持800ms,等待时间再长图像就失真了
  397. Full_RGB_Display(huang);        //刷一次屏大概170ms
  398.         Delayms(300);
  399. Full_RGB_Display(lan);
  400.         Delayms(300);
  401. for(a=0;a<25;a++)
  402. {
  403.         display_3232 (10,10,shan);        
  404.         display_3232 (10,10+4,xi);
  405.         display_3232 (10,10+4+4,sheng);
  406.         displayNum_1632(10,10+4+4+4,a);
  407.         pic480272(huang,hei);
  408. }
  409.         
  410.         LED=~LED;
  411.     }
  412. }
  413. void UartIsr() interrupt 4        //串口1中断函数
  414. {
  415. //        unsigned char i=0;
  416.     if (RI)        //接收
  417.     {
  418.         RI = 0;
  419.         CheckCustomCmd(SBUF);        //检测串口为指定命令函数
  420.     }
  421.         
  422. //    if (TI)
  423. //    {
  424. //        TI = 0;
  425. //    }        
  426.         
  427. }
复制代码
现在有个问题:为啥22MHz左右的频率可以正常显示,30Mhz以上频率就花屏,感觉clk翻转是不是太快了,我在clk=1和clk=0中加入延时,还是不行。


回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-9-27 23:23:00 | 显示全部楼层
你这段代码和描述已经非常贴近底层驱动开发了,尤其是在使用国产AI8051芯片(可能是基于增强型8051内核的国产MCU)直接驱动RGB接口的480x272分辨率液晶屏,这种做法在资源受限的MCU平台上具有一定的挑战性。以下是对你的代码和开发思路的专业性分析与优化建议。

一、整体架构分析

你使用的是DE模式驱动RGB接口的TFT液晶屏,这是一种较为常见的驱动方式,适用于没有VSYNC/HSYNC信号的液晶屏,通过DE(Data Enable)信号来判断当前是否处于有效显示区域。

你定义了以下关键参数:
水平分辨率:480
垂直分辨率:272
水平总周期:HACTIVE + HBLANK = 480 + 45 = 525
垂直总周期:VACTIVE + VBLANK = 272 + 14 = 286
主频:22.1184 MHz
RGB接口为24位,使用32位模式兼容

你采用的是一种全屏缓存+像素级替换的方式进行字符显示,这在资源有限的8位MCU上是一种比较常见但效率较低的方式,适用于静态或低帧率显示。

二、关于RGB接口与8051的适配问题

你提到“8位对long的兼容不好”,这可能是指你在进行像素数据拼接时,使用的是unsigned long类型来表示RGB数据(例如RGB888),但在8位MCU上操作32位数据效率较低,容易造成性能瓶颈。

建议:
使用结构体或联合体来处理RGB数据,提高可读性和可移植性;
避免频繁的32位运算,可以将RGB颜色值预处理为数组或常量;
若使用的是RGB565格式(16位),可考虑将颜色数据压缩为16位,降低内存和带宽压力。

三、关于全屏缓存与字符显示的优化

你提到“建立整屏缓存,替换对应字节”的方式,这种方式虽然简单直接,但在8位MCU上会带来以下问题:

1. 内存占用大:480x272x3 = 391,680字节(RGB888),对于片内RAM有限的MCU来说,必须使用外部SRAM或显存;
2. 刷新效率低:每次刷新都要遍历整个缓存,效率低下;
3. 字体渲染方式原始:缺乏字体缓存、区域更新等机制。

建议优化方案:

1. 使用帧缓存压缩(如RGB565)
RGB565格式占用内存为480x272x2 = 261,120字节,节省约1/3内存;
可以通过宏定义或函数实现RGB888到RGB565的转换。

2. 实现字符绘制函数
你提到“不知道怎么写这个函数”,其实可以按如下方式实现一个简单的字符绘制函数:

```c
void DrawChar(int x, int y, char c, unsigned short color) {
    const unsigned char font = GetFont(c); // 获取字符点阵数据
    for (int row = 0; row < FONTHEIGHT; row++) {
        for (int col = 0; col < FONTWIDTH; col++) {
            if (font[row] & (1

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:386
  • 最近打卡:2025-10-15 10:19:23

7

主题

25

回帖

1425

积分

金牌会员

积分
1425
发表于 2025-9-27 23:34:35 | 显示全部楼层
第一次传视频,为啥我传的视频这么大
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-10-16 05:38 , Processed in 0.446808 second(s), 58 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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