![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/5db20f264fda4a2e82fd0c704226f81e.jpeg)
使用ST7567A点阵屏引用U8g2 UI 库
`项目中使用到点阵屏,现在使用u8g2做UI库,加快UI开发速度
代码有用到移植内容,可以参考
链接: 金逸晨LCD屏驱动移值 HAL金逸晨LCD点阵屏移植
移植流程
- 配置Stm32CubeMX
- 下载u8g2库 https://github.com/olikraus/u8g2
- 精简u8t6
一、保留csrc文件夹
二、csrc 文件夹u8x8_d_xxxx 只保留st7567就行
三、修改u8g2_d_setup.c
void u8g2_Setup_st7567_jlx12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{
uint8_t tile_buf_height;
uint8_t *buf;
u8g2_SetupDisplay(u8g2, u8x8_d_st7567_jlx12864, u8x8_cad_001, byte_cb, gpio_and_delay_cb);
buf = u8g2_m_16_8_f(&tile_buf_height);
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
}
四、修改u8g2_d_memory.c
uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt)
{
#ifdef U8G2_USE_DYNAMIC_ALLOC
*page_cnt = 8;
return 0;
#else
static uint8_t buf[1024];
*page_cnt = 8;
return buf;
#endif
}
五、新建一个自己的回调处理函数
uint8_t u8g2_gpio_and_delay_stm32(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
switch(msg)
{
//Initialize SPI peripheral
case U8X8_MSG_GPIO_AND_DELAY_INIT:
break;
//Function which implements a delay, arg_int contains the amount of ms
case U8X8_MSG_DELAY_MILLI:
HAL_Delay(arg_int);
break;
//Function which delays 10us
case U8X8_MSG_DELAY_10MICRO:
mdelay_us(arg_int);
break;
//Function which delays 100ns
case U8X8_MSG_DELAY_100NANO:
__NOP();;
break;
//Function to define the logic level of the clockline
case U8X8_MSG_GPIO_SPI_CLOCK:
if(arg_int)
HAL_GPIO_WritePin(OLED_SCK_GPIO_Port,OLED_SCK_Pin,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(OLED_SCK_GPIO_Port,OLED_SCK_Pin,GPIO_PIN_RESET);
break;
//Function to define the logic level of the data line to the display
case U8X8_MSG_GPIO_SPI_DATA:
if(arg_int)
HAL_GPIO_WritePin(OLED_SDA_GPIO_Port,OLED_SDA_Pin,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(OLED_SDA_GPIO_Port,OLED_SDA_Pin,GPIO_PIN_RESET);
break;
// Function to define the logic level of the CS line
case U8X8_MSG_GPIO_CS:
if(arg_int)
HAL_GPIO_WritePin(OLED_CS_GPIO_Port,OLED_CS_Pin,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(OLED_CS_GPIO_Port,OLED_CS_Pin,GPIO_PIN_RESET);
break;
break;
//Function to define the logic level of the Data/ Command line
case U8X8_MSG_GPIO_DC:
if(arg_int)
HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,GPIO_PIN_RESET);
break;
break;
//Function to define the logic level of the RESET line
case U8X8_MSG_GPIO_RESET:
if(arg_int)
HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_RESET);
break;
break;
default:
return 0; //A message was received which is not implemented, return 0 to indicate an error
}
return 1; // command processed successfully.
}
六、新建一个自己的 延时函数
void mdelay_us(uint8_t Delay)
{
uint32_t tickstart = SysTick->VAL; ///<获取当前tick
uint32_t tickNum = 0;
uint32_t tickMax = SysTick->LOAD + 1;
uint32_t delay_usvalue = (tickMax / 1000) * Delay; ///<计算一共需要延时的tick
while(1)
{
uint32_t cur_tick = SysTick->VAL;
if (cur_tick > tickstart) ///<进行了一次重载
{
tickNum = tickstart + (tickMax - cur_tick);
}
else ///<未进行过重载
{
tickNum = tickstart - cur_tick;
}
if (tickNum > delay_usvalue) ///<达到延时的tick数
{
return;
}
}
}
七,main函数
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
//LCD_init();
//初始化 u8g2, u8x8_byte_4wire_sw_spi 系统有无需自建,u8g2_gpio_and_delay_stm32刚才建的回调
u8g2_Setup_st7567_jlx12864_f(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8g2_gpio_and_delay_stm32);
u8g2_InitDisplay(&u8g2);
//启动
u8g2_SetPowerSave(&u8g2, 0);
//清屏
u8g2_ClearBuffer(&u8g2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_Delay(1000);
while (1)
{
//清屏
u8g2_FirstPage(&u8g2);
//绘制一个进度条
for(int i=10;i<=80;i=i+2)
{
u8g2_ClearBuffer(&u8g2);
char buff[20];
//设置字符类型
u8g2_SetFont(&u8g2,u8g2_font_ncenB12_tf);
u8g2_DrawStr(&u8g2,16,32,"Test Q");//字符显示
u8g2_DrawRBox(&u8g2,16,40,i,10,4);//圆角填充框矩形框
u8g2_DrawRFrame(&u8g2,16,40,80,10,4);//圆角矩形
//发送显示
u8g2_SendBuffer(&u8g2);
}
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
细节
1、 第次修改屏幕内容都需要:u8g2_SendBuffer(&u8g2); 才会执行
2、第一次打印文本要先设置文本类型: u8g2_SetFont(&u8g2,u8g2_font_ncenB12_tf);