OLED SH1108 STM32 实际使用8080接口
OLED SH1108 STM32 实际使用8080接口
硬件部分
软件部分
以前有一个项目使用维信诺OLED 核心控制器为SH1108,一直沉浸在项目中,没有实际记录SH1108数据手册,感觉这张图很好SH1108描述的非常生动,贴在这里
硬件部分

项目选择采用8080接口IO模拟的方式进行SH1108通信
项目使用的OLED屏屏为128 COM× 160 SEG,该屏幕有128 个column与20 个Page,每Page有8 Seg即一共160 Seg。
OLED和STM32硬件连接,STM使用外部晶振2532Mhz,倍频到。
软件部分
关于stm32和OLED管脚定义如下所列
//------------OLED ------------------------------------------------------------------ #define OLED_SH1108_CS_PIN GPIO_Pin_1 /* PB.1 -------> OLED_CS */ #define OLED_SH1108_CS_GPIO_PORT GPIOB /* GPIOB */ #define OLED_SH1108_CS_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_SH1108_DC_PIN GPIO_Pin_13 /* PB.13 -------> OLED_A0 */ #define OLED_SH1108_DC_GPIO_PORT GPIOB /* GPIOB */ #define OLED_SH1108_DC_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_SH1108_WR_PIN GPIO_Pin_14 /* PB.14 -------> OLED_WR */ #define OLED_SH1108_WR_GPIO_PORT GPIOB /* GPIOB */ #define OLED_SH1108_WR_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_SH1108_RD_PIN GPIO_Pin_15 /* PB.15 -------> OLED_RD */ #define OLED_SH1108_RD_GPIO_PORT GPIOB /* GPIOB */ #define OLED_SH1108_RD_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_SH1108_RES_PIN GPIO_Pin_12 /* PB.12 -------> OLED_RES */ #define OLED_SH1108_RES_GPIO_PORT GPIOB /* GPIOB */ #define OLED_SH1108_RES_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_SH1108_D0_PIN GPIO_Pin_0 /* PC.0 -------> OLED_D0 */ #define OLED_SH1108_D0_GPIO_PORT GPIOC /* GPIOC */ #define OLED_SH1108_D0_GPIO_CLK RCC_APB2Periph_GPIOC #define OLED_SH1108_D1_PIN GPIO_Pin_1 /* PC.1 -------> OLED_D1 */ #define OLED_SH1108_D1_GPIO_PORT GPIOC /* GPIOC */ #define OLED_SH1108_D1_GPIO_CLK RCC_APB2Periph_GPIOC #define OLED_SH1108_D2_PIN GPIO_Pin_2 /* PC.2 -------> OLED_D2 */ #define OLED_SH1108_D3_PIN GPIO_Pin_3 /* PC.3 -------> OLED_D3 */ #define OLED_SH1108_D4_PIN GPIO_Pin_4 /* PC.4 -------> OLED_D4 */ #define OLED_SH1108_D5_PIN GPIO_Pin_5 /* PC.5 -------> OLED_D5 */ #define OLED_SH1108_D6_PIN GPIO_Pin_6 /* PC.6 -------> OLED_D6 */ #define OLED_SH1108_D7_PIN GPIO_Pin_7 /* PC.7 -------> OLED_D7 */ #define OLED_SH1108_XDATA_GPIO_PORT GPIOC /* GPIOC */ #define OLED_SH1108_XDATA_GPIO_CLK RCC_APB2Periph_GPIOC #define OLED_SH1108_RES_LOW() GPIO_ResetBits(OLED_SH1108_RES_GPIO_PORT, OLED_SH1108_RES_PIN) #define OLED_SH1108_RES_HIGH() GPIO_SetBits(OLED_SH1108_RES_GPIO_PORT, OLED_SH1108_RES_PIN) #define OLED_SH1108_CS_LOW() GPIO_ResetBits(OLED_SH1108_CS_GPIO_PORT, OLED_SH1108_CS_PIN) #define OLED_SH1108_CS_HIGH() GPIO_SetBits(OLED_SH1108_CS_GPIO_PORT, OLED_SH1108_CS_PIN) #define OLED_SH1108_DC_LOW() GPIO_ResetBits(OLED_SH1108_DC_GPIO_PORT, OLED_SH1108_DC_PIN) #define OLED_SH1108_DC_HIGH() GPIO_SetBits(OLED_SH1108_DC_GPIO_PORT, OLED_SH1108_DC_PIN) #define OLED_SH1108_WR_LOW() GPIO_ResetBits(OLED_SH1108_WR_GPIO_PORT, OLED_SH1108_WR_PI)
#define OLED_SH1108_WR_HIGH() GPIO_SetBits(OLED_SH1108_WR_GPIO_PORT, OLED_SH1108_WR_PIN)
#define OLED_SH1108_RD_LOW() GPIO_ResetBits(OLED_SH1108_RD_GPIO_PORT, OLED_SH1108_RD_PIN)
#define OLED_SH1108_RD_HIGH() GPIO_SetBits(OLED_SH1108_RD_GPIO_PORT, OLED_SH1108_RD_PIN)
#define OLED_SH1108_XDATA(x) GPIO_Write(OLED_SH1108_XDATA_GPIO_PORT, x)
//#define OLED_SH1108_XDATA(x) GPIOC->ODR=(GPIOC->ODR & 0xff00) | (x & 0x00FF)
#define OLED_SH1108_SCL_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D0_PIN)
#define OLED_SH1108_SCL_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D0_PIN)
#define OLED_SH1108_SI_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D1_PIN)
#define OLED_SH1108_SI_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, OLED_SH1108_D1_PIN)
#define OLED_SH1108_D2_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_2)
#define OLED_SH1108_D2_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_2)
#define OLED_SH1108_D3_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_3)
#define OLED_SH1108_D3_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_3)
#define OLED_SH1108_D4_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_4)
#define OLED_SH1108_D4_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_4)
#define OLED_SH1108_D5_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_5)
#define OLED_SH1108_D5_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_5)
#define OLED_SH1108_D6_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_6)
#define OLED_SH1108_D6_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_6)
#define OLED_SH1108_D7_LOW() GPIO_ResetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_7)
#define OLED_SH1108_D7_HIGH() GPIO_SetBits(OLED_SH1108_XDATA_GPIO_PORT, GPIO_Pin_7)
这里为了速度将PC口单独连接到OLED的数据线上,这样可以加快操作OLED的读写速度。
测试main函数,实现了OLED显示汉字和字符串,部分图案显示没有测试
/******************************************************************************
* 函数名称: main()
* 功能描述: OLED测试
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明:
* 修改日期 版本号 修改人 修改内容
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 2013/02/22 V1.0.0.0
******************************************************************************/
INT32S main (void)
{
BSP_Init(); // 系统初始化
oled_sh1108_init_program();
OLED_ShowChinese(1, 20, 4, 1);//主
OLED_ShowChinese(93, 20, 5, 1);//副
while(1)
{
sprintf((char*)oled_display_buf," ");
oled_sh1108_show_string(61, 5, oled_display_buf, 12);
sprintf((char*)oled_display_buf,"%4.4d-%2.2d-%2.2d", 2022, 1, 1);
oled_sh1108_show_string(1, 5, oled_display_buf, 12);
sprintf((char*)oled_display_buf,"%2.2d:%2.2d:%2.2d", 10, 10, 10);
oled_sh1108_show_string(105, 5, oled_display_buf, 12);
oled_sh1108_refresh_gram();
}
return (0);
}
STM32内部缓存定义,每次更改该数据,一定时间,或者及时将该数据刷新
/* OLED的显存
* 存放格式如下.
* [0]0 1 2 3 ... 127
* [1]0 1 2 3 ... 127
* [2]0 1 2 3 ... 127
*
* [19]0 1 2 3 ... 127
*/
static unsigned char OLED_GRAM[128][20];
刷新缓存到OLED,该函数实现将缓存数据刷新到OLED
/******************************************************************************
* 函数名称: oled_sh1108_all_screen()
* 功能描述: 更新显存到LCD
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明:
* 修改日期 版本号 修改人 修改内容
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 2013/02/22 V1.0.0.0
******************************************************************************/
void oled_sh1108_refresh_gram(void)
{
unsigned char i, j;
// for(i = 0 ; i < 8; i++)
// {
// OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
// OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
// OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
// for(n=0;n<128;n++)
// OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
// }
for(i = 0; i < 20; i++)
{
oled_sh1108_write_c(0xb0);
oled_sh1108_write_c(0x00 + i);
oled_sh1108_write_c(0x00);
oled_sh1108_write_c(0x11);
for(j = 0; j < 128; j++)
{
oled_sh1108_write_d(OLED_GRAM[j][i]);
}
}
}