这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【墨水屏电子书DIY】3、成果贴

共8条 1/1 1 跳转至

【墨水屏电子书DIY】3、成果贴

高工
2024-08-09 11:23:11     打赏

本次的diy活动主要的是实现电子书功能,我们分析一下具体的任务和需求以及本次提供的基础工程都有哪些。

任务分析:

1、 编程实现LED灯的闪烁。

学习GPIO输出能力的控制,该部分我们在商议章节已经实现

2、 编程实现按键控制LED灯的亮灭(按下一次LED亮,再按一次LED灭) 。

学习GPIO输出采集功能,通过上一章节综合了三个按键和LED进行了综合展示,已实现

3、 基于屏幕驱动函数(在屏幕任意位置画点)实现字符的显示,例如显示Hello EEPW & DigiKey,也可显示自己喜欢的名言警句 。

这一部分实际上是对墨水屏驱动的全面掌握,本章也重点实现对象。

4、 实现电子书基本功能,实现按键翻页(上一页、下一页等)。

电子书功能实际上是墨水屏显示和按键功能的结合,主要设计一些逻辑问题。

资源分析:

本次提供的工程中已经包含了相关的BSP基础函数文件和墨水屏的驱动文件,基本上实现了写点操作。我们需要做的实际上是着重是对引用层的实现,也就是把字如何显示在墨水屏山。

根据目前的资源来看,已经提供了一个HZK16的汉字库文件和Font_16x24_h的ASCII的点阵函数,实际上这两种字库尺寸是不匹配的,汉字库基本上是16*16的,内存中也占用的是两个字节,ASCII占用一个自己,最好是8*16的,所以这里我们使用点阵生成工具生成一个Font_8x16_h。

显示内容我们可以自行进行电子书的内容复制过来显示,不过本次提供了一个“大学之道”的数组指针,我们就把他作为电子书的内容进行展示。

到这里我们基本完成了实现前的准备工作,将任务3和任务2同时进行实现。

基本功能

开机进行初始化(LED、按键、墨水屏),然后进行墨水瓶初始化内容展示(显示Hello EEPW & DigiKey),等待按键操作;按键B开始进行电子书功能,这个时候其他按键是失效的;按键A进行上一页的操作,按键C进行下一页的操作,注意要进行防抖设计,不然会识别很多次操作。

代码实现

首先我们要实现单个ASCII字符的实现:

void draw_fb_ASCII(int x, int y, char word) {  
    const uint8_t *pData;
    uint8_t FONT_cut;
    unsigned char idxX, idxY;  
    int lineData;
    short int FONT_H,FONT_W;  

    FONT_H = ASCII_16_FONT_H;
    FONT_W = ASCII_16_FONT_W;


    for (idxY = 0; idxY < FONT_H; idxY++) { 
        if(FONT_W % 8 == 0)
{
            FONT_cut = FONT_W/8;
        }
        else
{
            FONT_cut = FONT_W/8 + 1;
        }
        for (uint8_t i = 0; i < FONT_cut; i++) {  
            lineData = lineData << 8; 
            lineData = lineData | pData[idxY * FONT_cut + FONT_cut - i - 1]; 
        } 
        for (idxX = 0; idxX < FONT_W; idxX++) {  
            if (lineData & (0x01 << idxX)) {  
                draw_fb_point(x + idxX, y + idxY);  
            } 
            else {  
                clear_fb_point(x + idxX, y + idxY);  
            }  
        }  
    }  
}

接下来是汉字单字的显示控制:

void draw_fb_GB2132(int x, int y, unsigned int bankCode, unsigned int posCode) {  
    const uint8_t *pData;  
    unsigned char idxX, idxY;  
    int lineData;  
    int pos; 
    short int FONT_H,FONT_W; 

    FONT_H = GB2312_FONT_H;
    FONT_W = GB2312_FONT_W;

    pos = ((bankCode - 0xA1) * 94 + (posCode - 0xA1)) * (FONT_H * FONT_W / 8);
    pData = acHZK16C + pos;


    for (idxY = 0; idxY < FONT_W; idxY++) {  
        lineData = pData[idxY * 2];  
        lineData = lineData << 8;  
        lineData = lineData | pData[idxY * 2 + 1];  

        for (idxX = 0; idxX < FONT_H; idxX++) {  
            if (lineData & (0x01 << idxX)) {  
                draw_fb_point(x + FONT_H - idxX, y + idxY);  
            } else {  
                clear_fb_point(x + FONT_H - idxX, y + idxY);  
            }  
        }  
    }  

}

