BK7231+字库+LCD显示

发布于:2024-03-11 ⋅ 阅读:(122) ⋅ 点赞:(0)

1、BK7231有2M flash,可以保存1个16*16汉字字库

2、驱动1个8位并口屏,将字库中的汉字中显示出来

4b4a8bbbd066425093cb3f7e9f490d55.jpg

 70281440015d469eb8d19aa9a9f566dc.jpg

 5a8e3a58347b4120bb28df4928d0f78e.jpg

一、将gb2312_80.bin打包到烧录镜像中。

1、bk7231u_rtt_sdk\OTAPackage\beken_packager中修改config.json文件:

{
    "magic": "RT-Thread",
    "version": "0.1",
    "count": 3,
    "section": [
        {
            "firmware": "bootloader_bk7231_ottime_v2.0.bin",
            "version": "0.1.3",
            "partition": "bootloader",
            "start_addr": "0x00000000",
            "size": "68K"
        },
        {
            "firmware": "../../rtthread.bin",
            "version": "0.1.15",
            "partition": "app",
            "start_addr": "0x00011000",
            "size": "1156K"
        },
		{
            "firmware": "gb2312_80.bin",
            "version": "0.0.2",
            "partition": "romfs",
            "start_addr": "0x000D0000",
            "size": "239K"
        }
		
    ]
}

 其中,gb2312_80.bin是16*16汉字GB2312库,可以通过高通字库软件生成。

这样再运行beken_packager.exe可以把字库文件打包到用于下载FLASH的镜像文件中。

字库文件的起始地址是0xD0000。

二、 用于LCD显示及字库读取的程序

drv_lcd.c

#include <rtdevice.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "drv_lcd.h"
#include "drv_lcd_font.h"
#include "drv_gpio.h"

#include "drv_flash.h"
#include "charcode.h"


#define DBG_SECTION_NAME    "LCD"
#define DBG_COLOR
#define DBG_LEVEL           DBG_LOG
#include <rtdbg.h>

#define LCD_CS_PIN  16
#define LCD_RS_PIN  23
#define LCD_WR_PIN  22
#define LCD_RD_PIN  20
#define LCD_RST_PIN 14

#define LCD_DB0_PIN 11
#define LCD_DB1_PIN 9
#define LCD_DB2_PIN 17
#define LCD_DB3_PIN 8
#define LCD_DB4_PIN 7
#define LCD_DB5_PIN 24
#define LCD_DB6_PIN 26
#define LCD_DB7_PIN 28


#define LCD_CS_SET rt_pin_write(LCD_CS_PIN, PIN_HIGH)
#define LCD_CS_CLR rt_pin_write(LCD_CS_PIN, PIN_LOW)

#define LCD_RS_SET rt_pin_write(LCD_RS_PIN, PIN_HIGH)
#define LCD_RS_CLR rt_pin_write(LCD_RS_PIN, PIN_LOW)

#define LCD_WR_SET rt_pin_write(LCD_WR_PIN, PIN_HIGH)
#define LCD_WR_CLR rt_pin_write(LCD_WR_PIN, PIN_LOW)

#define LCD_RD_SET rt_pin_write(LCD_RD_PIN, PIN_HIGH)
#define LCD_RD_CLR rt_pin_write(LCD_RD_PIN, PIN_LOW)

#define LCD_RST_SET rt_pin_write(LCD_RST_PIN, PIN_HIGH)
#define LCD_RST_CLR rt_pin_write(LCD_RST_PIN, PIN_LOW)

#define LCD_CLEAR_SEND_NUMBER LCD_W*LCD_H

rt_uint16_t BACK_COLOR =  BLUE, FORE_COLOR =WHITE;
rt_thread_t tid = RT_NULL;


#define FLASH_ADDR_BASE			 0x000D0000

rt_uint32_t flash_addr_base=0xD0000;
rt_uint32_t zkoffset=0;
//字模buff
rt_uint8_t MatrixBuff[32];



