在嵌入式系统开发中,使用单片机通过LCD屏幕显示点阵字是一个常见的任务。现代单片机具有强大的处理能力和丰富的外设接口,非常适合用于处理复杂的图形显示任务。以下是一个简单的教程,展示如何通过STM32F407驱动LCD屏幕并显示点阵字。
硬件准备:
1.STM32F407开发板:本教程使用STM32F407作为主控芯片。
2.LCD屏幕:可以选择ST7735、ILI9341等常见SPI或I2C接口的LCD屏幕。
软件准备:
1. Keil5 及STM32相关库
2. 点阵字库,通常使用的都是年代比较久远的字库文件,如:Hzk12,Hzk16,Hzk24等
3. 正点原子的LCD驱动例程
首先复制一份正点的LCD例程,先编译运行一下,确定可以在你手中的开发板上正常运行和显示,后面会基于这个代码修改LCD.c中的接口,以便支持点阵字的显示.
另外,还要先初始化SD驱动,这部分代码也可以从正点的例程中找到,整合到LCD例程中初始化好就可以了.
TF卡中预先拷贝好字库文件,存放在根目录即可.
打开LCD.C文件,将以下代码直接复制到里面空白处.
void LCD_ShowCN(FIL *fp, const uint8_t size, const char *str, uint16_t x, uint16_t y, uint16_t color)
{
unsigned char key[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
uint32_t i, j, k, offset;
uint32_t idx = 0, br;
uint32_t len = strlen(str);
uint8_t buffer[128]; // 最大32x32的字模数据
uint8_t fsize = size;
uint8_t cnt = (fsize / 8 + ((fsize % 8) ? 1 : 0));
uint8_t csize = cnt * (fsize);
while (idx < len - 1)
{
if (str[idx] & 0x80)
{
offset = (94 * (uint32_t)(str[idx] - 0xa1) + (str[idx + 1] - 0xa1)) * csize;
f_lseek(fp, offset);
f_read(fp, buffer, csize, &br);
for (k = 0; k < fsize; k++)
{
for (j = 0; j < cnt; j++)
{
for (i = 0; i < 8; i++)
{
if (buffer[k * cnt + j] & key[i])
{
LCD_Fast_DrawPoint(x + i + j * 8, y + k, color);
}
}
}
}
x += fsize;
idx += 2;
}
else
{
POINT_COLOR=color;
LCD_ShowChar(x, y, str[idx], size, 1);
idx++;
x += size / 2;
}
}
}
打开main.c 对其中内容进行修改如下:
SD_Init();
exfuns_init(); //为fatfs相关变量申请内存
f_mount(fs[0],"0:",1); //挂载SD卡
exf_getfree("0",&total,&free2); //得到SD卡的总容量和剩余容量
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,196,200,16,16,"FATFS OK!");
LCD_ShowString(30,216,200,16,16,"SD Total Size: MB");
LCD_ShowString(30,232,200,16,16,"SD Free Size: MB");
LCD_ShowNum(30+8*14,216,total>>10,5,16); //显示SD卡总容量 MB
LCD_ShowNum(30+8*14,232,free2>>10,5,16); //显示SD卡剩余容量 MB
以上是对TF卡初始化并检测卡容量,如果检测出错要先解决这个问题才能继续后面的.
紧接着增加以下代码:
uint8_t size=12;
FIL *fp=GetFont(size);
if(fp)
{
LCD_ShowCN(fp,size,"中文12x12点阵字体",2,50,RED);
f_close(fp);
free(fp);
}
fp=NULL;
size=14;
fp=GetFont(size);
if(fp)
{
LCD_ShowCN(fp,size,"中文14x14点阵字体",2,65,RED);
f_close(fp);
free(fp);
}
fp=NULL;
size=16;
fp=GetFont(size);
if(fp)
{
LCD_ShowCN(fp,size,"中文16x16点阵字体",2,82,RED);
f_close(fp);
free(fp);
}
fp=NULL;
size=24;
fp=GetFont(size);
if(fp)
{
LCD_ShowCN(fp,size,"中文24x24点阵字体",2,108,RED);
f_close(fp);
free(fp);
}
fp=NULL;
size=32;
fp=GetFont(size);
if(fp)
{
LCD_ShowCN(fp,size,"中文32x32点阵字体",2,142,RED);
f_close(fp);
free(fp);
}
fp=NULL;
while(1);
这部分代码分别读取指定字库并显示在LCD上. 需要说明一点的是,这里是作为简单演示代码,所以点阵数据是从tf卡读取的,这样效率低不说,速度还很慢,正式应用时需要将字库文件预存到片外FLASH中.
另外补上GetFont()接口,这个 也只是为了方便打开不同字库文件用的,仅作为参考:
FIL *GetFont(uint8_t size)
{
char buf[20]={0};
if(size>=24)
{
sprintf(buf,"0:hzk%d",size);
}
else
{
sprintf(buf,"0:hzk%d.bin",size);
}
FIL *fp=malloc(sizeof(FIL*));
if(f_open(fp,buf,FA_READ)!=FR_OK)
{
free(fp);
fp=NULL;
LCD_ShowString(30,10,200,16,16,"ERROR!");
}
return fp;
}
按照以上代码修改后,可以编译烧录了,运行结果如图:
2024/12/03 14:59
全部评论