因为ASCII和汉字的首字节的范围是不一样的,我们通过这个进行区分:

void draw_fb(int x, int y, unsigned char *data, char Mode) {  
    short int word,FONT_H,FONT_W;
    int i, dataLen = My_strlen(data);  

    for (i = 0; i < dataLen;){
        if(data[i] > 0x80){
            FONT_H = GB2312_FONT_H;
            FONT_W = GB2312_FONT_W;

            if ((x + FONT_W) > EPD_H) {  
                x = 0;

                if(y+FONT_H>=EPD_W)
            break;
            else
            y += FONT_H; 
            } 
            draw_fb_GB2132(x, y, data[i], data[i+1]);
            x += FONT_W;
            i += 2;
        }
        else{

            FONT_H = ASCII_16_FONT_H;
            FONT_W = ASCII_16_FONT_W;



            if ((x + FONT_W) > EPD_H) {  
                x = 0;  
                y += FONT_H;  
            }  
            draw_fb_ASCII(x, y, data[i]);  
            x += FONT_W;  
            i++;                 
        }
    }
    

}

接下来就是初始化以及main中的内容了,由于汉字是16*16的,所以一页屏幕可以显示144个汉字符号,对应的字节数是288个,简单实现就可以通过这种固定数字显示的方式进行:

int main(void) 
{
    system_init();      
    LED_init();
    key_init();
    epd_init();
    MY_DEV_Delay_ms(500);
    draw_fb(0, 50, "Hello EEPW & DigiKey");
    draw_fb(0, 70, "by 孤独的写手");
    updata_to_epd(DISPLAY_PART);


    LED_ON();
    while (true) {                                             
        if(gpio_get(INKY_KEYA_PIN) == 0)
{
            MY_DEV_Delay_ms(10);
            if(gpio_get(INKY_KEYA_PIN) == 0)
{
                while(gpio_get(INKY_KEYA_PIN) == 0);
                if(HZK_offise >= 288  && text_mode == 1){
                    HZK_offise -= 288;
                    draw_fb(0, 0, dx_dzs+HZK_offise,FONT_Mode);
                    updata_to_epd(DISPLAY_PART);
                }
            }
        }
        if(gpio_get(INKY_KEYB_PIN) == 0)
{
            MY_DEV_Delay_ms(10);
            if(gpio_get(INKY_KEYB_PIN) == 0)
{
                while(gpio_get(INKY_KEYB_PIN) == 0);
                
                text_mode = 1;
                HZK_offise = 0;
                draw_fb(0, 0, dx_dzs,FONT_Mode);
                updata_to_epd(DISPLAY_PART);
            }
        }
        if(gpio_get(INKY_KEYC_PIN) == 0)
{
            MY_DEV_Delay_ms(10);
            if(gpio_get(INKY_KEYC_PIN) == 0)
{
                while(gpio_get(INKY_KEYC_PIN) == 0);
                if(HZK_offise < My_strlen(dx_dzs  && text_mode == 1){
                    HZK_offise += 288;
                    draw_fb(0, 0, dx_dzs+HZK_offise,FONT_Mode);
                    updata_to_epd(DISPLAY_PART);
                }
            }
        }
    }
}

效果如下:

【Let's do第二期成果视频】 https://www.bilibili.com/video/BV1osaXeEEhd/?share_source=copy_web&vd_source=b04da51472e5874aa452f4a273672c46


高工
2024-08-09 11:24:14     打赏
2楼

高工
2024-08-09 20:58:29     打赏
3楼

感谢分享


工程师
2024-08-09 22:54:33     打赏
4楼

666666


院士
2024-08-10 12:32:47     打赏
5楼

谢谢分享,给你点赞。


专家
2024-08-10 13:38:19     打赏
6楼

感谢分享


助工
2024-08-14 10:41:48     打赏
7楼

感谢分享,赞!


高工
2024-08-16 10:50:20     打赏
8楼

恭喜顺利完成任务


共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]