51xlf 发表于 2022-6-1 23:20

快速实现移植LCD驱动到F425

本帖最后由 51xlf 于 2022-7-1 17:40 编辑

#申请原创#@21小跑堂 近期又购置了一个arduino接口的TFT LCD,可以兼容arduino接口。而且芯片还自动SD卡,后期可以通过这个SD卡加载汉字库。

需要在arduino上测试了一下,感觉效果还是可以的。突然想起来,AT-START-F425的板子也是自带arduino的接口的。
这个板子可以完全和AT-START-F425板子完美的融合起来的。奔着说干就干的原则,先看看需要用到哪些接口?
屏幕的接口就是暂时用到的是绿色框中的几个引脚。

而对应在屏幕上的几个端,就需要看原理图了。完美的arduino的接口,不错。

看一下屏幕和AT-START-F425的契合的图片。

就是刷新的速度有限,不能发挥出AT32F425的能力,不过这个的速度还是可以的。
这个需要用到的几个引脚。先在程序里面配置一下,因为不是连续的引脚,所以这个只能是按照位进行操作了。
程序的配置有点繁琐了,不如直接给寄存器赋值来的直接。先把引脚全部的配置为输出了。
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    /* set default parameter */
    gpio_default_para_init(&gpio_init_struct);

    /* configure button pin as input with pull-up/pull-down */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = GPIO_PINS_0 |GPIO_PINS_1|GPIO_PINS_4|GPIO_PINS_8|GPIO_PINS_9|GPIO_PINS_10;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOA, &gpio_init_struct);

    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = GPIO_PINS_0 |GPIO_PINS_4|GPIO_PINS_3|GPIO_PINS_5|GPIO_PINS_10;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOB, &gpio_init_struct);

    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = GPIO_PINS_1 |GPIO_PINS_7;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOC, &gpio_init_struct);后面就是对IO口进行赋值操作了,习惯了使用了stm32的HAL了,所以这里还是使用的宏定义对LCD的控制引脚(例如复位 读写 片选)进行操作的,
这样好操作,而且后期移植到其他的程序上也是非常的方便的。
#define LCD_RD_GPIO_Port GPIOA
#define LCD_RD_Pin GPIO_PINS_0

#define LCD_WR_GPIO_Port GPIOA
#define LCD_WR_PinGPIO_PINS_1

#define LCD_RS_GPIO_Port GPIOA
#define LCD_RS_Pin   GPIO_PINS_4

#define LCD_CS_GPIO_Port GPIOB
#define LCD_CS_Pin GPIO_PINS_0

#define LCD_RST_GPIO_Port GPIOC
#define LCD_RST_Pin GPIO_PINS_1

#define LCD_D0_GPIO_PortGPIOA
#define LCD_D0_Pin   GPIO_PINS_9
#define LCD_D1_GPIO_PortGPIOC
#define LCD_D1_Pin   GPIO_PINS_7
#define LCD_D2_GPIO_PortGPIOA
#define LCD_D2_Pin   GPIO_PINS_10
#define LCD_D3_GPIO_PortGPIOB
#define LCD_D3_Pin   GPIO_PINS_3
#define LCD_D4_GPIO_Port GPIOB
#define LCD_D4_Pin   GPIO_PINS_5
#define LCD_D5_GPIO_Port GPIOB
#define LCD_D5_Pin   GPIO_PINS_4
#define LCD_D6_GPIO_Port GPIOB
#define LCD_D6_Pin   GPIO_PINS_10
#define LCD_D7_GPIO_Port   GPIOA
#define LCD_D7_Pin   GPIO_PINS_8
#define                LCD_CS_LOW()                LCD_CS_GPIO_Port->clr =LCD_CS_Pin         //
#define                LCD_CS_HIGH()                LCD_CS_GPIO_Port->scr = LCD_CS_Pin                //

