i2c-oled.c

STM32F103 "Blue Pill" (STM32F103C8T6) · Archivo : i2c-oled.c · Lenguaje : C · Uso : Écrire sur un écran OLED SSD1306 en I2C avec la HAL

El protocolo I2C del SSD1306 se resume en dos bytes de control: 0x00 para orden, 0x40 para datos. Este programa envía la secuencia de inicialización y una imagen de prueba, sin librería: la mejor forma de entender el I2C maestro.

Hardware

Una Blue Pill STM32F103C8T6 (Cortex-M3 @ 72 MHz, 64 KB flash) alimentada por micro-USB o 3,3 V externo; programacion SWD o bootloader serie. 1 módulo OLED SSD1306 I2C (0x3C), alimentación de 3,3 V.

Cableado

SDA a PB7, SCL a PB6 (pines I2C1 típicos de las Nucleo, confírmalo en el .ioc), VCC 3,3 V, GND.

Funcionamiento

Cada trama I2C empieza con el byte de dirección 0x78 y luego el byte de control. La secuencia configura la bomba de carga y el barrido; 0xAF enciende el panel y la trama de 1024 bytes rellena la GDDRAM.

Ejecución

Proyecto STM32CubeIDE (STM32F103C8) o Arduino (core STM32): programar por SWD (ST-LINK, adaptador DAPLink) o por el bootloader serie (BOOT0 a 1). Atencion: el LED PC13 es activo LOW.

Variantes

Añade una fuente 5x7 para imprimir cadenas (printf → bitmap), o pasa a DMA I2C para liberar la CPU durante el refresco.

i2c-oled.c

// OLED SSD1306 (0x3C) : envoi de commandes/data en I2C HAL.
#include "main.h"
#include <string.h>

extern I2C_HandleTypeDef hi2c1;

#define SSD1306_ADDR 0x78 // 0x3C << 1 (format HAL)

static void cmd(uint8_t c) {
  uint8_t d[2] = { 0x00, c };        // 0x00 = byte de commande
  HAL_I2C_Master_Transmit(&hi2c1, SSD1306_ADDR, d, 2, 10);
}
static void data(const uint8_t *p, uint16_t n) {
  uint8_t buf[129];
  buf[0] = 0x40;                       // 0x40 = byte de donnees
  memcpy(buf + 1, p, n);
  HAL_I2C_Master_Transmit(&hi2c1, SSD1306_ADDR, buf, n + 1, 100);
}
static void init(void) {
  const uint8_t seq[] = { 0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00,
                          0x40, 0x8D, 0x14, 0x20, 0x00, 0xA1, 0xC8,
                          0xDA, 0x12, 0x81, 0xFF, 0xD9, 0xF1, 0xDB,
                          0x40, 0xA4, 0xA6, 0xAF };                 // AF = on
  for (unsigned i = 0; i < sizeof(seq); i++) cmd(seq[i]);
}

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();   // SCL/PB6, SDA/PB7 dans le .ioc (400 kHz)
  init();
  uint8_t trame[1024];
  memset(trame, 0xAA, sizeof(trame)); // damier de test 128x64
  data(trame, sizeof(trame));
  for (;;);
}

← Volver a la ficha