void getMatrix(const rt_uint16_t nmCode)
{
	rt_uint8_t i;
	rt_uint32_t offset;
	rt_uint8_t GBH,GBL;
	rt_uint16_t nm=nmCode;

	GBH=nm>>8&0xff;
	GBL=nm&0xff;
    //rt_kprintf("GB=%c%c\r\n",GBH,GBL);
	if(GBH>=0xb0)
	{
		offset=((GBH-0xa7)*94+GBL-0xa1)*34;
	}else
	{
		offset=((GBH-0xa1)*94+GBL-0xa1)*34;
	}

    //rt_kprintf("offset=%4x\r\n",offset);


    //memcpy(Buff,(rt_uint8_t *)(p_ZK_ADDR+offset),1);
/*
	for(i=0;i<32;i++)
	{
        rt_thread_mdelay(40);
        Buff[i]=*(p_ZK_ADDR+offset+i);
		//MatrixBuff[i]=*(FLASH_ADDR_BASE+offset+i);
         rt_kprintf("%d:=%2x\r\n",i,Buff[i]);
	}
*/
    //for(i=0;i<32;i++){
        //memcpy(&Buff,(rt_uint8_t *)(p_ZK_ADDR+offset+i*32),1);
        beken_flash_read(FLASH_ADDR_BASE+offset,(rt_uint8_t*)MatrixBuff,32);
        //rt_kprintf("0x%2X,",Buff);
    //}

}

static int rt_hw_lcd_config(void)
{
    return RT_EOK;
}


void LCD_Set_Port8(const rt_uint8_t dat)
{
    rt_pin_write(LCD_DB0_PIN,(dat&0x01)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB1_PIN,(dat&0x02)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB2_PIN,(dat&0x04)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB3_PIN,(dat&0x08)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB4_PIN,(dat&0x10)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB5_PIN,(dat&0x20)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB6_PIN,(dat&0x40)?PIN_HIGH:PIN_LOW);
    rt_pin_write(LCD_DB7_PIN,(dat&0x80)?PIN_HIGH:PIN_LOW);

    LCD_WR_CLR;
    LCD_WR_SET;

}

void gpio_lcd_write_data(const rt_uint8_t *dat, size_t size) {
    LCD_RD_SET;
    for (int i=0;i<size;i++) {
        rt_pin_write(LCD_DB0_PIN,(dat[i]&0x01)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB1_PIN,(dat[i]&0x02)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB2_PIN,(dat[i]&0x04)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB3_PIN,(dat[i]&0x08)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB4_PIN,(dat[i]&0x10)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB5_PIN,(dat[i]&0x20)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB6_PIN,(dat[i]&0x40)?PIN_HIGH:PIN_LOW);
        rt_pin_write(LCD_DB7_PIN,(dat[i]&0x80)?PIN_HIGH:PIN_LOW);

     LCD_WR_CLR;
     LCD_WR_SET;
    }
}

static void lcd_write_cmd(const rt_uint8_t cmd)
{
    LCD_CS_CLR;
    LCD_RS_CLR;     //RS=0,命令

    LCD_Set_Port8(cmd);

    LCD_CS_SET;
    //return RT_EOK;
}

static void lcd_write_data(const rt_uint8_t data)
{
    LCD_Set_Port8(data);
}

static rt_err_t lcd_write_half_word(const rt_uint16_t da)
{
    rt_size_t i;
    rt_uint8_t data[2] = {0};

    data[0] = (da >> 8)&0xff;
    data[1] = da&0xff;

    LCD_CS_CLR;
    LCD_RS_SET;     //RS=1,数据

    for(i=0;i<2;i++) {
        LCD_Set_Port8(data[i]);
    }

    LCD_CS_SET;
    return RT_EOK;
}


void lcd_write_comm_word(const rt_uint16_t  cmd)
{
    rt_uint8_t c[2];
    c[0] = (cmd >> 8) & 0xFF;
    c[1] = cmd & 0xFF;

    LCD_CS_CLR;
    LCD_RS_CLR;

    gpio_lcd_write_data(c, 2);

    LCD_CS_SET;
}

void lcd_write_data_word(const rt_uint16_t  data)
{
    rt_uint8_t c[2];
    c[0] = (data >> 8) & 0xFF;
    c[1] = data & 0xFF;

    LCD_CS_CLR;
    LCD_RS_SET;

    gpio_lcd_write_data(c, 2);

    LCD_CS_SET;
}

static void lcd_write_register_word(const rt_uint8_t cmd,const rt_uint16_t data)
{
    LCD_RD_SET;
    lcd_write_comm_word(cmd);
    LCD_RD_SET;
    lcd_write_data_word(data);
}