#define                LCD_RST_LOW()                LCD_RST_GPIO_Port->clr = LCD_RST_Pin         //
#define                LCD_RST_HIGH()      LCD_RST_GPIO_Port->scr = LCD_RST_Pin                //这里需要对屏幕进行操作了,需要用到的按照位进行操作了。
使用右键查询到使用寄存器赋值的方法。
对IO进行赋值需要对scr进行操作,如果是需要置0则对clr进行操作。
具体的代码如下所示,保障了屏幕的刷新速度了。最快的实现置位和置0的操作。
LCD_WR_GPIO_Port->clr = (uint32_t)LCD_WR_Pin ;      
    if(dat&0x01)      LCD_D0_GPIO_Port->scr = (uint32_t)LCD_D0_Pin;      
    else                LCD_D0_GPIO_Port->clr = (uint32_t)LCD_D0_Pin ;      
    if(dat&0x02)      LCD_D1_GPIO_Port->scr = (uint32_t)LCD_D1_Pin;               
    else                LCD_D1_GPIO_Port->clr = (uint32_t)LCD_D1_Pin ;      
    if(dat&0x04)      LCD_D2_GPIO_Port->scr = (uint32_t)LCD_D2_Pin;      
    else                LCD_D2_GPIO_Port->clr = (uint32_t)LCD_D2_Pin;      
    if(dat&0x08)      LCD_D3_GPIO_Port->scr = (uint32_t)LCD_D3_Pin;      
    else                LCD_D3_GPIO_Port->clr = (uint32_t)LCD_D3_Pin;      
    if(dat&0x10)      LCD_D4_GPIO_Port->scr = (uint32_t)LCD_D4_Pin;               
    else                LCD_D4_GPIO_Port->clr = (uint32_t)LCD_D4_Pin ;      
    if(dat&0x20)      LCD_D5_GPIO_Port->scr = (uint32_t)LCD_D5_Pin;               
    else                LCD_D5_GPIO_Port->clr = (uint32_t)LCD_D5_Pin ;
    if(dat&0x40)      LCD_D6_GPIO_Port->scr = (uint32_t)LCD_D6_Pin;      
    else                LCD_D6_GPIO_Port->clr = (uint32_t)LCD_D6_Pin ;      
    if(dat&0x80)      LCD_D7_GPIO_Port->scr = (uint32_t)LCD_D7_Pin;               
    else                LCD_D7_GPIO_Port->clr = (uint32_t)LCD_D7_Pin ;      
    LCD_WR_GPIO_Port->scr = (uint32_t)LCD_WR_Pin;                具体怎么配置寄存器,这里就不再赘述了。就是跟配置正常的LCD一样了,主要的实现对数据寄存器的写入。
再根据需要配置的形式,自己实现数据和命令的控制,这个具体的代码,在购买屏幕的时候,他就直接给出了。
自己根据提供的例程,选择一下,自己要实现的方式就行了。屏幕的配置很简单,都是固定的代码。
主要的实现函数就是现实一个点的绘制,点动成线,线动成面。
这样就会绘制出来想要的效果了。这个代码使用的就是淘宝店家的提供的例程了。
void lcd_point(uint16_t x, uint16_t y,uint16_t color){
    if ((x >= LCD_W) || (y >= LCD_H))      return ;
    LCD_CS_LOW();      //HAL_GPIO_WritePin(LCD_CS,LOW);
    lcd_address_set(x, y, x, y);
    lcd_write_data(color >> 8);
    lcd_write_data(color);
    LCD_CS_HIGH();      //HAL_GPIO_WritePin(LCD_CS,HIGH);
}有了这个点,后面就是现实的文字输出,根据自己的字库实现字符和汉字的输出了
字符很简单,就是根据字模输出屏幕了就行了。
这里移植了一个oled的显示程序,里面很简单,可以根据自己的需要选择需要的字符。具体的字库,可以看后面的代码了。
这个代码做的就是非常好,可选择性很高。
u8 i,m,temp,size2,chr1;
    u8 x0=x,y0=y;
    if(size1==8)size2=6;
    else size2=(size1/8+((size1%8)?1:0))*(size1/2);//得到字体一个字符对应点阵集所占的字节数
    chr1=chr-' ';//计算偏移后的值
    for(i=0; i<size2; i++)
    {
      if(size1==8)
      {
            temp=asc2_0806;   //调用0806字体
      }
      else if(size1==12)
      {
            temp=asc2_1206;   //调用1206字体
      }
      else if(size1==16)
      {
            temp=asc2_1608;   //调用1608字体
      }
      else if(size1==24)
      {
            temp=asc2_2412;   //调用2412字体
      }
      else return;
      for(m=0; m<8; m++)
      {
            if(temp&0x01)lcd_point(x,y,f_color);
            else lcd_point(x,y,b_color);
            temp>>=1;
            y++;
      }
      x++;
      if((size1!=8)&&((x-x0)==size1/2))
      {
            x=x0;
            y0=y0+8;
      }
      y=y0;
    }至于字符串就是逐个对字符进行输出实现。
