查看: 559|回复: 1

【LPC845月饼板】+ 修改优化LCD驱动的分享

[复制链接]
  • TA的每日心情
    慵懒
    18 小时前
  • 签到天数: 1941 天

    [LV.Master]伴坛终老

    61

    主题

    1万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    17303
    最后登录
    2024-4-27
    发表于 2023-5-24 10:12:01 | 显示全部楼层 |阅读模式
    本帖最后由 流水源 于 2023-5-24 10:19 编辑

        最近修改了LCD驱动,方便支持可以多屏显示以及坐标支持负坐标,超出显示范围时截取显示部分。
    首先增加了一个屏幕数据结构体
    1. typedef struct lcd_port_t
    2. {
    3.     int16_t     x;
    4.     int16_t     y;
    5.     uint16_t    w;
    6.     uint16_t    h;
    7.     uint8_t     buff[LCD_BUFF_SIZE * 2];
    8.     void ( * draw)(int16_t x1,int16_t y1,int16_t x2,int16_t y2,const uint8_t *pbuff);
    9.     void ( * setwindow)(int16_t x,int16_t y, int16_t width, int16_t height);
    10. }lcd_port_t;
    复制代码
    其中x,y标识这个lcd屏幕在画板上相对的偏移位置坐标,可以正负数据。
    w,h标识这个lcd屏幕可以显示的宽度和高度。这2个值可以<=屏幕实际的宽度和高度。
    buff是lcd绘图的内部缓存。
    draw函数指针代表本LCD的绘图函数。
    setwindow用于设置本LCD的允许显示的x,y相对坐标和w,h显示范围。
    1. //LCD_CNT代表支持的屏幕个数。这里是1个。
    2. lcd_port_t  __spilcd[LCD_CNT] =
    3. {
    4.     {
    5.         .x = 0,
    6.         .y = 0,
    7.         .w = LCD_W,
    8.         .h = LCD_H,
    9.         .draw = lcd_draw_image,
    10.         .setwindow = lcd_set_window,
    11.     },
    12. };
    复制代码

    下面是设置显示范围函数
    1. void lcd_set_window(int16_t x,int16_t y, int16_t width, int16_t height)
    2. {
    3.     __spilcd[0].x = x;
    4.     __spilcd[0].y = y;
    5.     __spilcd[0].w = width;
    6.     __spilcd[0].h = height;
    7. }
    复制代码
    最重要的绘图函数如下,后面所有绘图都基于这个绘图函数。
    1. void lcd_draw_image(int16_t x1,int16_t y1,int16_t x2,int16_t y2,const uint8_t *pbuf)
    2. {
    3.     int16_t i,j;
    4.     int16_t x_s,y_s,x_e, y_e;
    5.     uint8_t *ptr,*p;
    6.    
    7.     if (pbuf == NULL)   return;
    8.     //这里坐标减去屏幕相对坐标就是屏幕映射的显示坐标位置
    9.     x1 -= __spilcd[0].x;
    10.     x2 -= __spilcd[0].x;
    11.     y1 -= __spilcd[0].y;
    12.     y2 -= __spilcd[0].y;
    13.    
    14.     if(x1 >= __spilcd[0].w) return;
    15.     else if(x1 >= 0)    x_s = x1;
    16.     else x_s = 0;
    17.     if(x2 >= __spilcd[0].w)  x_e  = __spilcd[0].w - 1;
    18.     else if(x2 >= 0) x_e = x2;
    19.     else return;
    20.    
    21.     if(y1 >= __spilcd[0].h) return;
    22.     else if(y1 >= 0)    y_s = y1;
    23.     else y_s = 0;
    24.     if(y2 >= __spilcd[0].h)  y_e  = __spilcd[0].h - 1;
    25.     else if(y2 >= 0) y_e = y2;
    26.     else return;

    27.     ptr = (uint8_t *)pbuf + (y_s - y1) * 2 * (x2 - x1 + 1);
    28.     SPILCD_SetRegin(x_s, y_s, x_e, y_e);
    29.     for (i = y_s; i <= y_e; i++)
    30.     {
    31.         ptr += (x_s - x1) * 2;
    32.         p = __spilcd[0].buff;
    33.         for (j = x_s; j <= x_e; j++)
    34.         {
    35.             *p ++ = *ptr++;
    36.             *p ++ = *ptr++;
    37.         }
    38.         ptr += (x2 - x_e) * 2;
    39.         SPILCD_WriteMultiData(__spilcd[0].buff,(p - __spilcd[0].buff));
    40.     }
    41. }
    复制代码
    下面就是基于LCD屏驱动绘图的API
    1. uint8_t lcd_line_buff[LCD_BUFF_SIZE * 2 * 2];   //长边的2倍缓存
    2. void Lcd_DrawImage(int16_t x1,int16_t y1,int16_t x2,int16_t y2,const uint8_t *pbuf)
    3. {
    4.     uint32_t i;
    5.     for(i=0;i<LCD_CNT;i++)
    6.     {
    7.         __spilcd[i].draw(x1,y1,x2,y2,pbuf);
    8.     }
    9. }
    10. void Lcd_DrawPoint(int16_t x,int16_t y,uint16_t color)
    11. {
    12.     lcd_line_buff[0] = color>>8;
    13.     lcd_line_buff[1] = color;
    14.     Lcd_DrawImage(x,y,x,y,lcd_line_buff);
    15. }

    16. void Lcd_DrawCircle(int16_t x0, int16_t y0, uint16_t r,uint16_t color)
    17. {
    18.     int a, b;
    19.     int di;
    20.    
    21.     if(r <= 0)  return;
    22.     else if(r == 1)
    23.     {
    24.         Lcd_DrawPoint(x0, y0, color);
    25.         return;
    26.     }
    27.     a = 0;
    28.     b = r;
    29.     di = 3 - (r << 1);
    30.     while (a <= b)
    31.     {
    32.         Lcd_DrawPoint(x0 - b, y0 - a, color);
    33.         Lcd_DrawPoint(x0 + b, y0 - a, color);
    34.         
    35.         Lcd_DrawPoint(x0 - b, y0 + a, color);
    36.         Lcd_DrawPoint(x0 + b, y0 + a, color);
    37.         
    38.         Lcd_DrawPoint(x0 - a, y0 - b, color);
    39.         Lcd_DrawPoint(x0 + a, y0 - b, color);
    40.         
    41.         Lcd_DrawPoint(x0 - a, y0 + b, color);
    42.         Lcd_DrawPoint(x0 + a, y0 + b, color);
    43.         
    44.         Lcd_DrawPoint(x0 - b, y0 - a, color);
    45.         a++;
    46.         //Bresenham
    47.         if (di < 0)di += 4 * a + 6;
    48.         else
    49.         {
    50.             di += 10 + 4 * (a - b);
    51.             b--;
    52.         }
    53.         Lcd_DrawPoint(x0 + a, y0 + b, color);
    54.     }
    55. }

    56. void Lcd_DrawHLine(int16_t x1, int16_t y1, int16_t x2,uint16_t color)
    57. {
    58.     int16_t i;
    59.     uint8_t *p;

    60.     p = lcd_line_buff;
    61.     for(i=x1;i<=x2;i++)
    62.     {
    63.         *p ++ = color>>8;
    64.         *p ++ = color;
    65.     }
    66.     Lcd_DrawImage(x1,y1,x2,y1,lcd_line_buff);
    67. }

    68. void Lcd_DrawVLine(int16_t x1, int16_t y1, int16_t y2,uint16_t color)
    69. {
    70.     int16_t i;
    71.     uint8_t *p;

    72.     p = lcd_line_buff;
    73.     for(i=y1;i<=y2;i++)
    74.     {
    75.         *p ++ = color>>8;
    76.         *p ++ = color;
    77.     }
    78.     Lcd_DrawImage(x1,y1,x1,y2,lcd_line_buff);
    79. }

    80. void Lcd_DrawRect(int16_t x1,int16_t y1,int16_t x2,int16_t y2,uint16_t color)
    81. {
    82.   Lcd_DrawHLine(x1, y1, x2, color);
    83.   Lcd_DrawHLine(x1, y2, x2, color);
    84.   Lcd_DrawVLine(x1, y1, y2, color);
    85.   Lcd_DrawVLine(x2, y1, y2, color);
    86. }

    87. void Lcd_Fill(int16_t x1,int16_t y1,int16_t x2,int16_t y2, uint16_t color)
    88. {
    89.     int i,j;
    90.     uint8_t *p;
    91.    
    92.     for(j=y1;j<=y2;j++)
    93.     {
    94.         p = lcd_line_buff;
    95.         for(i=x1;i<=x2;i++)
    96.         {
    97.             *p ++ = color>>8;
    98.             *p ++ = color;
    99.         }
    100.         Lcd_DrawImage(x1,j,x2,j,lcd_line_buff);
    101.     }
    102. }

    103. void Lcd_FillCircle(int16_t x0, int16_t y0, uint16_t r,uint16_t color)
    104. {
    105.     int a, b;
    106.     int di;

    107.     if(r <= 0)  return;
    108.     else if(r == 1)
    109.     {
    110.         Lcd_DrawPoint(x0, y0, color);
    111.         return;
    112.     }
    113.     a = 0;
    114.     b = r;
    115.     di = 3 - (r << 1);
    116.     while (a <= b)
    117.     {
    118.         Lcd_DrawHLine(x0 - b, y0 - a, x0 + b, color);
    119.         Lcd_DrawHLine(x0 - a, y0 + b, x0 + a, color);
    120.         Lcd_DrawHLine(x0 - a, y0 - b, x0 + a, color);
    121.         Lcd_DrawHLine(x0 - b, y0 + a, x0 + b, color);
    122.         
    123.         Lcd_DrawPoint(x0 - b, y0 - a, color);
    124.         a++;
    125.         //Bresenham
    126.         if (di < 0)di += 4 * a + 6;
    127.         else
    128.         {
    129.             di += 10 + 4 * (a - b);
    130.             b--;
    131.         }
    132.         Lcd_DrawPoint(x0 + a, y0 + b, color);
    133.     }
    134. }

    135. void Lcd_Clear(uint16_t color)
    136. {
    137.     uint32_t i;
    138.     for(i=0;i<LCD_CNT;i++)
    139.     {
    140.         Lcd_Fill(__spilcd[i].x,__spilcd[i].y,__spilcd[i].w-1,__spilcd[i].h-1,color);
    141.     }
    142. }

    143. //字符点阵绘制
    144. void Lcd_CharDot(int16_t x1, int16_t y1, uint16_t w, uint16_t h,const uint8_t *pbuf,uint16_t f_color,uint16_t b_color)
    145. {
    146.     int16_t i,j;
    147.     uint8_t *p,*ptr;
    148.    
    149.     if((pbuf == NULL)||(w == 0)||(h == 0))  return ;
    150.    
    151.     ptr = (uint8_t *)pbuf;
    152.     for(i=0;i<h;i++)
    153.     {
    154.         p = lcd_line_buff;
    155.         for(j=0;j<w;)
    156.         {
    157.             if(*ptr & (0x80>>(j&0x07)))
    158.             {
    159.                 *p ++ = f_color>>8;
    160.                 *p ++ = f_color;
    161.             }else
    162.             {
    163.                 *p ++ = b_color>>8;
    164.                 *p ++ = b_color;
    165.             }
    166.             j++;
    167.             if(!(j&0x07))
    168.             {
    169.                 ptr++;
    170.             }
    171.         }
    172.         Lcd_DrawImage(x1,y1+i,x1+w-1,y1+i,lcd_line_buff);
    173.     }
    174. }

    175. int32_t Disp0_DrawBitmap(int16_t x,int16_t y, int16_t width, int16_t height, const uint8_t *bitmap)
    176. {
    177.     Lcd_DrawImage(x,y,x+width-1,y+height-1,bitmap);
    178.     return 0;
    179. }
    复制代码


    下面添加shell命令来测试各个API绘图函数:
    1. #include "nr_micro_shell.h"

    2. extern const unsigned char gImage_1[];

    3. /* GLCD RGB color definitions                            */
    4. #define GLCD_COLOR_BLACK        0x0000  /*   0,   0,   0 */
    5. #define GLCD_COLOR_NAVY         0x000F  /*   0,   0, 128 */
    6. #define GLCD_COLOR_DARK_GREEN   0x03E0  /*   0, 128,   0 */
    7. #define GLCD_COLOR_DARK_CYAN    0x03EF  /*   0, 128, 128 */
    8. #define GLCD_COLOR_MAROON       0x7800  /* 128,   0,   0 */
    9. #define GLCD_COLOR_PURPLE       0x780F  /* 128,   0, 128 */
    10. #define GLCD_COLOR_OLIVE        0x7BE0  /* 128, 128,   0 */
    11. #define GLCD_COLOR_LIGHT_GREY   0xC618  /* 192, 192, 192 */
    12. #define GLCD_COLOR_DARK_GREY    0x7BEF  /* 128, 128, 128 */
    13. #define GLCD_COLOR_BLUE         0x001F  /*   0,   0, 255 */
    14. #define GLCD_COLOR_GREEN        0x07E0  /*   0, 255,   0 */
    15. #define GLCD_COLOR_CYAN         0x07FF  /*   0, 255, 255 */
    16. #define GLCD_COLOR_RED          0xF800  /* 255,   0,   0 */
    17. #define GLCD_COLOR_MAGENTA      0xF81F  /* 255,   0, 255 */
    18. #define GLCD_COLOR_YELLOW       0xFFE0  /* 255, 255, 0   */
    19. #define GLCD_COLOR_WHITE        0xFFFF  /* 255, 255, 255 */

    20. static uint16_t g_color_f = GLCD_COLOR_WHITE,g_color_b = GLCD_COLOR_BLACK;
    21. static int16_t g_x=0,g_y=0;

    22. static uint16_t lcd_color_find(char *pstr)
    23. {
    24.     if (!strcmp("black", pstr)) return GLCD_COLOR_BLACK;
    25.     else if (!strcmp("white", pstr)) return GLCD_COLOR_WHITE;
    26.     else if (!strcmp("red", pstr)) return GLCD_COLOR_RED;
    27.     else if (!strcmp("yellow", pstr)) return GLCD_COLOR_YELLOW;
    28.     else if (!strcmp("green", pstr)) return GLCD_COLOR_GREEN;
    29.     else if (!strcmp("blue", pstr)) return GLCD_COLOR_BLUE;
    30.     else if (!strcmp("purple", pstr)) return GLCD_COLOR_PURPLE;
    31.     else if (!strcmp("light", pstr)) return GLCD_COLOR_LIGHT_GREY;
    32.     else if (!strcmp("dark", pstr)) return GLCD_COLOR_DARK_GREY;
    33.     else return atoi(pstr);
    34. }
    35. /**
    36. * @brief test command
    37. */

    38. void shell_lcd(char argc, char *argv)
    39. {
    40.     int color;
    41.     int x1,y1,x2,y2;
    42.     if (argc > 1)
    43.     {
    44.         if (!strcmp("clear", &argv[argv[1]]))
    45.         {
    46.             if(argc == 3)
    47.             {
    48.                 color = lcd_color_find(&argv[argv[2]]);
    49.             }else if(argc == 2)
    50.             {
    51.                 color = g_color_b;
    52.             }else goto lcd_end;
    53.             Lcd_Clear(color);
    54.         }else if (!strcmp("fillrect", &argv[argv[1]]))
    55.         {
    56.             if(argc == 6)
    57.             {
    58.                 color = g_color_f;
    59.             }else if(argc == 7)
    60.             {
    61.                 color = lcd_color_find(&argv[argv[6]]);
    62.             }else goto lcd_end;
    63.             x1 = atoi(&argv[argv[2]]);
    64.             y1 = atoi(&argv[argv[3]]);
    65.             x2 = atoi(&argv[argv[4]]);
    66.             y2 = atoi(&argv[argv[5]]);
    67.             if(x2 && y2)    Lcd_Fill(x1,y1,x1+x2-1,y1+y2-1,color);
    68.             else printf("w h must > 0");
    69.         }else if (!strcmp("fillcircle", &argv[argv[1]]))
    70.         {
    71.             if(argc == 5)
    72.             {
    73.                 color = g_color_f;
    74.             }else if(argc == 6)
    75.             {
    76.                 color = lcd_color_find(&argv[argv[5]]);
    77.             }else goto lcd_end;
    78.             x1 = atoi(&argv[argv[2]]);
    79.             y1 = atoi(&argv[argv[3]]);
    80.             x2 = atoi(&argv[argv[4]]);  //r
    81.             if(x2)  Lcd_FillCircle(x1,y1,x2,color);
    82.             else printf("r must > 0");
    83.         }else if (!strcmp("vline", &argv[argv[1]]))
    84.         {
    85.             if(argc == 5)
    86.             {
    87.                 color = g_color_f;
    88.             }else if(argc == 6)
    89.             {
    90.                 color = lcd_color_find(&argv[argv[5]]);
    91.             }else goto lcd_end;
    92.             x1 = atoi(&argv[argv[2]]);
    93.             y1 = atoi(&argv[argv[3]]);
    94.             y2 = atoi(&argv[argv[4]]);
    95.             if(y2)  Lcd_DrawVLine(x1,y1,y1+y2-1,color);
    96.             else printf("h must > 0");
    97.         }else if (!strcmp("hline", &argv[argv[1]]))
    98.         {
    99.             if(argc == 5)
    100.             {
    101.                 color = g_color_f;
    102.             }else if(argc == 6)
    103.             {
    104.                 color = lcd_color_find(&argv[argv[5]]);
    105.             }else goto lcd_end;
    106.             x1 = atoi(&argv[argv[2]]);
    107.             y1 = atoi(&argv[argv[3]]);
    108.             x2 = atoi(&argv[argv[4]]);
    109.             if(x2)  Lcd_DrawHLine(x1,y1,x1+x2-1,color);
    110.             else printf("w  must > 0");
    111.         }else if (!strcmp("circle", &argv[argv[1]]))
    112.         {
    113.             if(argc == 5)
    114.             {
    115.                 color = g_color_f;
    116.             }else if(argc == 6)
    117.             {
    118.                 color = lcd_color_find(&argv[argv[5]]);
    119.             }else goto lcd_end;
    120.             x1 = atoi(&argv[argv[2]]);
    121.             y1 = atoi(&argv[argv[3]]);
    122.             x2 = atoi(&argv[argv[4]]);  //r
    123.             if(x2)   Lcd_DrawCircle(x1,y1,x2,color);
    124.             else printf("r must > 0");
    125.         }else if (!strcmp("rect", &argv[argv[1]]))
    126.         {
    127.             if(argc == 6)
    128.             {
    129.                 color = g_color_f;
    130.             }else if(argc == 7)
    131.             {
    132.                 color = lcd_color_find(&argv[argv[6]]);
    133.             }else goto lcd_end;
    134.             x1 = atoi(&argv[argv[2]]);
    135.             y1 = atoi(&argv[argv[3]]);
    136.             x2 = atoi(&argv[argv[4]]);
    137.             y2 = atoi(&argv[argv[5]]);
    138.             if(x2 && y2)    Lcd_DrawRect(x1,y1,x1+x2-1,y1+y2-1,color);
    139.             else printf("w h must > 0");
    140.         }else if (!strcmp("point", &argv[argv[1]]))
    141.         {
    142.             if(argc == 4)
    143.             {
    144.                 color = g_color_f;
    145.             }else if(argc == 5)
    146.             {
    147.                 color = lcd_color_find(&argv[argv[4]]);
    148.             }else goto lcd_end;
    149.             x1 = atoi(&argv[argv[2]]);
    150.             y1 = atoi(&argv[argv[3]]);
    151.             Lcd_DrawPoint(x1,y1,color);
    152.         }else if (!strcmp("color", &argv[argv[1]]))
    153.         {
    154.             if(argc == 2)
    155.             {
    156.                 printf("f_color=%04X,b_color=%04X\r\n",g_color_f,g_color_b);
    157.             }else if(argc == 4)
    158.             {
    159.                 g_color_f = lcd_color_find(&argv[argv[2]]);
    160.                 g_color_b = lcd_color_find(&argv[argv[3]]);
    161.             }else goto lcd_end;
    162.         }else if (!strcmp("move", &argv[argv[1]]))
    163.         {
    164.             if(argc == 2)
    165.             {
    166.                 printf("x=%d,y=%d\r\n",g_x,g_y);
    167.             }else if(argc == 4)
    168.             {
    169.                 g_x = atoi(&argv[argv[2]]);
    170.                 g_y = atoi(&argv[argv[3]]);
    171.             }else goto lcd_end;
    172.         }else if (!strcmp("display", &argv[argv[1]]))
    173.         {
    174.             if(argc == 5)
    175.             {
    176.                 x1 = atoi(&argv[argv[2]]);
    177.                 y1 = atoi(&argv[argv[3]]);
    178.                 lcd_disp_str_at(x1,y1,&argv[argv[4]]);
    179.             }else goto lcd_end;
    180.         }else if (!strcmp("image", &argv[argv[1]]))
    181.         {
    182.             if(argc == 2)
    183.             {
    184.                 Lcd_DrawImage(g_x,g_y,g_x+39,g_y+39,(uint8_t *)gImage_1);
    185.             }else if(argc == 4)
    186.             {
    187.                 x1 = atoi(&argv[argv[2]]);
    188.                 y1 = atoi(&argv[argv[3]]);
    189.                 Lcd_DrawImage(x1,y1,x1+39,y1+39,(uint8_t *)gImage_1);
    190.             }else goto lcd_end;
    191.         }else goto lcd_end;
    192.     }else goto lcd_end;
    193.     return;
    194. lcd_end:
    195.     printf("usage: lcd  \r\n");
    196.     printf("lcd clear                    [color]\r\n");
    197.     printf("lcd fillrect     x1 y1 w  h  [color]\r\n");
    198.     printf("lcd fillcircle   x1 y1 r     [color]\r\n");
    199.     printf("lcd hline        x1 y1 w     [color]\r\n");
    200.     printf("lcd vline        x1 y1    h  [color]\r\n");
    201.     printf("lcd circle       x1 y1 r     [color]\r\n");
    202.     printf("lcd rect         x1 y1 w  h  [color]\r\n");
    203.     printf("lcd point        x1 y1       [color]\r\n");
    204.     printf("lcd display      x  y    string   \r\n");
    205.     printf("lcd move         x  y             \r\n");
    206.     printf("lcd image        x  y             \r\n");
    207.     printf("lcd color        f_color  b_color \r\n");
    208. }
    209. NR_SHELL_CMD_EXPORT(lcd, shell_lcd, "lcd display test");

    复制代码
    a4.jpg
    a5.jpg
    11.jpg
    a6.jpg


    lpc845_mooncake.zip (5.9 MB, 下载次数: 1, 售价: 1 NXP金币)
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3300

    主题

    6547

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32034
    最后登录
    2024-4-26
    发表于 2023-5-24 11:15:48 | 显示全部楼层
    赞一个
    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-27 19:02 , Processed in 0.133401 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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