stm32移植u8g2显示库(spi驱动st7567)

U8G2是一个开源的单色图形显示库,除了在arduino框架下使用外,U8G2还在GitHub上上传了所有的源码,方便我们移植到其他平台(源码地址)我手上的lcd屏幕为st7567驱动,目前该驱动的移植资料较少,所以发出来供大家参考。


一、提示

移植st7567驱动的lcd的方法与ssd1306驱动芯片的OLED的移植方法大体相同,具体可看这篇文章文章地址,本文仅指出不同点。

二、去掉无用的驱动文件

下载源码后,我们仅需要留下st7567的驱动文件并导入即可。
在这里插入图片描述

三、修改u8g2_d_setup.c

根据我的尝试,发现只有使用SPI通信协议的初始化函数可用,所以我们保留使用SPI的初始化函数,如下,其他可删除

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

u8g2_d_memory.c中的程序不能全部保留,否则单片机会内存爆炸,所以我们仅需要保留u8g2_Setup_st7567_jlx12864_f()函数中使用到的u8g2_m_16_8_f()函数

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
}

四、提供接口函数

我们这里只需要编写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)中的u8x8_msg_cb gpio_and_delay_cb函数
官方也提供了移植帮助文档(帮助文档地址

1.初始化GPIO

首先我们先把所有的驱动引脚配置为推挽输出或者上拉输出模式
宏定义:

/* 宏定义 --------------------------------------------------------------------*/
#define PORT_LCD_LED              GPIOA
#define PIN_LCD_LED               GPIO_Pin_0

#define PORT_LCD_MOSI             GPIOA
#define PIN_LCD_MOSI              GPIO_Pin_1

#define PORT_LCD_SCK              GPIOA
#define PIN_LCD_SCK               GPIO_Pin_2

#define PORT_LCD_RST              GPIOA
#define PIN_LCD_RST               GPIO_Pin_11

#define PORT_LCD_RS               GPIOA
#define PIN_LCD_RS                GPIO_Pin_12

#define PORT_LCD_CS               GPIOA
#define PIN_LCD_CS                GPIO_Pin_15

初始化:

void GPIO_Basic_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
  GPIO_InitStructure.GPIO_Pin =  PIN_LCD_LED;                        //引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //频率(50M)
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                   //输出类型(推挽式输出)
  GPIO_Init(PORT_LCD_LED, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  PIN_LCD_CS;                         //引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //频率(50M)
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                   //输出类型(推挽式输出)
  GPIO_Init(PORT_LCD_CS, &GPIO_InitStructure);  
  
  GPIO_InitStructure.GPIO_Pin =  PIN_LCD_SCK;                        //引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //频率(50M)
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                   //输出类型(推挽式输出)
  GPIO_Init(PORT_LCD_SCK, &GPIO_InitStructure);  
  
  GPIO_InitStructure.GPIO_Pin =  PIN_LCD_MOSI;                       //引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //频率(50M)
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                   //输出类型(推挽式输出)
  GPIO_Init(PORT_LCD_MOSI, &GPIO_InitStructure);  
  
  GPIO_InitStructure.GPIO_Pin =  PIN_LCD_RS;                         //引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //频率(50M)
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                   //输入类型(上拉输出)
  GPIO_Init(PORT_LCD_RS, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  PIN_LCD_RST;                         //引脚
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //频率(50M)
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                   //输入类型(上拉输出)
  GPIO_Init(PORT_LCD_RST, &GPIO_InitStructure);
  GPIO_SetBits(PORT_LCD_RST, PIN_LCD_RST);

}

2.编写u8x8_msg_cb gpio_and_delay_cb

这里我将这个函数命名为u8g2_gpio_and_delay_stm32,我们在这个函数中需要提供延时函数接口以及spi和GPIO驱动的函数接口,注意这里使用的是spi通信协议,与iic的代码不同

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:
      s_spi_init(&lcd_s_spi,PORT_LCD_CS,PIN_LCD_CS,
				PORT_LCD_SCK,
                PIN_LCD_SCK,				
				PORT_LCD_MOSI,
                PIN_LCD_MOSI,
				NULL,
                NULL);
      break;
	//Function which implements a delay, arg_int contains the amount of ms
	case U8X8_MSG_DELAY_MILLI:
      delay_ms(arg_int);
      break;
	//Function which delays 10us
    case U8X8_MSG_DELAY_10MICRO:
	  delay_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) GPIO_SetBits(PORT_LCD_SCK, PIN_LCD_SCK);
	  else GPIO_ResetBits(PORT_LCD_SCK, PIN_LCD_SCK);
      break;
    //Function to define the logic level of the data line to the display
	case U8X8_MSG_GPIO_SPI_DATA:
  	  if(arg_int) GPIO_SetBits(PORT_LCD_MOSI, PIN_LCD_MOSI);
      else GPIO_ResetBits(PORT_LCD_MOSI, PIN_LCD_MOSI);
	  break;
    // Function to define the logic level of the CS line
	case U8X8_MSG_GPIO_CS:
	  if(arg_int) GPIO_SetBits(PORT_LCD_CS ,PIN_LCD_CS);
	  else GPIO_ResetBits(PORT_LCD_CS, PIN_LCD_CS);
	  break;
	//Function to define the logic level of the Data/ Command line
	case U8X8_MSG_GPIO_DC:
	  if(arg_int) GPIO_SetBits(PORT_LCD_RS,PIN_LCD_RS);
	  else GPIO_ResetBits(PORT_LCD_RS,PIN_LCD_RS);
	  break;
	//Function to define the logic level of the RESET line
	case U8X8_MSG_GPIO_RESET:
	  if(arg_int) GPIO_SetBits(PORT_LCD_RST,PIN_LCD_RST);
	  else GPIO_ResetBits(PORT_LCD_RST,PIN_LCD_RST);
	  break;
	default:
	  return 0; //A message was received which is not implemented, return 0 to indicate an error
	}
	return 1; // command processed successfully.
}

