ctspot · 2022年12月10日 · 浙江

【GD32F427开发板试用】GD32F427VK显示JLX12864点阵屏

手上刚好有一块JLX12864的点阵屏,刚好用来评估GD32F427,趁着晚上有空,移植了一下JLX12864的程序,代码片段如下:

#include "bsp_lcd.h"
#include "gd32f4xx.h"
#include "systick.h"

#define RESET_PIN GPIO_PIN_3
#define CS_PIN    GPIO_PIN_6
#define RS_PIN    GPIO_PIN_1
#define SCK_PIN   GPIO_PIN_7
#define SDA_PIN   GPIO_PIN_9

//液晶1个像素占1个bit,即1个字节含8个像素,在显存中的位置位于同一列,从上到下依次从BIT0~BIT7
//液晶水平共192列, 8页, 即1页为8行

#define BSP_LCD_DELAY_MS(n) delay_1ms(n)

#define BSP_LCD_RESET_CTRL(n) gpio_bit_write(GPIOE, RESET_PIN, (bit_status)n)

#define BSP_LCD_CS(n)  gpio_bit_write(GPIOE, CS_PIN, (bit_status)n)
#define BSP_LCD_RS(n)  gpio_bit_write(GPIOE, RS_PIN, (bit_status)n)
#define BSP_LCD_SCK(n) gpio_bit_write(GPIOB, SCK_PIN, (bit_status)n)
#define BSP_LCD_SDA(n) gpio_bit_write(GPIOB, SDA_PIN, (bit_status)n)

static void bsp_lcd_reset(void)
{
    BSP_LCD_RESET_CTRL(0);
    BSP_LCD_DELAY_MS(100);
    BSP_LCD_RESET_CTRL(1);
    BSP_LCD_DELAY_MS(100);
}

static void bsp_lcd_write_reg(uint8_t reg)
{
    uint8_t i;

    BSP_LCD_CS(0);
    BSP_LCD_RS(0);

    for(i = 0; i < 8; i++)
    {
        BSP_LCD_SCK(0);
        if(reg & 0x80) //MSB
        {
            BSP_LCD_SDA(1);
        }
        else
        {
            BSP_LCD_SDA(0);
        }
        BSP_LCD_SCK(1);
        reg <<= 1;  //MSB
    }
    BSP_LCD_CS(1);
}

static void bsp_lcd_write_data(uint8_t dat)
{
    uint8_t i;

    BSP_LCD_CS(0);
    BSP_LCD_RS(1);

    for(i = 0; i < 8; i++)
    {
        BSP_LCD_SCK(0);
        if(dat & 0x80) //MSB
        {
            BSP_LCD_SDA(1);
        }
        else
        {
            BSP_LCD_SDA(0);
        }
        BSP_LCD_SCK(1);
        dat <<= 1;  //MSB
    }
    BSP_LCD_CS(1);
}

//设置LCD页和起始列(8行为1页)
static void bsp_lcd_address(uint8_t page, uint8_t column)
{
    bsp_lcd_write_reg(0xb0 + (page & 0x0f)); //设置页地址。每页是8行。一个画面的64 行被分成8 个页。
    bsp_lcd_write_reg((column >> 4) + 0x10); //设置列地址的高4 位
    bsp_lcd_write_reg(column & 0x0f); //设置列地址的低4 位
}

//显示 8x16 点阵图像、ASCII, 或8x16 点阵的自造字符、其他图标
void bsp_lcd_disp_graph_8x16(uint8_t page, uint8_t column, const uint8_t *dp)
{
    uint8_t i, j;
    for(j = 0; j < 2; j++)
    {
        bsp_lcd_address(page + j, column);
        for (i = 0; i < 8; i++)
        {
            bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
            dp++;
        }
    }
}

//显示16x16 点阵图像、汉字、生僻字或16x16 点阵的其他图标
void bsp_lcd_disp_graph_16x16(uint8_t page, uint8_t column, const uint8_t *dp)
{
    uint8_t i, j;
    for(j = 0; j < (16 >> 3); j++)
    {
        bsp_lcd_address(page + j, column);
        for (i = 0; i < 16; i++)
        {
            bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
            dp++;
        }
    }
}

//显示24x48 点阵图像、汉字、生僻字或24x48 点阵的其他图标
void bsp_lcd_disp_graph_24x48(uint8_t page, uint8_t column, const uint8_t *dp)
{
    uint8_t i, j;
    for(j = 0; j < (48 >> 3); j++)
    {
        bsp_lcd_address(page + j, column);
        for (i = 0; i < 24; i++)
        {
            bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
            dp++;
        }
    }
}

//void bsp_lcd_disp_graph_128x64(const uint8_t *dp)
//{
//    uint8_t i, j;
//    for(i = 0; i < LCD_PAGES; i++)
//    {
//        bsp_lcd_address(i, 0);
//        for(j = 0; j < LCD_COLS; j++)
//        {
//            bsp_lcd_write_data(*dp);
//            dp++;
//        }
//    }
//}

//显示32x32 点阵图像、汉字、生僻字或32x32 点阵的其他图标
//void bsp_lcd_disp_graph_32x32(uint8_t page, uint8_t column, const uint8_t *dp)
//{
//    uint8_t i, j;
//    for(j = 0; j < (32 >> 3); j++)
//    {
//        bsp_lcd_address(page + j, column);
//        for (i = 0; i < 32; i++)
//        {
//            bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
//            dp++;
//        }
//    }
//}

//显示48x48 点阵图像、汉字、生僻字或48x48 点阵的其他图标
void bsp_lcd_disp_graph_48x48(uint8_t page, uint8_t column, const uint8_t *dp)
{
    uint8_t i, j;
    for(j = 0; j < (48 >> 3); j++)
    {
        bsp_lcd_address(page + j, column);
        for (i = 0; i < 48; i++)
        {
            bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
            dp++;
        }
    }
}

