本文基于u8g2绘图库,用C语言实现了部分基础的动画效果
使用硬件为stm32f103zet6,即正点原子精英开发版;和0.96寸oled屏iic驱动
使用该动画库前,需要读者自行移植u8g2,并配置底层驱动(通信、延时等),为了实现高帧率,推荐采取SPI+DMA的方式驱动屏幕
此外,由于本库只进行了基础的性能优化,对于一些硬件较差的平台,可能效率不佳;代码有不足之处,还请大佬们多多指教
动图中,依次调用了 逐字打印、收缩清屏、闪烁、发散显示、滑动字符串 和 缓动函数控制图形实现弹跳效果。
/*
动效 - 逐字符显示字符串
参数: x/y - 打印位置左下角坐标
*text - 要打印的字符
space - 字符间隔
delay - 打印时间间隔
tip:需要在函数外部设置字体
*/
void PrintStr_CharByChar(u8g2_t *u8g2, uint8_t x, uint8_t y, uint8_t* text,uint8_t space, uint16_t delayMS){
uint8_t text_len;
text_len = strlen(text);
for(uint8_t i = 0; i < text_len; i++){
u8g2_DrawGlyph(u8g2, x + space * i, y, text[i]);
u8g2_SendBuffer(u8g2);
HAL_Delay(delayMS); //这个延时要短一些才有流畅的转换效果
}
}
很基础的动效,需要在调用前先设置气体,space间隔的选取需要考虑到使用的字体宽度。需要注意的是,u8g2的字体库中,并不是 所有的字体 中的字母 都等宽。
调用格式如下:
u8g2_SetFont(&my_u8g2, u8g2_font_8x13B_tr);
PrintStr_CharByChar(&my_u8g2, 10, 10, "test string", 8, 100);
typedef enum{
CLEAR_LEFT,
CLEAR_RIGHT,
CLEAR_UP,
CLEAR_DOWN
} LinearClearDirction;
void LinearClearScreen(u8g2_t *u8g2, LinearClearDirction direction, uint8_t speed, uint16_t delayMS){
int screenWidth = u8g2_GetDisplayWidth(u8g2);
int screenHeight = u8g2_GetDisplayHeight(u8g2);
int x, y;
u8g2_SetDrawColor(u8g2, 0); //设置绘图颜色为黑色
switch (direction) {
case CLEAR_LEFT:
for (x = 0; x < screenWidth; x += speed) {
u8g2_DrawBox(u8g2, 0, 0, x, screenHeight);
u8g2_SendBuffer(u8g2);
HAL_Delay(delayMS);
}
break;
case CLEAR_RIGHT:
for (x = screenWidth - 1; x >= 0; x -= speed) {
u8g2_DrawBox(u8g2, x, 0, screenWidth, screenHeight);
u8g2_SendBuffer(u8g2);
HAL_Delay(delayMS);
}
break;
case CLEAR_UP:
for (y = 0; y < screenHeight; y += speed) {
u8g2_DrawBox(u8g2, 0, 0, screenWidth, y);
u8g2_SendBuffer(u8g2);
HAL_Delay(delayMS);
}
break;
case CLEAR_DOWN:
for (y = screenHeight - 1; y >= 0; y -= speed) {
u8g2_DrawBox(u8g2, 0, y, screenWidth, screenHeight);
u8g2_SendBuffer(u8g2);
HAL_Delay(delayMS);
}
break;
}
u8g2_ClearBuffer(u8g2);
u8g2_SendBuffer(u8g2);
// 恢复正常绘图模式
u8g2_SetDrawColor(u8g2, 1);
}
调用动画前,需要缓冲区存在待清屏的图像。效果就是屏幕一边缘,向另一层逐渐清除屏幕内容
PrintStr_CharByChar(&my_u8g2, 10, 10, "test string", 8, 100); //清屏对象
LinearClearScreen(&my_u8g2, CLEAR_UP, 2, 10);
typedef void (*DrawFuncCallback)(