五、U8G2初始化

到了这一步,移植的函数编写已经完成,我们只需要在主函数中添加初始化代码即可完成移植工作

u8g2_Setup_st7567_jlx12864_f(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8g2_gpio_and_delay_stm32); // 初始化 u8g2 结构体
u8g2_InitDisplay(&u8g2);// 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
u8g2_SetPowerSave(&u8g2, 0); // 唤醒显示器
u8g2_SetContrast(&u8g2, 100);//设置对比度
u8g2_ClearBuffer(u8g2);//清除显示缓存

在这里插入图片描述

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STMicroelectronics(ST)是一家微控制器和半导体解决方案的供应商,其产品STM32是一种功能强大的微控制器系列。U8g2是一款开源的用于驱动显示屏的,它提供了对许多不同显示屏的支持。在STM32移植U8g2并使用软件模拟SPI的方法如下: 首先,在STM32的开发环境中创建一个新的项目,并包含U8g2的文件。确保安装了适用于STM32的C编译器和开发工具。 然后,阅读U8g2的文档,了解如何在STM32上使用软件模拟的SPI进行通信。通常,这涉及到定义和配置GPIO引脚,以及模拟SPI时钟、数据线和片选线等。 接下来,使用STM32的GPIO函数进行引脚的初始化和配置。根据U8g2的文档,将相关的GPIO引脚配置为软件模拟SPI所需的输入和输出。 然后,根据U8g2的文档,编写适配代码来实现软件模拟的SPI通信。这涉及到模拟SPI时钟、数据线和片选线的读写操作。可以使用STM32的GPIO函数来控制引脚的电平。 最后,根据项目的需求,使用U8g2的函数来初始化和控制显示屏。这些函数通常包括设置显示屏的尺寸、清除屏幕内容、绘制图形和显示文本等。 在完成以上步骤后,可以使用STM32的开发工具编译和烧录代码到目标设备上,然后运行程序。如果一切顺利,显示屏应该能够正常工作,并显示预期的内容。 需要注意的是,软件模拟SPI可能会导致通信的速度较慢,因为它依赖于处理器的计算能力。如果需要更高的通信速度,可以考虑使用硬件SPI接口。 总之,将U8g2移植STM32并使用软件模拟的SPI进行通信需要对STM32的GPIO函数和U8g2的文档有一定的了解。同时,根据具体的项目需求进行适配和调试,以确保显示屏能够正确工作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值