结构"/>
u8g2结构
填充结构,注册函数
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
class U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI : public U8G2 {public: U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() {u8g2_Setup_ssd1306_128x64_noname_f(
&u8g2 , rotation, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino);u8x8_SetPin_4Wire_SW_SPI(getU8x8(), clock, data, cs, dc, reset);}
}
void u8g2_Setup_ssd1306_128x64_noname_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_ssd1306_128x64_noname, 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);
}void u8g2_Setup_ssd1306_128x64_noname_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_ssd1306_128x64_noname, 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);
}
struct 结构
struct u8x8_tile_struct
{uint8_t *tile_ptr; /* pointer to one or more tiles... should be "const" */uint8_t cnt; /* number of tiles */uint8_t x_pos; /* tile x position */uint8_t y_pos; /* tile y position */
};--------------------------------------------------------------struct u8x8_struct
{const u8x8_display_info_t *display_info;u8x8_char_cb next_cb; /* procedure, which will be used to get the next char from the string */u8x8_msg_cb display_cb;u8x8_msg_cb cad_cb;u8x8_msg_cb byte_cb;u8x8_msg_cb gpio_and_delay_cb;uint32_t bus_clock; /* can be used by the byte function to store the clock speed of the bus */const uint8_t *font;uint16_t encoding; /* encoding result for utf8 decoder in next_cb */uint8_t x_offset; /* copied from info struct, can be modified in flip mode */uint8_t is_font_inverse_mode; /* 0: normal, 1: font glyphs are inverted */uint8_t i2c_address; /* a valid i2c adr. Initially this is 255, but this is set to something useful during DISPLAY_INIT *//* i2c_address is the address for writing data to the display *//* usually, the lowest bit must be zero for a valid address */uint8_t i2c_started; /* for i2c interface *///uint8_t device_address; /* OBSOLETE???? - this is the device address, replacement for U8X8_MSG_CAD_SET_DEVICE */uint8_t utf8_state; /* number of chars which are still to scan */uint8_t gpio_result; /* return value from the gpio call (only for MENU keys at the moment) */ uint8_t debounce_default_pin_state;uint8_t debounce_last_pin_state;uint8_t debounce_state;uint8_t debounce_result_msg; /* result msg or event after debounce */
#ifdef U8X8_WITH_USER_PTRvoid *user_ptr;
#endif
#ifdef U8X8_USE_PINS uint8_t pins[U8X8_PIN_CNT]; /* defines a pinlist: Mainly a list of pins for the Arduino Environment, use U8X8_PIN_xxx to access */
#endif
};------------------------------------------------------struct u8x8_display_info_struct
{/* == general == */uint8_t chip_enable_level; /* UC1601: 0 */uint8_t chip_disable_level; /* opposite of chip_enable_level */uint8_t post_chip_enable_wait_ns; /* UC1601: 5ns */uint8_t pre_chip_disable_wait_ns; /* UC1601: 5ns */uint8_t reset_pulse_width_ms; /* UC1601: 0.003ms --> 1ms */ uint8_t post_reset_wait_ms; /* UC1601: 6ms */ /* == SPI interface == *//* after SDA has been applied, wait this much time for the SCK data takeover edge *//* if this is smaller than sck_pulse_width_ns, then use the value from sck_pulse_width_ns */uint8_t sda_setup_time_ns; /* UC1601: 12ns *//* the pulse width of the the clock signal, cycle time is twice this value *//* max freq is 1/(2*sck_pulse_width_ns) *//* AVR: below 70: DIV2, 8 MHz, >= 70 --> 4MHz clock (DIV4) */uint8_t sck_pulse_width_ns; /* UC1701: 50ns *//* until here we have 8 bytes (uint8_t). Newly introduced for SPI.beginTransaction */uint32_t sck_clock_hz;/* previous name "sck_takeover_edge" renamed to "spi_mode" *//* bit 0 of spi_mode is equal to the value of the previous variable sck_takeover_edge, 20 Aug 16: This is wrong the bit is actually inverted */ /* SPI has four clock modes: *//* 0: clock active high, data out on falling edge, clock default value is zero, takover on rising edge *//* 1: clock active high, data out on rising edge, clock default value is zero, takover on falling edge *//* 2: clock active low, data out on rising edge *//* 3: clock active low, data out on falling edge *//* most displays have clock mode 1 */uint8_t spi_mode;/* == I2C == */uint8_t i2c_bus_clock_100kHz; /* UC1601: 1000000000/275 = 37 *100k *//* == 8 bit interface == *//* how long to wait after all data line are set */uint8_t data_setup_time_ns; /* UC1601: 30ns *//* write enable pulse width */uint8_t write_pulse_width_ns; /* UC1601: 40ns *//* == layout == */uint8_t tile_width;uint8_t tile_height;uint8_t default_x_offset; /* default x offset for the display */uint8_t flipmode_x_offset; /* x offset, if flip mode is enabled *//* pixel width is not used by the u8x8 procedures *//* instead it will be used by the u8g2 procedures, because the pixel dimension can *//* not always be calculated from the tile_width/_height *//* the following conditions must be true: *//* pixel_width <= tile_width*8 *//* pixel_height <= tile_height*8 */uint16_t pixel_width;uint16_t pixel_height;
};
u8x8_byte_arduino_hw_spi 具体实现
U8x8lib.cppextern "C" uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
#ifdef U8X8_HAVE_HW_SPI#if !defined(ESP_PLATFORM)uint8_t *data;
#endifuint8_t internal_spi_mode;switch(msg){case U8X8_MSG_BYTE_SEND:#if defined(ESP_PLATFORM)//T.M.L 2023-02-28: use the block transfer function on ESP, which does not overwrite the buffer.SPI.writeBytes((uint8_t*)arg_ptr, arg_int);
#else // 1.6.5 offers a block transfer, but the problem is, that the// buffer is overwritten with the incoming data// so it can not be used...// SPI.transfer((uint8_t *)arg_ptr, arg_int);data = (uint8_t *)arg_ptr;while( arg_int > 0 ){SPI.transfer((uint8_t)*data);data++;arg_int--;}
#endifbreak;case U8X8_MSG_BYTE_INIT:if ( u8x8->bus_clock == 0 ) /* issue 769 */u8x8->bus_clock = u8x8->display_info->sck_clock_hz;/* disable chipselect */u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);/* no wait required here *//* for SPI: setup correct level of the clock signal */// removed, use SPI.begin() instead: pinMode(11, OUTPUT);// removed, use SPI.begin() instead: pinMode(13, OUTPUT);// removed, use SPI.begin() instead: digitalWrite(13, u8x8_GetSPIClockPhase(u8x8));/* setup hardware with SPI.begin() instead of previous digitalWrite() and pinMode() calls *//* issue #377 *//* issue #378: removed ESP8266 support, which is implemented differently */
#if defined(ESP_PLATFORM) || defined(ARDUINO_ARCH_ESP32)/* ESP32 has the following begin: SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); *//* not sure about ESP8266 */if ( u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE ){/* SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); *//* actually MISO is not used, but what else could be used here??? */SPI.begin(u8x8->pins[U8X8_PIN_SPI_CLOCK], MISO, u8x8->pins[U8X8_PIN_SPI_DATA]);}else{SPI.begin();}
#elseSPI.begin();
#endif break;case U8X8_MSG_BYTE_SET_DC:u8x8_gpio_SetDC(u8x8, arg_int);break;case U8X8_MSG_BYTE_START_TRANSFER:/* SPI mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */internal_spi_mode = 0;switch(u8x8->display_info->spi_mode){case 0: internal_spi_mode = SPI_MODE0; break;case 1: internal_spi_mode = SPI_MODE1; break;case 2: internal_spi_mode = SPI_MODE2; break;case 3: internal_spi_mode = SPI_MODE3; break;}#if ARDUINO >= 10600SPI.beginTransaction(SPISettings(u8x8->bus_clock, MSBFIRST, internal_spi_mode));
#elseSPI.begin();if ( u8x8->display_info->sck_pulse_width_ns < 70 )SPI.setClockDivider( SPI_CLOCK_DIV2 );else if ( u8x8->display_info->sck_pulse_width_ns < 140 )SPI.setClockDivider( SPI_CLOCK_DIV4 );elseSPI.setClockDivider( SPI_CLOCK_DIV8 );SPI.setDataMode(internal_spi_mode);SPI.setBitOrder(MSBFIRST);
#endifu8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level); u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);break;case U8X8_MSG_BYTE_END_TRANSFER: u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);#if ARDUINO >= 10600SPI.endTransaction();
#elseSPI.end();
#endifbreak;default:return 0;}#else /* U8X8_HAVE_HW_SPI */#endif /* U8X8_HAVE_HW_SPI */return 1;
}
u8x8_d_ssd1306_128x64_noname
uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )return 1;switch(msg){case U8X8_MSG_DISPLAY_INIT:u8x8_d_helper_display_init(u8x8);u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq); break;case U8X8_MSG_DISPLAY_SETUP_MEMORY:u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);break;default:return 0;}return 1;
}uint8_t u8x8_d_ssd1312_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{switch(msg){case U8X8_MSG_DISPLAY_SET_FLIP_MODE:if ( arg_int == 0 ){u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_flip0_seq);u8x8->x_offset = u8x8->display_info->default_x_offset;}else{u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_flip1_seq);u8x8->x_offset = u8x8->display_info->flipmode_x_offset;}break;case U8X8_MSG_DISPLAY_INIT:u8x8_d_helper_display_init(u8x8);u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_init_seq); /* update 27 mar 2022 */break;case U8X8_MSG_DISPLAY_SETUP_MEMORY:u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);break;default:if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )return 1;}return 1;
}
extern "C" uint8_t u8x8_gpio_and_delay_arduino(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{uint8_t i;switch(msg){case U8X8_MSG_GPIO_AND_DELAY_INIT:for( i = 0; i < U8X8_PIN_CNT; i++ )if ( u8x8->pins[i] != U8X8_PIN_NONE ){if ( i < U8X8_PIN_OUTPUT_CNT ){pinMode(u8x8->pins[i], OUTPUT);}else{
#ifdef INPUT_PULLUPpinMode(u8x8->pins[i], INPUT_PULLUP);
#elsepinMode(u8x8->pins[i], OUTPUT);digitalWrite(u8x8->pins[i], 1);
#endif }}break;#ifndef __AVR__ /* this case is not compiled for any AVR, because AVR uC are so slow *//* that this delay does not matter */case U8X8_MSG_DELAY_NANO:delayMicroseconds(arg_int==0?0:1);break;
#endifcase U8X8_MSG_DELAY_10MICRO:/* not used at the moment */break;case U8X8_MSG_DELAY_100NANO:/* not used at the moment */break;case U8X8_MSG_DELAY_MILLI:delay(arg_int);break;case U8X8_MSG_DELAY_I2C:/* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */delayMicroseconds(arg_int<=2?5:2);break;case U8X8_MSG_GPIO_I2C_CLOCK:case U8X8_MSG_GPIO_I2C_DATA:if ( arg_int == 0 ){pinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);digitalWrite(u8x8_GetPinValue(u8x8, msg), 0);}else{
#ifdef INPUT_PULLUPpinMode(u8x8_GetPinValue(u8x8, msg), INPUT_PULLUP);
#elsepinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);digitalWrite(u8x8_GetPinValue(u8x8, msg), 1);
#endif }break;default:if ( msg >= U8X8_MSG_GPIO(0) ){i = u8x8_GetPinValue(u8x8, msg);if ( i != U8X8_PIN_NONE ){if ( u8x8_GetPinIndex(u8x8, msg) < U8X8_PIN_OUTPUT_CNT ){digitalWrite(i, arg_int);}else{if ( u8x8_GetPinIndex(u8x8, msg) == U8X8_PIN_OUTPUT_CNT ){// call yield() for the first pin only, u8x8 will always request all the pins, so this should be okyield();}u8x8_SetGPIOResult(u8x8, digitalRead(i) == 0 ? 0 : 1);}}break;}return 0;}return 1;
}
#endif // U8X8_USE_PINS
更多推荐
u8g2结构
发布评论