这里说明一下如何实现汉字的输出。参考正点原子的方法。
实现字符的取模用的是PC2LCD2000,因为软件的原因,获取的数据,需要修改的内容很多,太麻烦,所以我将正点原子的变量修改了一下,
这样就可以直接实现把内容复制到字模文件中了。
struct typFNT_GB162
{char Msk;
      unsigned char Index;      
      unsigned char no;
};



这样对比一下就行了,直接复制粘贴的效果还是比较好的。省去了,调换字符位置,删除字符内容等一系列的复杂操作。
接下来实现的就是汉字和字符的混合输出了。
根据字符的大小判断是字符还是汉字,如果是字符调用上述的方法就可以实现,如果是汉字,就根据汉字字模,赋值前景色和背景色就行了。
while(*chr) {
      if((*chr) < 128)
      {
            OLED_ShowChar(x,y,*chr,size1, f_color,b_color);
            if(size1==8)x+=6;
            else x+=size1/2;
            chr++;
      } else {
            for (k=0; k<hz16_num; k++)
            {
                if ((hz16.Index==*(chr))&&(hz16.Index==*(chr+1)))
                {
                  for(i=0; i<16; i++)
                  {
                        for(j=0; j<8; j++)
                        {
                            if(hz16.Msk&(0x80>>j))      lcd_point(x+j,y+i,f_color);//lcd_point(x,y,f_color);
                            else {
                              lcd_point(x+j,y+i,b_color);
                            }
                        }
                        for(j=0; j<8; j++)
                        {
                            if(hz16.Msk&(0x80>>j))      lcd_point(x+j+8,y+i,f_color);//lcd_point(x+j,y+i,f_color);
                            else
                            {
                              lcd_point(x+j+8,y+i,b_color);
                            }
                        }
                  }
                }
            }
            chr+=2;
            x+=16;
      }
    }
主要的一些代码已经实现了
OLED_ShowStringCN(0,20,"bbs.21ic.com",16,GREEN,BLACK);
      OLED_ShowStringCN(0,40,"雅特力AT32 MCU",16,RED,BLACK);
      lcd_show_image(0,60,160,27,gImage_ic21);      
      lcd_show_image(0,90,120,80,gImage_at);


让我们来欣赏一下,演示的效果。









caigang13 发表于 2022-6-2 08:19

刷新频率咋样?

51xlf 发表于 2022-6-2 08:37

caigang13 发表于 2022-6-2 08:19
刷新频率咋样?

不怎么快,写入数据的速度太慢了。

koala889 发表于 2022-6-3 10:41

真不错啊

trucyw 发表于 2022-7-6 15:06

赞赞赞

geraldbetty 发表于 2022-10-5 19:29

哪位仁兄帮我介绍一本关于LCD的书

janewood 发表于 2022-10-5 19:43

一个屏,两个驱动板,怎么实现切换

mollylawrence 发表于 2022-10-5 20:00

如何使F425的启动信息显示到LCD 上面

maqianqu 发表于 2022-11-1 11:06

能不能实现读取LCD的触摸数据吗

dspmana 发表于 2022-11-1 15:05

这个lcd的刷屏速度比较慢了            

bestwell 发表于 2022-11-1 15:25

可以是用dma写入数据吗            

pentruman 发表于 2022-11-1 16:12

模拟spi的效果很一般,写入的速度不快,lcd比较慢了。

yangxiaor520 发表于 2023-7-1 11:56

SP刷新I速度有限

georgeliu2016 发表于 2023-7-1 15:27

动手能力强。

Jon495323976 发表于 2023-7-12 14:02

SRAM够用吗

guijial511 发表于 2023-7-12 19:25

arduino编程确定方便,不用过多关注底层驱动。
页: [1]
查看完整版本: 快速实现移植LCD驱动到F425