void lcd_gpio_init(void)
{


    rt_pin_mode(LCD_CS_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_RS_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_WR_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_RST_PIN, PIN_MODE_OUTPUT);

    rt_pin_mode(LCD_RD_PIN, PIN_MODE_OUTPUT);

    rt_pin_mode(LCD_DB0_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB1_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB2_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB3_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB4_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB5_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB6_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LCD_DB7_PIN, PIN_MODE_OUTPUT);


    LCD_RD_SET;

    rt_pin_write(LCD_RST_PIN, PIN_LOW);
    //wait at least 100ms for reset
    rt_thread_delay(RT_TICK_PER_SECOND / 10);
    rt_pin_write(LCD_RST_PIN, PIN_HIGH);

    rt_kprintf("lcd_gpio_init\n");
}

int rt_hw_lcd_init(void)
{

    lcd_gpio_init();

    LCD_CS_CLR;

    lcd_write_register_word(0x10, 0x0000);
    lcd_write_register_word(0x11, 0x0000);
    lcd_write_register_word(0x12, 0x0000);
    lcd_write_register_word(0x13, 0x0000);
    lcd_write_register_word(0x14, 0x0000);
    rt_thread_mdelay(40);

    lcd_write_register_word(0x11, 0x0018);
    lcd_write_register_word(0x12, 0x6121);
    lcd_write_register_word(0x13, 0x006F);
    lcd_write_register_word(0x14, 0x495F);
    lcd_write_register_word(0x10, 0x0800);
    rt_thread_mdelay(10);
    lcd_write_register_word(0x11, 0x103B);
    rt_thread_mdelay(50);
    lcd_write_register_word(0x01, 0x021C);
    lcd_write_register_word(0x02, 0x0100);
    lcd_write_register_word(0x03, 0x1030);
    lcd_write_register_word(0x07, 0x0000);
    lcd_write_register_word(0x08, 0x0808);
    lcd_write_register_word(0x0b, 0x1100);
    lcd_write_register_word(0x0c, 0x0000);
    lcd_write_register_word(0x0f, 0x0D01);
    lcd_write_register_word(0x15, 0x0020);
    lcd_write_register_word(0x20, 0x0000);
    lcd_write_register_word(0x21, 0x0000);

    lcd_write_register_word(0x30, 0x0000);
    lcd_write_register_word(0x31, 0x00DB);
    lcd_write_register_word(0x32, 0x0000);
    lcd_write_register_word(0x33, 0x0000);

    lcd_write_register_word(0x34, 0x00DB);
    lcd_write_register_word(0x35, 0x0000);
    lcd_write_register_word(0x36, 0x00AF);
    lcd_write_register_word(0x37, 0x0000);
    lcd_write_register_word(0x38, 0x00DB);
    lcd_write_register_word(0x39, 0x0000);

    lcd_write_register_word(0x50, 0x0000);
    lcd_write_register_word(0x51, 0x0808);
    lcd_write_register_word(0x52, 0x080A);
    lcd_write_register_word(0x53, 0x000A);
    lcd_write_register_word(0x54, 0x0A08);
    lcd_write_register_word(0x55, 0x0808);
    lcd_write_register_word(0x56, 0x0000);
    lcd_write_register_word(0x57, 0x0A00);
    lcd_write_register_word(0x58, 0x0710);
    lcd_write_register_word(0x59, 0x0710);

    lcd_write_register_word(0x07, 0x0012);
    rt_thread_mdelay(50);
    lcd_write_register_word(0x07, 0x1017);
    lcd_write_cmd(0x22);
    rt_thread_mdelay(50);
    LCD_CS_SET;

    rt_kprintf("rt_hw_lcd_init\r\n");

    lcd_clear(BLUE);

     GUI_Write16CnCharMatrix(56,0,"念头通达",YELLOW,BLUE);
     GUI_Write16CnCharMatrix(0,17,"人生苦短,终归尘土",YELLOW,BLUE);
     GUI_Write16CnCharMatrix(0,34,"凭什么仙家",YELLOW,BLUE);
     GUI_Write16CnCharMatrix(0,51,"就可以遨游天地,",YELLOW,BLUE);

     GUI_Write16CnCharMatrix(0,68,"而我等凡人",YELLOW,BLUE);
     GUI_Write16CnCharMatrix(0,85,"只能做这井底之蛙?",YELLOW,BLUE);



    rt_thread_mdelay(2000);
    return RT_EOK;
}
//INIT_DEVICE_EXPORT(rt_hw_lcd_init);

