上期的《墨水屏电子书》过程篇2-字符显示:https://forum.eepw.com.cn/thread/384823/1展示了有关ASCII显示方法,同样基于该工程,实现中文字符显示,并通过“A”“B”“C”三个按键进行换行阅读。
首先来实现按键控制换行部分的功能,因此首当其冲就要分析按键部分的电路原理图。
根据上面电路原理图的设计,显然很容易得知,当按键“A”,“B”,“C”没有被按下时是悬空状态,为高电平。当按键“A”,“B”,“C”中某个按键按下时,则该管脚被拉低,为低电平输入。按键部分的代码实现如下:
#define PICO_SWA_PIN 12
#define PICO_SWB_PIN 13
#define PICO_SWC_PIN 14
void key_init(void){
gpio_init(PICO_SWA_PIN);
gpio_init(PICO_SWB_PIN);
gpio_init(PICO_SWC_PIN);
gpio_set_dir(PICO_SWA_PIN, GPIO_IN);
gpio_set_dir(PICO_SWB_PIN, GPIO_IN);
gpio_set_dir(PICO_SWC_PIN, GPIO_IN);
gpio_set_pulls(PICO_SWA_PIN,1, 0);
gpio_set_pulls(PICO_SWB_PIN,1, 0);
gpio_set_pulls(PICO_SWC_PIN,1, 0);
}
char get_key(void){
if(gpio_get(PICO_SWA_PIN)== 0){
return 1;
}
else if(gpio_get(PICO_SWB_PIN)== 0){
return 2;
}
else if(gpio_get(PICO_SWC_PIN)== 0){
return 3;
}
else{
return 0;
}
}工程是基于MDK5.38版本上编辑的,由“axf2uf2.bat”文件可知工程中运用了“tool”文件夹下“elf2uf2.exe”工具,实现将编译好的.axf文件转换成.uf2文件。因此“elf2uf2.exe”文件显得尤为重要,如果开发者的电脑中安装了杀毒软件(如360安全卫士),必须在编译该工程前检查“tool”文件夹下“elf2uf2.exe”是否存在,并将杀毒软件强制退出,否则该文件会被杀毒软件误删。如以下脚本所示,编译完成后,如果检测到Pico处在盘符下载模式,则会“template.uf2”文件自动拷贝到Pico的盘符根目录下。
"..\..\tool\elf2uf2.exe" .\Objects\template.axf .\template.uf2 copy/B .\template.uf2 H:\
接下来就是中文字符显示部分的功能实现,部分代码展示如下:
#include "epd2.h"
#include "epd.h"
#include "key.h"
#include "my_epd.h"
#define EPD_W 128
#define EPD_H 296
#define GB2312_FONT_W 16
#define GB2312_FONT_H 16
uint8_t Image_BW2[EPD_W*EPD_H/8];
uint8_t drawfb[EPD_H][EPD_W];
extern const unsigned char acHZK16C[];
uint16_t EPD_WidthMemory;
uint16_t EPD_HeightMemory;
unsigned char *rj_dzs;
void fb_init(){
int x,y;
for(x = 0; x < EPD_H; x++){
for(y = 0; y < EPD_W; y++){
drawfb[x][y] = 0;
}
}
EPD_HeightMemory = EPD_H;
EPD_WidthMemory = EPD_W;
if(EPD_WidthMemory % 8){
EPD_WidthMemory = EPD_W / 8 + 1;
}else{
EPD_WidthMemory = EPD_W / 8 ;
}
}
extern const unsigned char acHZK16C[];
void draw_fb_GB2132(int x, int y, int bankCode, int posCode) {
const unsigned char *pData = NULL;
unsigned char idxX, idxY;
int lineData;
int pos;
pos = ((bankCode - 0xA1) * 94 + (posCode - 0xA1)) * (GB2312_FONT_H * GB2312_FONT_W / 8);
pData = acHZK16C + pos;
for (idxY = 0; idxY < GB2312_FONT_W; idxY++) {
lineData = pData[idxY * 2];
lineData = lineData << 8;
lineData = lineData | pData[idxY * 2 + 1];
for (idxX = 0; idxX < GB2312_FONT_H; idxX++) {
if (lineData & (0x01 << idxX)) {
draw_fb_point(x + GB2312_FONT_H - idxX, y + idxY);
} else {
clear_fb_point(x + GB2312_FONT_H - idxX, y + idxY);
}
}
}
}
void draw_hanzi(int x, int y, char *data) {
int i, dataLen = My_strlen(data);
for (i = 0; i < dataLen;) {
if (data[i] > 127) {
if ((x + GB2312_FONT_H) > EPD_H) {
x = 0;
y += GB2312_FONT_W;
}
draw_fb_GB2132(x, y, data[i], data[i + 1]);
x += GB2312_FONT_H;
i += 2;
} else {
if ((x + ASCII_FONT_H) > EPD_H) {
x = 0;
y += ASCII_FONT_W;
}
draw_fb_ASCII(x, y, data[i]);
x += ASCII_FONT_H;
i++;
}
}
}
int My_strlen(char *data) {
int i = 0;
while (data[i]) {
i++;
}
return i;
}
uint8_t get_fb_to_epd(int x,int y){
uint8_t dat = 0xff;
char i;
for(i = 0; i < 8; i++){
if(drawfb[x][y*8+i]){
dat &= (~(0x80>>i));
}
}
return dat;
}
void fb_to_epddata(){
int x,y;
int index = 0;
for(x = 0; x < EPD_HeightMemory; x++){
index = x * EPD_WidthMemory;
for(y = 0; y < EPD_WidthMemory; y++){
Image_BW2[index + y] = get_fb_to_epd( x, y);
}
}
}
void draw_fb_point(int x,int y){
drawfb[OLED_H - x - 1][y] = 1;
}
void epd_init(){
OLED_GPIOInit();
EPD_2IN9D_Init();
EPD_2IN9D_Clear();
fb_init();
}
void updata_to_epd(char flag){
fb_to_epddata();
if(flag == DISPLAY_PART){
EPD_2IN9D_DisplayPart(Image_BW2);
DEV_Delay_ms(600);
}else{
EPD_2IN9D_Init();
EPD_2IN9D_Display(Image_BW2);
DEV_Delay_ms(600);
}
}
void clear_fb_point(int x, int y){
drawfb[OLED_H - x -1][y] = 0;
}main函数内容如下:
#define KEYA_MASK 1
#define KEYB_MASK 2
#define KEYC_MASK 3
int main(void)
{
volatile char key = 0x00;
unsigned short offise= 0 ;
system_init();
LED_init();
key_init();
epd_init();
while (true) {
key = get_key();
switch(key){
case KEYA_MASK:
LED_Toggle();
if(offise > 108){
offise -= 108;
draw_hanzi(0, 0, rj_dzs+offise);
}
updata_to_epd(DISPLAY_PART);
break;
case KEYB_MASK:
LED_Toggle();
offise = 0;
draw_hanzi(0, 0, rj_dzs+offise);
updata_to_epd(DISPLAY_PART);
break;
case KEYC_MASK:
LED_Toggle();
if(offise < My_strlen(rj_dzs)){
offise += 108;
draw_hanzi(0, 0, rj_dzs+offise);
}
updata_to_epd(DISPLAY_PART);
break;
default:
break;
}
}
} 编译完成后,等Pico自动重启后,则可通过按键换行阅读朱自清的《背影》了。阅读部分内容展示如下:

写到最后,小结一下:这是笔者初次通过Keil对Raspberry Pi Pico进行开发,虽然每次编译后下载到Pico开发板,都需要先按下boot按键再给Pico上电,使其进入盘符下载模式,因此感觉有点繁琐。之前基本上都是使用Thonny这类Python语言开发的IDE,这次活动也是让我受益匪浅。感谢EEPW与DigKey联合举办的DIY活动,实验的操作演示视频见B站,链接如下:
https://www.bilibili.com/video/BV1n91qYhEs8/
我要赚赏金