void bsp_lcd_init(void)
{
    gpio_bit_reset(GPIOB, SCK_PIN);
    gpio_bit_reset(GPIOB, SDA_PIN);
    gpio_bit_reset(GPIOE, RS_PIN);
    gpio_bit_set(GPIOE, RESET_PIN);
    gpio_bit_set(GPIOE, CS_PIN);
    
    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCK_PIN);
    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SDA_PIN);
    gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS_PIN);
    gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RESET_PIN);
    gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CS_PIN);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCK_PIN);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SDA_PIN);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS_PIN);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RESET_PIN);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CS_PIN);
    
    bsp_lcd_reset();
    bsp_lcd_write_reg(0xe2);    //软复位
    BSP_LCD_DELAY_MS(5);
    bsp_lcd_write_reg(0x2c);    //升压步骤1
    BSP_LCD_DELAY_MS(50);
    bsp_lcd_write_reg(0x2e);    //升压步骤2
    BSP_LCD_DELAY_MS(50);
    bsp_lcd_write_reg(0x2f);    //升压步骤3
    BSP_LCD_DELAY_MS(5);
    bsp_lcd_write_reg(0x23);    //粗调对比度,可设置范围0x20~0x27
    bsp_lcd_write_reg(0x81);    //微调对比度
    bsp_lcd_write_reg(0x28);    //微调对比度的值,可设置范围0x00~0x3f
    bsp_lcd_write_reg(0xa2);    //1/9 偏压比(bias)
    bsp_lcd_write_reg(0xc8);    //行扫描顺序:从上到下
    bsp_lcd_write_reg(0xa0);    //列扫描顺序:从左到右
    bsp_lcd_write_reg(0x40);    //起始行:第一行开始
    bsp_lcd_clear(0x00);        
    bsp_lcd_write_reg(0xaf);    //开显示
}

//全屏清屏
void bsp_lcd_clear(uint8_t color)
{
    uint8_t i, j;
    for(i = 0; i < LCD_PAGES; i++)
    {
        bsp_lcd_address(i, 0);
        for(j = 0;j < LCD_COLS; j++)
        {
            bsp_lcd_write_data(color);
        }
    }
}

void bsp_lcd_draw_rect(uint8_t page_start, uint8_t col, uint8_t pages, uint8_t cols)
{
    uint8_t i, j;

    if(pages == 0 || cols == 0)
    {
        return;
    }
    
    if(pages == 1)
    {
        bsp_lcd_address(page_start, col);
        bsp_lcd_write_data(0xff);//首列
        for(j = col + 1; j < col + cols - 1; j++)//中间列
        {
            bsp_lcd_write_data(0x81);
        }
        if(cols > 1)//尾列
        {
            bsp_lcd_write_data(0xff);
        }
    }
    else
    {
        //首行
        bsp_lcd_address(page_start, col);
        bsp_lcd_write_data(0xff);//首列
        for(j = col + 1; j < col + cols - 1; j++)//中间列
        {
            bsp_lcd_write_data(0x01);
        }
        if(cols > 1)//尾列
        {
            bsp_lcd_write_data(0xff);
        }
        //中间行
        for(i = page_start + 1; i < page_start + pages - 1; i++)
        {
            bsp_lcd_address(i, col);
            bsp_lcd_write_data(0xff);//首列
            for(j = col + 1; j < col + cols - 1; j++)//中间列
            {
                bsp_lcd_write_data(0x00);
            }
            if(cols > 1)//尾列
            {
                bsp_lcd_write_data(0xff);
            }
        }
        //尾行
        if(pages > 1)
        {
            bsp_lcd_address(page_start + pages - 1, col);
            bsp_lcd_write_data(0xff);//首列
            for(j = col + 1; j < col + cols - 1; j++)//中间列
            {
                bsp_lcd_write_data(0x80);
            }
            if(cols > 1)//尾列
            {
                bsp_lcd_write_data(0xff);
            }
        }
    }
}

uint8_t word_tab[][32] = {
    {0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,
     0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00},/*"你",0*/

    {0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,
     0x40,0x22,0x15,0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00},/*"好",1*/
};

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* configure systick */
    systick_config();

    /* enable the LEDs GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOE);

    /* reset LED2 GPIO pin */
    gpio_bit_reset(GPIOC, GPIO_PIN_6);
    bsp_lcd_init();
    bsp_lcd_draw_rect(0, 0, 8, 128);
    bsp_lcd_disp_graph_16x16(1, 1, word_tab[0]);
    bsp_lcd_disp_graph_16x16(1, 17, word_tab[1]);

    while(1) {
        delay_1ms(1000);
    }
}

上述代码的逻辑很简单,首先初始化LCD,然后画一个128*64的矩形,最后在屏幕中显示你好中文,详细效果如下
IMG_5966.JPG
其中有关点阵汉字使用的是16X16的点阵,点阵数据是自己产生的,JLX12864像素点整的排列规则如下:
aaa.PNG
我们使用的是PCtoLCD2002.exe这款软件
首先配置点阵排列规则,如下图所示,注意选择C51格式
bbb.PNG
然后输入要生成点阵数据的汉字,点击生成字模,就可以生成对应的点阵数据了
ccc.PNG
好了,以上就是如何使用GD32驱动JLX12864的视频,除了显示文字,还可以显示点阵图片,原理都是相同的,欢迎感兴趣的小伙伴与我交流分享。

推荐阅读
关注数
10708
内容数
187
中国高性能通用微控制器领域的领跑者兆易创新GD系列芯片技术专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息