/**
 * Set background color and foreground color
 *
 * @param   back    background color
 * @param   fore    fore color
 *
 * @return  void
 */
void lcd_set_color(rt_uint16_t back, rt_uint16_t fore)
{
    BACK_COLOR = back;
    FORE_COLOR = fore;
}


/**
 * Set drawing area
 *
 * @param   x1      start of x position
 * @param   y1      start of y position
 * @param   x2      end of x position
 * @param   y2      end of y position
 *
 * @return  void
 */
void lcd_address_set(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
{
    lcd_write_register_word(0x36,x2);
    lcd_write_register_word(0x37,x1);
    lcd_write_register_word(0x38,y2);
    lcd_write_register_word(0x39,y1);
    lcd_write_register_word(0x20,x1);
    lcd_write_register_word(0x21,y1);
    lcd_write_cmd(0x22);
}

/**
 * clear the lcd.
 *
 * @param   color       Fill color
 *
 * @return  void
 */
void lcd_clear(rt_uint16_t color)
{
    rt_uint16_t i, j;
    rt_uint8_t data[2] = {0};

    data[0] = color >> 8;
    data[1] = color;
    lcd_address_set(0, 0, LCD_W - 1, LCD_H - 1);

    LCD_CS_CLR;
    LCD_RS_SET;

    if(data[0]==data[1])
    {
        LCD_Set_Port8(data[0]);
        for(j = 0;j < LCD_H;j++)
        {
            for (i = 0; i < LCD_W; i++)
            {
                LCD_WR_CLR;LCD_WR_SET;
                LCD_WR_CLR;LCD_WR_SET;
            }
        }

    }
    else
    {
        for(j = 0;j < LCD_H;j++)
        {
            for (i = 0; i < LCD_W; i++)
            {
                LCD_Set_Port8(data[0]);
                LCD_Set_Port8(data[1]);
            }
        }
    }
    LCD_CS_SET;
    rt_kprintf("lcd_clear\n");
}

/**
 * display a point on the lcd.
 *
 * @param   x   x position
 * @param   y   y position
 *
 * @return  void
 */
void lcd_draw_point(rt_uint16_t x, rt_uint16_t y)
{
    lcd_address_set(x, y, x, y);
    lcd_write_half_word(FORE_COLOR);
}

/**
 * display a point on the lcd using the given colour.
 *
 * @param   x       x position
 * @param   y       y position
 * @param   color   color of point
 *
 * @return  void
 */
void lcd_draw_point_color(rt_uint16_t x, rt_uint16_t y, rt_uint16_t color)
{
    lcd_address_set(x, y, x, y);
    lcd_write_half_word(color);
}

/**
 * full color on the lcd.
 *
 * @param   x_start     start of x position
 * @param   y_start     start of y position
 * @param   x_end       end of x position
 * @param   y_end       end of y position
 * @param   color       Fill color
 *
 * @return  void



/**
 * display a line on the lcd.
 *
 * @param   x1      x1 position
 * @param   y1      y1 position
 * @param   x2      x2 position
 * @param   y2      y2 position
 *
 * @return  void
 */
void lcd_draw_line(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
{

}

/**
 * display a rectangle on the lcd.
 *
 * @param   x1      x1 position
 * @param   y1      y1 position
 * @param   x2      x2 position
 * @param   y2      y2 position
 *
 * @return  void
 */
void lcd_draw_rectangle(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
{
    lcd_draw_line(x1, y1, x2, y1);
    lcd_draw_line(x1, y1, x1, y2);
    lcd_draw_line(x1, y2, x2, y2);
    lcd_draw_line(x2, y1, x2, y2);
}

/**
 * display a circle on the lcd.
 *
 * @param   x       x position of Center
 * @param   y       y position of Center
 * @param   r       radius
 *
 * @return  void
 */
void lcd_draw_circle(rt_uint16_t x0, rt_uint16_t y0, rt_uint8_t r)
{
    int a, b;
    int di;
    a = 0;
    b = r;
    di = 3 - (r << 1);
    while (a <= b)
    {
        lcd_draw_point(x0 - b, y0 - a);
        lcd_draw_point(x0 + b, y0 - a);
        lcd_draw_point(x0 - a, y0 + b);
        lcd_draw_point(x0 - b, y0 - a);
        lcd_draw_point(x0 - a, y0 - b);
        lcd_draw_point(x0 + b, y0 + a);
        lcd_draw_point(x0 + a, y0 - b);
        lcd_draw_point(x0 + a, y0 + b);
        lcd_draw_point(x0 - b, y0 + a);
        a++;
        //Bresenham
        if (di < 0)di += 4 * a + 6;
        else
        {
            di += 10 + 4 * (a - b);
            b--;
        }
        lcd_draw_point(x0 + a, y0 + b);
    }
}

static void lcd_show_char(rt_uint16_t x, rt_uint16_t y, rt_uint8_t data, rt_uint32_t size)
{
    rt_uint8_t temp;
    rt_uint8_t num = 0;;
    rt_uint8_t pos, t;
    rt_uint16_t colortemp = FORE_COLOR;
    rt_uint8_t *font_buf = RT_NULL;

    if (x > LCD_W - size / 2 || y > LCD_H - size)return;

    data = data - ' ';

    if (size == 16)
    {
        lcd_address_set(x, y, x + size / 2 - 1, y + size - 1);//(x,y,x+8-1,y+16-1)


            /* fast show char */
            for (pos = 0; pos < size * (size / 2) / 8; pos++)
            {
                temp = asc2_1608[(rt_uint16_t)data * size * (size / 2) / 8 + pos];
                for (t = 0; t < 8; t++)
                {
                    if (temp & 0x80)colortemp = FORE_COLOR;
                    else colortemp = BACK_COLOR;
                    lcd_write_half_word(colortemp);
                    temp <<= 1;
                }
            }
        }

}


/**
 * display the string on the lcd.
 *
 * @param   x       x position
 * @param   y       y position
 * @param   size    size of font
 * @param   p       the string to be display
 *
 * @return   0: display success
 *          -1: size of font is not support
 */
rt_err_t lcd_show_string(rt_uint16_t x, rt_uint16_t y, rt_uint32_t size, const char *fmt, ...)
{
#define LCD_STRING_BUF_LEN 128

    va_list args;
    rt_uint8_t buf[LCD_STRING_BUF_LEN] = {0};
    rt_uint8_t *p = RT_NULL;

    if (size != 16 && size != 24 && size != 32)
    {
        LOG_E("font size(%d) is not support!", size);
        return -RT_ERROR;
    }

    va_start(args, fmt);
    rt_vsnprintf((char *)buf, 100, (const char *)fmt, args);
    va_end(args);

    p = buf;
    while (*p != '\0')
    {
        if (x > LCD_W - size / 2)
        {
            x = 0;
            y += size;
        }
        if (y > LCD_H - size)
        {
            y = x = 0;
            lcd_clear(RED);
        }
        lcd_show_char(x, y, *p, size);
        x += size / 2;
        p++;
    }

    return RT_EOK;
}

/**
 * display the number on the lcd.
 *
 * @param   x       x position
 * @param   y       y position
 * @param   num     number
 * @param   len     length of number
 * @param   size    size of font
 *
 * @return  void
 */
void lcd_show_num(rt_uint16_t x, rt_uint16_t y, rt_uint32_t num, rt_uint8_t len, rt_uint32_t size)
{
    lcd_show_string(x, y, size, "%d", num);
}

/**
 * display the string on the lcd.
 *
 * @param   x       x position
 * @param   y       y position
 * @param   size    size of font
 * @param   p       the string to be display
 *
 * @return   0: display success
 *          -1: size of font is not support
 */

/**
 * display the image on the lcd.
 *
 * @param   x       x position
 * @param   y       y position
 * @param   length  length of image
 * @param   wide    wide of image
 * @param   p       image
 *
 * @return   0: display success
 *          -1: the image is too large
 */
rt_err_t lcd_show_image(rt_uint16_t x, rt_uint16_t y, rt_uint16_t length, rt_uint16_t wide, const rt_uint8_t *p)
{

    return RT_EOK;
}




void GUI_Write16CnCharMatrix(rt_uint16_t x, rt_uint16_t y,const rt_uint8_t *cn, rt_uint16_t wordColor, rt_uint16_t backColor)
{
    rt_uint16_t i, j, wordNum,mx,my;
	rt_uint16_t zm;
    rt_uint16_t color;

    mx=x;
    my=y;
    while (*cn != '\0')
    {
        if(*cn<128){
            lcd_show_char(mx,my,*cn,16);

            mx+= 8;
            cn+=1;
            continue;
        }
        lcd_address_set(mx, my, mx+15, my+15);
						zm=*cn;
						zm<<=8;
						zm|=*(cn+1);

						getMatrix(zm);


                for(i=0; i<32; i++)
                {   //MSK的位数
                    color=MatrixBuff[i];
                    for(j=0;j<8;j++)
                    {
                        if((color&0x80)==0x80)
                        {
                            lcd_write_data_word(wordColor);
                        }
                        else
                        {
                            lcd_write_data_word(backColor);
                        }
                        color<<=1;
                    }//for(j=0;j<8;j++)结束
                }


        cn += 2;
        mx += 16;
    }
}


void GUI_Write16CnChar(rt_uint16_t x, rt_uint16_t y, const unsigned char *cn, rt_uint16_t wordColor, rt_uint16_t backColor)
{
    rt_uint8_t i, j, wordNum;
    rt_uint8_t color;

    rt_uint8_t buf[100] = {0};
    rt_uint8_t *p = RT_NULL;

    rt_sprintf((char *)buf, "%s", cn);
    //rt_kprintf("[GUI_Write16CnChar]:%s\r\n",buf);
    p = buf;
    while (*p != '\0')
    {
        //rt_kprintf("p: %c%c,",(unsigned char *)*p,(unsigned char *)*(p+1));
        lcd_address_set(x, y, x+15, y+15);
        for (wordNum=0; wordNum<(sizeof(CnChar16x16) / sizeof(CnChar16x16[0])); wordNum++)
        {   //wordNum扫描字库的字数
            if ((CnChar16x16[wordNum].Index[0]==*p)
                 &&(CnChar16x16[wordNum].Index[1]==*(p+1)))
            {
                for(i=0; i<32; i++)
                {   //MSK的位数
                    color=CnChar16x16[wordNum].Msk[i];
                    for(j=0;j<8;j++)
                    {
                        if(color&0x80)
                        {
                            lcd_write_data_word(wordColor);
                        }
                        else
                        {
                            lcd_write_data_word(backColor);
                        }
                        color<<=1;
                    }//for(j=0;j<8;j++)结束
                }
            }
        } //for (wordNum=0; wordNum<20; wordNum++)结束
        p += 2;
        x += 16;
    }
}


void GUI_Write16CnCharTest(rt_uint16_t x, rt_uint16_t y, rt_uint16_t wordColor, rt_uint16_t backColor)
{
    rt_uint16_t i, j;
    unsigned char color;


    lcd_address_set(x, y, x+15, y+15);

    //rt_kprintf("");
    for(i=0; i<32; i++)
    {   //MSK的位数
        color=MatrixBuff[i];
        //rt_kprintf("0x%02X,",color);

        for(j=0;j<8;j++)
        {
            if(color&0x80)
            {
                lcd_write_data_word(wordColor);
            }
            else
            {
                lcd_write_data_word(backColor);
            }
            color<<=1;
        }//for(j=0;j<8;j++)结束
    }
    //rt_kprintf("\r\n");

}






void lcd_thread_entry(void *parameter)
{
    rt_uint8_t i,j,k;
    rt_hw_lcd_init();
    rt_uint32_t address;

    time_t now;
	struct tm *tm;
    char result[20];

    while(1)
    {
        now = time(RT_NULL);
		tm = localtime(&now);
        sprintf(result, "%02d时%02d分%02d秒",
           tm->tm_hour, tm->tm_min, tm->tm_sec);

        GUI_Write16CnCharMatrix(40,83+34,result,MAGENTA,BLUE);

        sprintf(result, "%04d年%02d月%02d日",
           tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);

        GUI_Write16CnCharMatrix(39,85+17,result,MAGENTA,BLUE);

        rt_thread_delay(rt_tick_from_millisecond(1000));
    }


}

int lcd_sample(void)
{



    tid = rt_thread_create("lcd",
                           lcd_thread_entry,
                           RT_NULL,
                           1024*100,
                           1,
                           5);

    if (tid != RT_NULL)
        rt_thread_startup(tid);


    return 0;
}


int lcd_del(void)
{
    rt_thread_delete(tid);
    return 0;
}


FINSH_FUNCTION_EXPORT_ALIAS(lcd_sample, __cmd_lcd, lcd sample);
FINSH_FUNCTION_EXPORT_ALIAS(lcd_del, __cmd_lcddel, lcd_del sample );

drv_lcd.h

#ifndef __DRV_LCD_H__
#define __DRV_LCD_H__

#include <rtthread.h>
#ifdef PKG_USING_QRCODE
#include <qrcode.h>
#endif

#define LCD_W 176
#define LCD_H 220

//POINT_COLOR
#define WHITE            0xFFFF
#define BLACK            0x0000
#define BLUE             0x001F
#define BRED             0XF81F
#define GRED             0XFFE0
#define GBLUE            0X07FF
#define RED              0xF800
#define MAGENTA          0xF81F
#define GREEN            0x07E0
#define CYAN             0x7FFF
#define YELLOW           0xFFE0
#define BROWN            0XBC40
#define BRRED            0XFC07
#define GRAY             0X8430
#define GRAY175          0XAD75
#define GRAY151          0X94B2
#define GRAY187          0XBDD7
#define GRAY240          0XF79E

int rt_hw_lcd_init(void);
void lcd_gpio_init(void);
void lcd_clear(rt_uint16_t color);
void lcd_address_set(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2);
void lcd_set_color(rt_uint16_t back, rt_uint16_t fore);

void lcd_draw_point(rt_uint16_t x, rt_uint16_t y);
void lcd_draw_point_color(rt_uint16_t x, rt_uint16_t y, rt_uint16_t color);
void lcd_draw_circle(rt_uint16_t x0, rt_uint16_t y0, rt_uint8_t r);
// void lcd_draw_line(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2);
// void lcd_draw_rectangle(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2);
// void lcd_fill(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, rt_uint16_t color);

void GUI_Write16CnChar(rt_uint16_t x, rt_uint16_t y, const unsigned char *cn, rt_uint16_t wordColor, rt_uint16_t backColor);
void GUI_Write16CnCharMatrix(rt_uint16_t x, rt_uint16_t y,const rt_uint8_t *cn, rt_uint16_t wordColor, rt_uint16_t backColor);
void lcd_show_num(rt_uint16_t x, rt_uint16_t y, rt_uint32_t num, rt_uint8_t len, rt_uint32_t size);
rt_err_t lcd_show_string(rt_uint16_t x, rt_uint16_t y, rt_uint32_t size, const char *fmt, ...);
// rt_err_t lcd_show_image(rt_uint16_t x, rt_uint16_t y, rt_uint16_t length, rt_uint16_t wide, const rt_uint8_t *p);
#ifdef PKG_USING_QRCODE
rt_err_t lcd_show_qrcode(rt_uint16_t x, rt_uint16_t y, rt_uint8_t version, rt_uint8_t ecc, const char *data, rt_uint8_t enlargement);
#endif

void lcd_enter_sleep(void);
void lcd_exit_sleep(void);
void lcd_display_on(void);
void lcd_display_off(void);

#endif

三、总结

1、这个字库偏移的计算公式:

    if(GBH>=0xb0)

    {

        offset=((GBH-0xa7)*94+GBL-0xa1)*34;

    }else

    {

        offset=((GBH-0xa1)*94+GBL-0xa1)*34;

    }

2、 drv_lcd.c、drv_lcd.h文件放在bk7231u_rtt_sdk\drivers中。

3、msh中键入lcd运行

msh />lcd
msh />

4、 user_app_start(void)中加入lcd_sample()可以在开机后直接驱动LCD显示

extern int lcd_sample(void);

void user_app_start(void)

{

    rt_hw_wdg_start(0, NULL);

    lcd_sample();         //前面加extern

}

5、**\bk7231u_rtt_sdk\beken378\app\config中sys_config.h需做如下修改:

#define CFG_JTAG_ENABLE                            0

这样JTAG的pin复用为普通GPIO ,用于LCD驱动。