// 0 0 0 0 0 0 SA0 R/W#
#define LED_DEVICE_ADDR (0x78)
// Co D/C 0 0 0 0 0 0
#define LED_DEVICE_WCMD (0x00) // 连续写命�????????????
#define I2C1_SENDTIMEOUT 100
void ssd1306_init()
{
uint8_t pdata[] = {0xae, // 关闭显示
0x20, 0x02, // 配置内存寻址模式
0x00, 0x10, // 页寻�?
0x40, // 设置显示�?始行
0x81, 0x7f, // 设置对比�?
0xa0, // 列地�?映射
0xc0, // 输出扫描方向
0xa8, 0x3f, // 设置多重比例
0xd3, 0x00, // 显示偏移
0xd5, 0x80, // 设置显示时钟分频,振荡器频�?
0xd9, 0xf1, // 设置预充电周�?
0xda, 0x12, // 设置COM引脚硬件配置
0xdb, 0x20, // 设置VCOMH取消选择等级
0x8d, 0x14, // 电荷泵设�?
0xa4, // 整个显示打开,忽略\展示内存中的数据
0xa6, // 设置正\反显�? "0�?1�?"或�??"0�?1�?"
//
// 0x26, // 向左\右水平滚�?
// 0x00, // 脏数�?
// 0x00, // 页开始地�?
// 0x07, // 滚动帧�?�率
// 0x07, // 结束页地�?
// 0x00, // 脏数�?
// 0xFF, // 脏数�?
// 0x2f, // 使能滚动
//
0xaf}; // 显示打开
int len = sizeof(pdata) / sizeof(pdata[0]),
ret = 0;
//写初始化配置
ret = HAL_I2C_Mem_Write(&hi2c2, LED_DEVICE_ADDR, 0, 0, pdata, len, I2C1_SENDTIMEOUT);
if (ret != 0)
{
printf("error 0\n");
return;
}
}
void ssd1306_clear()
{
// vTaskDelay(50 / portTICK_PERIOD_MS);
uint8_t data[] = {0xb0, // 设置页面开始地址
0x00, // 设置页面寻址模式的下起始地址
0x10}; // 设置页面寻址模式的上起始地址
uint8_t pdata[128] = {0xff}; // 像素数据
int ret = 0,
len = sizeof(data) / sizeof(data[0]),
plen = sizeof(pdata) / sizeof(pdata[0]);
// printf("len %d\n", len);
for (int i = 0; i < 8; i++)
{
//写控制命令告诉ssd1306 需要写指定位置显存
ret = HAL_I2C_Mem_Write(&hi2c2, LED_DEVICE_ADDR, 0, 0, data, 3, I2C1_SENDTIMEOUT);
//写数据内容到显存
ret = HAL_I2C_Mem_Write(&hi2c2, LED_DEVICE_ADDR, 0x40, 1, pdata, plen, I2C1_SENDTIMEOUT);
if (ret != 0)
{
printf("error 5\n");
}
data[0] += 1; // 页地址b0~b7
}
}
可以直接使用,stm32codeMx的使用不多介绍,参考上一篇stm32codeMx 读取24c02
显示效果如下图: