[AT32M412] 【AT-START-M412测评】+ ②驱动LCD彩屏

[复制链接]
 楼主| 发表于 2025-6-16 19:30 | 显示全部楼层 |阅读模式
本帖最后由 yinwuqing110 于 2025-6-16 20:45 编辑

       本次使用AT-START-M412驱动1.77寸TFT-LCD屏,该屏驱动芯片ST7735S,购买链接:AFL128160A0-1.77N12NTM-ANO,屏的点像素为128x160,通讯接口SPI,为方便移植,这里驱动采用GPIO口模拟SPI通讯方式。LCD屏的规格书如下附件:
AFL128160A0-1.77N12NTM-ANO.pdf (416.33 KB, 下载次数: 0)
        AT-START-M412开发板与ST7735S屏硬件接口连线:
硬件对应接口.png
         接下来移植相关驱动源码,代码展示如下。
lcd_st7735.c与lcd_st7735.h文件
  1. #include "lcd_st7735.h"
  2. #include "at32m412_416_board.h"
  3. #include "at32m412_416_conf.h"
  4. #include  "lcdfont.h"
  5. #include  "pics.h"

  6. #define SOFTWARE_SPI_ENABLE   1
  7. /*
  8.         AT32M412      LCD屏
  9.         GND              GND
  10.         3.3V              VCC
  11.         PA0               RES(复位)
  12.         PA1               DC(命令数据选择)
  13.         PA2               CS(片选)               
  14.         PA3               SCLK
  15.         PA4               MOSI
  16.         PA5               BL(背光)
  17. */
  18. #define TFT_RST_GPIO_PORT     GPIOA
  19. #define TFT_RST_PIN           GPIO_PINS_0
  20. #define TFT_DC_GPIO_PORT      GPIOA
  21. #define TFT_DC_PIN            GPIO_PINS_1
  22. #define TFT_CS_GPIO_PORT      GPIOA
  23. #define TFT_CS_PIN            GPIO_PINS_2
  24. #define TFT_SCLK_GPIO_PORT    GPIOA
  25. #define TFT_SCLK_PIN          GPIO_PINS_3
  26. #define TFT_MOSI_GPIO_PORT    GPIOA
  27. #define TFT_MOSI_PIN          GPIO_PINS_4
  28. #define TFT_BLK_GPIO_PORT     GPIOA
  29. #define TFT_BLK_PIN           GPIO_PINS_5
  30.         
  31. #define LCD_RES_LOW()   gpio_bits_reset(TFT_RST_GPIO_PORT, TFT_RST_PIN)//RES
  32. #define LCD_RES_HIGH()  gpio_bits_set(TFT_RST_GPIO_PORT, TFT_RST_PIN)

  33. #define LCD_DC_LOW()    gpio_bits_reset(TFT_DC_GPIO_PORT, TFT_DC_PIN) //DC
  34. #define LCD_DC_HIGH()   gpio_bits_set(TFT_DC_GPIO_PORT, TFT_DC_PIN)

  35. #define LCD_CS_LOW()    gpio_bits_reset(TFT_CS_GPIO_PORT, TFT_CS_PIN) //CS
  36. #define LCD_CS_HIGH()   gpio_bits_set(TFT_CS_GPIO_PORT, TFT_CS_PIN)
  37.                      
  38. #define LCD_BLK_LOW()   gpio_bits_reset(TFT_BLK_GPIO_PORT, TFT_BLK_PIN) //BLK
  39. #define LCD_BLK_HIGH()  gpio_bits_set(TFT_BLK_GPIO_PORT, TFT_BLK_PIN)

  40. #if SOFTWARE_SPI_ENABLE
  41. #define LCD_SCLK_LOW()  gpio_bits_reset(TFT_SCLK_GPIO_PORT, TFT_SCLK_PIN) //SCLK
  42. #define LCD_SCLK_HIGH() gpio_bits_set(TFT_SCLK_GPIO_PORT, TFT_SCLK_PIN)

  43. #define LCD_MOSI_LOW()  gpio_bits_reset(TFT_MOSI_GPIO_PORT, TFT_MOSI_PIN) //MOSI
  44. #define LCD_MOSI_HIGH() gpio_bits_set(TFT_MOSI_GPIO_PORT, TFT_MOSI_PIN)
  45. #endif

  46. #define USE_HORIZONTAL 1  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏
  47. #if USE_HORIZONTAL==0||USE_HORIZONTAL==1
  48.         #define LCD_W 128  
  49.         #define LCD_H 160  
  50. #else
  51.         #define LCD_W 160
  52.         #define LCD_H 128
  53. #endif

  54. void LcdIoInit(void)
  55. {
  56.         gpio_init_type gpio_init_struct;
  57.         crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  58.         
  59.         gpio_init_struct.gpio_pins   = TFT_BLK_PIN;
  60.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  61.         gpio_init_struct.gpio_mode  = GPIO_MODE_OUTPUT;
  62.         gpio_init(GPIOA, &gpio_init_struct);
  63.         
  64.         gpio_init_struct.gpio_pins   = TFT_RST_PIN;
  65.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  66.         gpio_init_struct.gpio_mode  = GPIO_MODE_OUTPUT;
  67.         gpio_init(GPIOA, &gpio_init_struct);
  68.         
  69.         gpio_init_struct.gpio_pins   = TFT_DC_PIN;
  70.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  71.         gpio_init_struct.gpio_mode  = GPIO_MODE_OUTPUT;
  72.         gpio_init(GPIOA, &gpio_init_struct);
  73.         
  74.         gpio_init_struct.gpio_pins   = TFT_CS_PIN;
  75.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  76.         gpio_init_struct.gpio_mode  = GPIO_MODE_OUTPUT;
  77.         gpio_init(GPIOA, &gpio_init_struct);
  78.          
  79.         gpio_init_struct.gpio_pins   = TFT_SCLK_PIN;
  80.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  81.         gpio_init_struct.gpio_mode  = GPIO_MODE_OUTPUT;
  82.         gpio_init(GPIOA, &gpio_init_struct);
  83.          
  84.         gpio_init_struct.gpio_pins   = TFT_MOSI_PIN;
  85.         gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  86.         gpio_init_struct.gpio_mode  = GPIO_MODE_OUTPUT;
  87.         gpio_init(GPIOA, &gpio_init_struct);
  88. }

  89. /******************************************************************************
  90. 函数说明:LCD串行数据写入函数
  91. 入口数据:dat  要写入的串行数据
  92. 返回值:  无
  93. ******************************************************************************/
  94. void LCD_Writ_Bus(uint8_t dat)
  95. {        
  96.         uint8_t i;
  97.         
  98.         LCD_CS_LOW();
  99. #if SOFTWARE_SPI_ENABLE        
  100.         for(i=0;i<8;i++)
  101.         {                          
  102.                 LCD_SCLK_LOW();
  103.                 if(dat&0x80)
  104.                 {
  105.                    LCD_MOSI_HIGH();
  106.                 }
  107.                 else
  108.                 {
  109.                    LCD_MOSI_LOW();
  110.                 }
  111.                 LCD_SCLK_HIGH();
  112.                 dat<<=1;
  113.         }
  114. #else

  115.         SPI_SendData(CW_SPI2, dat);
  116.         while(SPI_GetFlagStatus(CW_SPI2, SPI_FLAG_TXE) == RESET);

  117. #endif        
  118.         LCD_CS_HIGH();        
  119. }

  120. /******************************************************************************
  121. 函数说明:LCD写入数据
  122. 入口数据:dat 写入的数据
  123. 返回值:  无
  124. ******************************************************************************/
  125. void LCD_WR_DATA8(uint8_t dat)
  126. {
  127.         LCD_Writ_Bus(dat);
  128. }

  129. /******************************************************************************
  130. 函数说明:LCD写入数据
  131. 入口数据:dat 写入的数据
  132. 返回值:  无
  133. ******************************************************************************/
  134. void LCD_WR_DATA(uint16_t dat)
  135. {
  136.         LCD_Writ_Bus(dat>>8);
  137.         LCD_Writ_Bus(dat);
  138. }

  139. /******************************************************************************
  140. 函数说明:LCD写入命令
  141. 入口数据:dat 写入的命令
  142. 返回值:  无
  143. ******************************************************************************/
  144. void LCD_WR_REG(uint8_t  dat)
  145. {
  146.         LCD_DC_LOW();//写命令
  147.         LCD_Writ_Bus(dat);
  148.         LCD_DC_HIGH();//写数据
  149. }

  150. /******************************************************************************
  151. 函数说明:设置起始和结束地址
  152. 入口数据:x1,x2 设置列的起始和结束地址
  153.                   y1,y2 设置行的起始和结束地址
  154. 返回值:  无
  155. ******************************************************************************/
  156. void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
  157. {
  158.         if(USE_HORIZONTAL==0)
  159.         {
  160.                 LCD_WR_REG(0x2a);//列地址设置
  161.                 LCD_WR_DATA(x1+2);
  162.                 LCD_WR_DATA(x2+2);
  163.                 LCD_WR_REG(0x2b);//行地址设置
  164.                 LCD_WR_DATA(y1+1);
  165.                 LCD_WR_DATA(y2+1);
  166.                 LCD_WR_REG(0x2c);//储存器写
  167.         }
  168.         else if(USE_HORIZONTAL==1)
  169.         {
  170.                 LCD_WR_REG(0x2a);//列地址设置
  171.                 LCD_WR_DATA(x1+2);
  172.                 LCD_WR_DATA(x2+2);
  173.                 LCD_WR_REG(0x2b);//行地址设置
  174.                 LCD_WR_DATA(y1+1);
  175.                 LCD_WR_DATA(y2+1);
  176.                 LCD_WR_REG(0x2c);//储存器写
  177.         }
  178.         else if(USE_HORIZONTAL==2)
  179.         {
  180.                 LCD_WR_REG(0x2a);//列地址设置
  181.                 LCD_WR_DATA(x1+1);
  182.                 LCD_WR_DATA(x2+1);
  183.                 LCD_WR_REG(0x2b);//行地址设置
  184.                 LCD_WR_DATA(y1+2);
  185.                 LCD_WR_DATA(y2+2);
  186.                 LCD_WR_REG(0x2c);//储存器写
  187.         }
  188.         else
  189.         {
  190.                 LCD_WR_REG(0x2a);//列地址设置
  191.                 LCD_WR_DATA(x1+1);
  192.                 LCD_WR_DATA(x2+1);
  193.                 LCD_WR_REG(0x2b);//行地址设置
  194.                 LCD_WR_DATA(y1+2);
  195.                 LCD_WR_DATA(y2+2);
  196.                 LCD_WR_REG(0x2c);//储存器写
  197.         }
  198. }

  199. /******************************************************************************
  200. 函数说明:LCD初始化,包含硬件IO
  201. 入口数据:无
  202. 返回值:  无
  203. ******************************************************************************/
  204. void LcdInit(void)
  205. {
  206.         LcdIoInit();
  207.         
  208.         LCD_RES_LOW();
  209.         delay_ms(100);
  210.         LCD_RES_HIGH();
  211.         delay_ms(100);
  212.         LCD_BLK_HIGH();
  213.         delay_ms(100);
  214.       
  215.         LCD_WR_REG(0x11);
  216.         delay_ms(120);
  217.         LCD_WR_REG(0xB1);
  218.         LCD_WR_DATA8(0x05);
  219.         LCD_WR_DATA8(0x3C);
  220.         LCD_WR_DATA8(0x3C);
  221.         LCD_WR_REG(0xB2);
  222.         LCD_WR_DATA8(0x05);
  223.         LCD_WR_DATA8(0x3C);
  224.         LCD_WR_DATA8(0x3C);
  225.         LCD_WR_REG(0xB3);
  226.         LCD_WR_DATA8(0x05);
  227.         LCD_WR_DATA8(0x3C);
  228.         LCD_WR_DATA8(0x3C);
  229.         LCD_WR_DATA8(0x05);
  230.         LCD_WR_DATA8(0x3C);
  231.         LCD_WR_DATA8(0x3C);
  232.         LCD_WR_REG(0xB4);
  233.         LCD_WR_DATA8(0x03);
  234.         LCD_WR_REG(0xC0);
  235.         LCD_WR_DATA8(0x28);
  236.         LCD_WR_DATA8(0x08);
  237.         LCD_WR_DATA8(0x04);
  238.         LCD_WR_REG(0xC1);
  239.         LCD_WR_DATA8(0XC0);
  240.         LCD_WR_REG(0xC2);
  241.         LCD_WR_DATA8(0x0D);
  242.         LCD_WR_DATA8(0x00);
  243.         LCD_WR_REG(0xC3);
  244.         LCD_WR_DATA8(0x8D);
  245.         LCD_WR_DATA8(0x2A);
  246.         LCD_WR_REG(0xC4);
  247.         LCD_WR_DATA8(0x8D);
  248.         LCD_WR_DATA8(0xEE);
  249.         LCD_WR_REG(0xC5);
  250.         LCD_WR_DATA8(0x1A);
  251.         LCD_WR_REG(0x36);
  252.         
  253.         if(USE_HORIZONTAL==0)
  254.                 LCD_WR_DATA8(0x00);
  255.         else if(USE_HORIZONTAL==1)
  256.                 LCD_WR_DATA8(0xC0);
  257.         else if(USE_HORIZONTAL==2)
  258.                 LCD_WR_DATA8(0x70);
  259.         else
  260.                 LCD_WR_DATA8(0xA0);
  261.       
  262.         LCD_WR_REG(0xE0);
  263.         LCD_WR_DATA8(0x04);
  264.         LCD_WR_DATA8(0x22);
  265.         LCD_WR_DATA8(0x07);
  266.         LCD_WR_DATA8(0x0A);
  267.         LCD_WR_DATA8(0x2E);
  268.         LCD_WR_DATA8(0x30);
  269.         LCD_WR_DATA8(0x25);
  270.         LCD_WR_DATA8(0x2A);
  271.         LCD_WR_DATA8(0x28);
  272.         LCD_WR_DATA8(0x26);
  273.         LCD_WR_DATA8(0x2E);
  274.         LCD_WR_DATA8(0x3A);
  275.         LCD_WR_DATA8(0x00);
  276.         LCD_WR_DATA8(0x01);
  277.         LCD_WR_DATA8(0x03);
  278.         LCD_WR_DATA8(0x13);
  279.         LCD_WR_REG(0xE1);
  280.         LCD_WR_DATA8(0x04);
  281.         LCD_WR_DATA8(0x16);
  282.         LCD_WR_DATA8(0x06);
  283.         LCD_WR_DATA8(0x0D);
  284.         LCD_WR_DATA8(0x2D);
  285.         LCD_WR_DATA8(0x26);
  286.         LCD_WR_DATA8(0x23);
  287.         LCD_WR_DATA8(0x27);
  288.         LCD_WR_DATA8(0x27);
  289.         LCD_WR_DATA8(0x25);
  290.         LCD_WR_DATA8(0x2D);
  291.         LCD_WR_DATA8(0x3B);
  292.         LCD_WR_DATA8(0x00);
  293.         LCD_WR_DATA8(0x01);
  294.         LCD_WR_DATA8(0x04);
  295.         LCD_WR_DATA8(0x13);
  296.         LCD_WR_REG(0x3A);
  297.         LCD_WR_DATA8(0x05);
  298.         LCD_WR_REG(0x29);
  299. }

  300. /******************************************************************************
  301. 函数说明:在指定区域填充颜色
  302. 入口数据:xsta,ysta   起始坐标
  303.                   xend,yend   终止坐标
  304.                   color       要填充的颜色
  305. 返回值:  无
  306. ******************************************************************************/
  307. void LcdFill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
  308. {         
  309.         uint16_t i,j;
  310.         
  311.         LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
  312.         
  313.         for(i=ysta;i<yend;i++)
  314.         {                                                                                                                           
  315.                 for(j=xsta;j<xend;j++)
  316.                 {
  317.                         LCD_WR_DATA(color);
  318.                 }
  319.         }                                                      
  320. }

  321. /******************************************************************************
  322. 函数说明:在指定位置画点
  323. 入口数据:x,y 画点坐标
  324.                   color 点的颜色
  325. 返回值:  无
  326. ******************************************************************************/
  327. void LcdDrawPoint(uint16_t x,uint16_t y,uint16_t color)
  328. {
  329.         LCD_Address_Set(x,y,x,y);//设置光标位置
  330.         LCD_WR_DATA(color);
  331. }

  332. /******************************************************************************
  333. 函数说明:画线
  334. 入口数据:x1,y1   起始坐标
  335.                   x2,y2   终止坐标
  336.                   color   线的颜色
  337. 返回值:  无
  338. ******************************************************************************/
  339. void LcdDrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
  340. {
  341.         uint16_t t;
  342.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  343.         int incx,incy,uRow,uCol;
  344.         
  345.         delta_x=x2-x1; //计算坐标增量
  346.         delta_y=y2-y1;
  347.         uRow=x1;//画线起点坐标
  348.         uCol=y1;
  349.         if(delta_x>0)incx=1; //设置单步方向
  350.         else if (delta_x==0)incx=0;//垂直线
  351.         else {incx=-1;delta_x=-delta_x;}
  352.         if(delta_y>0)incy=1;
  353.         else if (delta_y==0)incy=0;//水平线
  354.         else {incy=-1;delta_y=-delta_y;}
  355.         if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  356.         else distance=delta_y;
  357.         
  358.         for(t=0;t<distance+1;t++)
  359.         {
  360.                 LcdDrawPoint(uRow,uCol,color);//画点
  361.                 xerr+=delta_x;
  362.                 yerr+=delta_y;
  363.                 if(xerr>distance)
  364.                 {
  365.                         xerr-=distance;
  366.                         uRow+=incx;
  367.                 }
  368.                 if(yerr>distance)
  369.                 {
  370.                         yerr-=distance;
  371.                         uCol+=incy;
  372.                 }
  373.         }
  374. }

  375. /******************************************************************************
  376. 函数说明:画矩形
  377. 入口数据:x1,y1   起始坐标
  378.                   x2,y2   终止坐标
  379.                   color   矩形的颜色
  380. 返回值:  无
  381. ******************************************************************************/
  382. void LcdDrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color)
  383. {
  384.         LcdDrawLine(x1,y1,x2,y1,color);
  385.         LcdDrawLine(x1,y1,x1,y2,color);
  386.         LcdDrawLine(x1,y2,x2,y2,color);
  387.         LcdDrawLine(x2,y1,x2,y2,color);
  388. }

  389. /******************************************************************************
  390. 函数说明:画圆
  391. 入口数据:x0,y0   圆心坐标
  392.                   r       半径
  393.                   color   圆的颜色
  394. 返回值:  无
  395. ******************************************************************************/
  396. void LcdDrawCircle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color)
  397. {
  398.         int a,b;
  399.         
  400.         a=0;b=r;         
  401.         while(a<=b)
  402.         {
  403.                 LcdDrawPoint(x0-b,y0-a,color);              //3           
  404.                 LcdDrawPoint(x0+b,y0-a,color);             //0           
  405.                 LcdDrawPoint(x0-a,y0+b,color);             //1               
  406.                 LcdDrawPoint(x0-a,y0-b,color);              //2            
  407.                 LcdDrawPoint(x0+b,y0+a,color);            //4               
  408.                 LcdDrawPoint(x0+a,y0-b,color);             //5
  409.                 LcdDrawPoint(x0+a,y0+b,color);            //6
  410.                 LcdDrawPoint(x0-b,y0+a,color);             //7
  411.                 a++;
  412.                 if((a*a+b*b)>(r*r))//判断要画的点是否过远
  413.                 {
  414.                         b--;
  415.                 }
  416.         }
  417. }

  418. /******************************************************************************
  419. 函数说明:显示单个字符
  420. 入口数据:x,y显示坐标
  421.                   ch 要显示的字符
  422.                   fc 字的颜色
  423.                   bc 字的背景色
  424.                   csize 字号
  425. 返回值:  无
  426. ******************************************************************************/
  427. void LcdShowChar(uint16_t x,uint16_t y,uint8_t ch,uint16_t fc,uint16_t bc,uint8_t csize)
  428. {
  429.         const unsigned char  *temp;
  430.         uint8_t i,j,k;
  431.         uint16_t x0=x,y0=y;
  432.         uint8_t row=0,column=0;
  433.         
  434.         row=(csize/8+((csize%8)?1:0));  //计算行
  435.         column=csize/2;                        //列
  436.         ch=ch-' ';                                  //得到偏移后的值
  437.                
  438.         switch(csize)
  439.         {
  440.                 case 12:temp=Ascii_6x12[ch]; break;
  441.                 case 16:temp=Ascii_8x16[ch]; break;
  442.                 case 24:temp=Ascii_12x24[ch]; break;
  443.                 case 32:temp=Ascii_16x32[ch]; break;
  444.                 default: temp=Ascii_6x12[ch]; break;
  445.         }
  446.         
  447.         //显示要与取模方式保持一致
  448.         for(i=0;i<row;i++)
  449.         {
  450.                 for(j=0;j<column;j++)
  451.                 {
  452.                         for(k=0;k<8;k++)
  453.                         {
  454.                                 if((*temp)&(0x01<<k))
  455.                                 {
  456.                                         LcdDrawPoint(x,y,fc);//画一个点,字体色
  457.                                 }
  458.                                 else
  459.                                 {
  460.                                         LcdDrawPoint(x,y,bc);//画一个点,背景色
  461.                                 }
  462.                                 y++;
  463.                         }
  464.                         y=y0;
  465.                         x++;
  466.                         temp++;
  467.                 }
  468.                 x=x0;
  469.                 y0+=8;
  470.                 y=y0;
  471.         }
  472. }

  473. /******************************************************************************
  474. 函数说明:显示字符串
  475. 入口数据:x,y显示坐标
  476.                   *p 要显示的字符串
  477.                   fc 字的颜色
  478.                   bc 字的背景色
  479.                   csize 字号
  480. 返回值:  无
  481. ******************************************************************************/
  482. void LcdShowString(uint16_t x,uint16_t y,const char *p,uint16_t fc,uint16_t bc,uint8_t csize)
  483. {         
  484.         while(*p!='\0')
  485.         {      
  486.                 LcdShowChar(x,y,*p,fc,bc,csize);
  487.                 x+=csize/2;
  488.                 p++;
  489.         }  
  490. }

  491. /******************************************************************************
  492. 函数说明:显示汉字字符
  493. 入口数据:x,y显示坐标
  494.                   index 汉字字符索引
  495.                   fc 字的颜色
  496.                   bc 字的背景色
  497. 返回值:  无
  498. ******************************************************************************/
  499. void LcdShow16x16Hz(uint32_t x, uint32_t y, uint8_t index, uint16_t fc, uint16_t bc)        
  500. {  
  501.         const char *temp=Hzk[index];              // 获取字体数据在数组中的的起始位置
  502.         uint8_t y0=y,x0=x;
  503.         uint8_t i,j,k;
  504.         uint8_t row=0,column=0;

  505.         row=16/8;
  506.         column=16;
  507.         
  508.         //显示要与取模方式保持一致
  509.         for(i=0;i<row;i++)
  510.         {
  511.                 for(j=0;j<column;j++)
  512.                 {
  513.                         for( k=0;k<8;k++)
  514.                         {         
  515.                                 if(*temp&(0x01<<k))
  516.                                 {
  517.                                         LcdDrawPoint(x,y,fc);//画一个点,字体色
  518.                                 }
  519.                                 else
  520.                                 {
  521.                                         LcdDrawPoint(x,y,bc);//画一个点,背景色
  522.                                 }
  523.                                 y++;
  524.                         }
  525.                         temp++;
  526.                         x++;
  527.                         y=y0;
  528.                 }
  529.                 x=x0;
  530.                 y0+=8;
  531.                 y=y0;
  532.         }
  533. }        

  534. /******************************************************************************
  535.       函数说明:显示图片
  536.       入口数据:x,y起点坐标
  537.                 length 图片长度
  538.                 width  图片宽度
  539.                 pic[]  图片数组
  540.       返回值:  无
  541. ******************************************************************************/
  542. void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
  543. {
  544.         u16 i,j;
  545.         u32 k=0;
  546.         x=x-5;
  547.         LCD_Address_Set(x,y,x+length-1,y+width-1);
  548.         for(i=0;i<length;i++)
  549.         {
  550.                 for(j=0;j<width;j++)
  551.                 {
  552.                         LCD_WR_DATA8(pic[k*2]);
  553.                         LCD_WR_DATA8(pic[k*2+1]);
  554.                         k++;
  555.                 }
  556.         }                        
  557. }

  558. /******************************************************************************
  559. 函数说明:显示图片
  560. 入口数据:x,y显示坐标
  561.                   width   图片宽度
  562.                   height  图片高度
  563.                   image   图片数据
  564. 返回值:  无
  565. ******************************************************************************/
  566. void LcdShowImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *image)
  567. {         
  568.         uint16_t colorData=0;
  569.         uint32_t cnt=0;
  570.         uint16_t i,j;
  571.         
  572.          for( i=0; i<height; i++)                                          // 一行一行地显示
  573.         {
  574.                  LCD_Address_Set(x, y+i, x+width, y+height);  // 重新设置光标位置
  575.                 for( j=0; j<width; j++)                                  // 一行中,从左到右,逐个像素处理
  576.                 {                    
  577.                     colorData=(image[cnt*2+1]<<8) | image[cnt*2];
  578.                     LCD_WR_DATA(colorData);                        // 写入16位颜色数据
  579.                         cnt++;        
  580.                 }
  581.         }         
  582. }
  1. #ifndef __LCD_ST7735_H__
  2. #define __LCD_ST7735_H__

  3. typedef unsigned int   uint32_t;
  4. typedef unsigned short uint16_t;
  5. typedef unsigned char  uint8_t;

  6. #define WHITE                  0xFFFF
  7. #define BLACK                  0x0000         
  8. #define BLUE                   0x001F  
  9. #define BRED                   0XF81F
  10. #define GRED                   0XFFE0
  11. #define GBLUE                  0X07FF
  12. #define RED                    0xF800
  13. #define MAGENTA                0xF81F
  14. #define GREEN                  0x07E0
  15. #define CYAN                   0x7FFF
  16. #define YELLOW                 0xFFE0
  17. #define BROWN                  0XBC40            //棕色
  18. #define BRRED                  0XFC07            //棕红色
  19. #define GRAY                   0X8430            //灰色
  20. #define DARKBLUE               0X01CF            //深蓝色
  21. #define LIGHTBLUE              0X7D7C            //浅蓝色  
  22. #define GRAYBLUE               0X5458            //灰蓝色
  23. #define LIGHTGREEN             0X841F            //浅绿色
  24. #define LGRAY                  0XC618            //浅灰色(PANNEL),窗体背景色
  25. #define LGRAYBLUE              0XA651            //浅灰蓝色(中间层颜色)
  26. #define LBBLUE                 0X2B12            //浅棕蓝色(选择条目的反色)

  27. void Display_Test(void);
  28. void LcdDrawPoint(uint16_t x,uint16_t y,uint16_t color);
  29. void LcdInit(void);
  30. #endif
应用相关接口代码如下:
main.c
  1. /* includes */
  2. #include "at32m412_416_board.h"
  3. #include "at32m412_416_clock.h"
  4. #include "lcd_st7735.h"

  5. /**
  6.   * [url=home.php?mod=space&uid=247401]@brief[/url]  main function.
  7.   * @param  none
  8.   * @retval none
  9.   */
  10. int main(void)
  11. {
  12.   system_clock_config();
  13.   at32_board_init();
  14.         LcdInit();
  15.        
  16.   while(1)
  17.   {
  18.   Display_Test();
  19.   }
  20. }

在lcd_st7735.c中添加LCD测试接口代码:
  1. /******************************************************************************
  2. 函数说明:LCD显示测试
  3. 入口数据:无
  4. 返回值:  无
  5. ******************************************************************************/
  6. void Display_Test(void)
  7. {
  8.         LcdFill(0,3,LCD_W,LCD_H,BLACK);
  9.         LcdShow16x16Hz(8, 3, 0, YELLOW, BLACK);
  10.         LcdShow16x16Hz(24, 3, 1, YELLOW, BLACK);
  11.         LcdShow16x16Hz(40, 3, 2, YELLOW, BLACK);
  12.         LcdShow16x16Hz(56, 3, 3, YELLOW, BLACK);
  13.         LcdShow16x16Hz(72, 3, 4, YELLOW, BLACK);
  14.         LcdShow16x16Hz(88, 3, 5, YELLOW, BLACK);
  15.         LcdShow16x16Hz(104,3, 6, YELLOW, BLACK);
  16.         LcdShowString(12,24,"AT32F412",RED, BLACK,24);
  17.         delay_ms(100);
  18.         LcdShow16x16Hz(38,60, 7, BLUE, WHITE);
  19.         delay_ms(100);
  20.         LcdShow16x16Hz(56,60, 8, BLUE, WHITE);
  21.         delay_ms(100);
  22.         LcdShow16x16Hz(74,60, 9, BLUE, WHITE);
  23.         delay_ms(1000);
  24.         LCD_ShowPicture(0,0,128,160,gImage_1);
  25.         delay_ms(1000);
  26. }
硬件实物连线如下:
硬件实物连接.png
这里的中文字符与彩色图片制作,需要借助汉字取模工具“PCtoLCD2002”与图片取模工具“Img2Lcd”。
PCtoLCD2002.zip (886.17 KB, 下载次数: 0)
Image2Lcd.zip (506.45 KB, 下载次数: 0)
驱动的效果见B站视频:AT32M412驱动ST7735S彩屏
https://www.bilibili.com/video/BV1KtMizJEAQ/



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

本版积分规则

106

主题

1096

帖子

7

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