Skip to content
c
#include "oled.h"
#include "main.h"
#include "stm32f1xx_hal.h"
#include "u8g2.h"
#include <math.h>
#include <stdint.h>
#include <stdlib.h>



void PCD_SendByte(uint8_t byte);


uint8_t u8x8_byte_stm32_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,void *arg_ptr){

  /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and
   * END_TRANSFER */
  uint8_t *data;


  switch (msg) {
  case U8X8_MSG_BYTE_SEND:// 发送数据
    data = (uint8_t *)arg_ptr;
    while (arg_int > 0) {
      PCD_SendByte(*data);
      data++;
      arg_int--;
    }
    break;
  case U8X8_MSG_BYTE_INIT:
    //复位
    HAL_GPIO_WritePin(PCD_RST_GPIO_Port, PCD_RST_Pin, GPIO_PIN_RESET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(PCD_RST_GPIO_Port, PCD_RST_Pin, GPIO_PIN_SET);
    break;
  case U8X8_MSG_BYTE_START_TRANSFER:// 开始传输
     //接低片选
     HAL_GPIO_WritePin(PCD_CS_GPIO_Port, PCD_CS_Pin, GPIO_PIN_RESET);
    break;
  case U8X8_MSG_BYTE_END_TRANSFER:// 结束传输
     //接高片选
     HAL_GPIO_WritePin(PCD_CS_GPIO_Port, PCD_CS_Pin, GPIO_PIN_SET);
    break;
  case U8X8_MSG_BYTE_SET_DC:// 设置Data/Cmd引脚
        HAL_GPIO_WritePin(PCD_DC_GPIO_Port, PCD_DC_Pin, arg_int>0?GPIO_PIN_SET:GPIO_PIN_RESET);
    break;
  default:
    return 0;
  }
  return 1;
}

uint8_t u8g2_gpio_and_delay_stm32_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,void *arg_ptr)
  {
    switch (msg) {
    case U8X8_MSG_DELAY_100NANO: // 延时100纳秒
      __NOP();
      break;
    case U8X8_MSG_DELAY_10MICRO: // 延时10微秒
      for (uint16_t n = 0; n < 320; n++) {
        __NOP();
      }
      break;
    case U8X8_MSG_DELAY_MILLI: // 延时arg_int毫秒
      HAL_Delay(arg_int);
      break;
    // 硬件I2C不需要以下延时和GPIO控制
    // case U8X8_MSG_DELAY_I2C: // 延时I2C时钟 - 硬件I2C不需要
    // case U8X8_MSG_GPIO_I2C_CLOCK: // 输出I2C时钟 - 硬件I2C不需要
    // case U8X8_MSG_GPIO_I2C_DATA: // 输出I2C数据 - 硬件I2C不需要
    case U8X8_MSG_GPIO_MENU_SELECT:// 获取菜单选择引脚状态
      u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
      break;
    case U8X8_MSG_GPIO_MENU_NEXT:// 获取菜单下一页引脚状态
      u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
      break;
    case U8X8_MSG_GPIO_MENU_PREV:// 获取菜单上一页引脚状态
      u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
      break;
    case U8X8_MSG_GPIO_MENU_HOME:// 获取菜单返回引脚状态
      u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
      break;
    default:
      u8x8_SetGPIOResult(u8x8, 1); // default return value
      break;
    }
    return 1;
  }


void u8g2Init(u8g2_t *u8g2){
  // u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_stm32_hw_i2c,
  //     u8g2_gpio_and_delay_stm32); // ssd1306 I2C初始化 u8g2 结构体

  // u8g2_Setup_ssd1312_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_stm32_hw_i2c,
  //     u8g2_gpio_and_delay_stm32); // ssd1312 I2C初始化 u8g2 结构体

  
  u8g2_Setup_pcd8544_84x48_f(u8g2, U8G2_R0, u8x8_byte_stm32_sw_spi,
      u8g2_gpio_and_delay_stm32_spi); // pcd8544 I2C初始化 u8g2 结构体

  //设置I2C地址(8位地址格式)
  // u8g2_SetI2CAddress(u8g2, OLED_ADDRESS<<1);


  u8g2_InitDisplay(u8g2); // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
  u8g2_SetPowerSave(u8g2, 0); // 打开显示器
  u8g2_ClearBuffer(u8g2);     // 清除缓冲区
}


void PCD_SendByte(uint8_t byte){
    // 发送数据(SPI模拟)
  for (uint8_t i = 0; i < 8; i++) {
    // 准备数据位
    if (byte & 0x80) {
      HAL_GPIO_WritePin(PCD_DATA_GPIO_Port, PCD_DATA_Pin, GPIO_PIN_SET); // 数据位为1
    } else {
      HAL_GPIO_WritePin(PCD_DATA_GPIO_Port, PCD_DATA_Pin, GPIO_PIN_RESET); // 数据位为0
    }

    // 时钟上升沿
    HAL_GPIO_WritePin(PCD_CLK_GPIO_Port, PCD_CLK_Pin, GPIO_PIN_SET);

    // 时钟下降沿,数据被采样
    HAL_GPIO_WritePin(PCD_CLK_GPIO_Port, PCD_CLK_Pin, GPIO_PIN_RESET);

    // 移动到下一位
    byte <<= 1;
  }
}