00 U8G2移植到STM32(GPIO模拟SPI)

U8G2移植到STM32(GPIO模拟SPI)


1.硬件电路

  • 使用STM32C8T6来移植U8G2
  • LCD屏,单色12864lcd液晶屏,厂家是深圳思迈微电子,驱动芯片是ST7567,购买链接:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.121d2e8d7OvIb2&id=660349996995&_u=72gg942t051a
    LCD屏使用SPI接口,屏资料如下:
    在这里插入图片描述
    在这里插入图片描述
  • STM32C8T6使用GPIO口模拟SPI来与LCD屏通信,使用的IO口如下:
#define SPI_LCD_CONTROL			PAout(0)
#define	SPI_LCD_LED_A			PAout(6)

#define SPI_PORT_LCD_SCK		GPIOA
#define SPI_PIN_LCD_SCK			GPIO_Pin_4

#define SPI_PORT_LCD_SDA		GPIOA
#define SPI_PIN_LCD_SDA			GPIO_Pin_5

#define SPI_PORT_LCD_CS			GPIOA
#define SPI_PIN_LCD_CS			GPIO_Pin_1

#define SPI_PORT_LCD_DC			GPIOA
#define SPI_PIN_LCD_DC			GPIO_Pin_3

#define SPI_PORT_LCD_RES		GPIOA
#define SPI_PIN_LCD_RES			GPIO_Pin_2

2.代码移植

  • U8G2源代码下载:https://github.com/olikraus/u8g2
  • 将u8g2-master/csrc目录下的代码移植到STM32C8T6的工程目录下。
  • u8x8_d_驱动芯片型号.c是不同屏幕的驱动文件,只保留u8x8_d_st7567.c。
  • 在keil5中添加u8g2目录和头文件。
  • keil5配置好后目录结构如下:
    在这里插入图片描述

3.代码修改

  • 裁剪u8g2_d_setup.c
    u8g2_Setup_st7567_jlx12864_1
    u8g2_Setup_st7567_jlx12864_2
    u8g2_Setup_st7567_jlx12864_f
    这三个是使用SPI驱动的代码,删除其它不用的代码。
    这三个函数的区别是占用的缓冲区大小不一样,分别是128Byte,256Byte,1024Byte。

  • 在u8g2_d_setup.c中添加u8g2初始化代码

void u8g2_init(u8g2_t *u8g2)
{
	u8g2_Setup_st7567_jlx12864_f(u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8g2_gpio_and_delay); // 初始化 u8g2 结构体
	u8g2_InitDisplay(u8g2);// 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
	u8g2_SetPowerSave(u8g2, 0); // 唤醒显示器
	u8g2_SetContrast(u8g2, 100);//设置对比度
	u8g2_ClearBuffer(u8g2);//清除显示缓存
}
  • u8g2_Setup_st7567_jlx12864_f函数参数解析
    u8g2: A pointer to the u8g2 structure.
    rotation:旋转角度
    在这里插入图片描述
    byte_cb:SPI读写回调函数
    gpio_and_delay_cb:SPI GPIO操作及延时函数的回调

  • 写gpio_and_delay_cb回调函数

uint8_t u8g2_gpio_and_delay(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_gpio_spi_init();
      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(SPI_PORT_LCD_SCK, SPI_PIN_LCD_SCK);
	  else 
	  	GPIO_ResetBits(SPI_PORT_LCD_SCK, SPI_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(SPI_PORT_LCD_SDA, SPI_PIN_LCD_SDA);
      else 
	  	GPIO_ResetBits(SPI_PORT_LCD_SDA, SPI_PIN_LCD_SDA);
	  break;
    // Function to define the logic level of the CS line
	case U8X8_MSG_GPIO_CS:
	  if(arg_int) 
	  	GPIO_SetBits(SPI_PORT_LCD_CS, SPI_PIN_LCD_CS);
	  else 
	  	GPIO_ResetBits(SPI_PORT_LCD_CS, SPI_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(SPI_PORT_LCD_DC, SPI_PIN_LCD_DC);
	  else 
	  	GPIO_ResetBits(SPI_PORT_LCD_DC, SPI_PIN_LCD_DC);
	  break;
	//Function to define the logic level of the RESET line
	case U8X8_MSG_GPIO_RESET:
	  if(arg_int) 
	  	GPIO_SetBits(SPI_PORT_LCD_RES, SPI_PIN_LCD_RES);
	  else 
	  	GPIO_ResetBits(SPI_PORT_LCD_RES, SPI_PIN_LCD_RES);
	  break;
	default:
	  return 0; //A message was received which is not implemented, return 0 to indicate an error
	}
	return 1; // command processed successfully.
}
  • u8g2的坐标系如下
    在这里插入图片描述
  • 主函数添加如下代码
void draw(u8g2_t *u8g2)
{
    u8g2_SetFontMode(u8g2, 1); /*字体模式选择*/
    u8g2_SetFontDirection(u8g2, 0); /*字体方向选择*/
    u8g2_SetFont(u8g2, u8g2_font_inb24_mf); /*字库选择*/
    u8g2_DrawStr(u8g2, 0, 20, "U");
    
    u8g2_SetFontDirection(u8g2, 1);
    u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
    u8g2_DrawStr(u8g2, 21,8,"8");
        
    u8g2_SetFontDirection(u8g2, 0);
    u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
    u8g2_DrawStr(u8g2, 51,30,"g");
    u8g2_DrawStr(u8g2, 67,30,"\xb2");
    
    u8g2_DrawHLine(u8g2, 2, 35, 47);
    u8g2_DrawHLine(u8g2, 3, 36, 47);
    u8g2_DrawVLine(u8g2, 45, 32, 12);
    u8g2_DrawVLine(u8g2, 46, 33, 12);
  
    u8g2_SetFont(u8g2, u8g2_font_amstrad_cpc_extended_8r);
    u8g2_DrawStr(u8g2, 1,54,"github.x/x/u8g2");
}

int main(void)
{
	unsigned int index;
	u8g2_t u8g2;
	
	SysTick_Init(72);
	GPIO_Configuration();
  	u8g2_init(&u8g2);
	while (1)
	{
		index++;
		if(index%10000)
			PBout(12) = ~ PBin(12);
		delay_us(100);
		
		u8g2_FirstPage(&u8g2);
		do
		{
			draw(&u8g2);
		} while (u8g2_NextPage(&u8g2)); 
	}
}
draw函数是官网上面的一个demo。
  • 另外对字体库u8g2_fonts.c进行了裁剪 ,只保留的使用的字体。具体的修改请看源码。

4.移植成功后运行效果

在这里插入图片描述

5.备注

项目源码下载:
spi_lcd_u8g2_v01.rar
链接:https://pan.baidu.com/s/1ODQzlX-4O6Z5gBeAOLHorA
提取码:v1ks

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值