【WCH】CH32F203软件I2C驱动SSD1306 OLED
📌相关篇《【WCH】CH32F203硬件I2C驱动SSD1306 OLED》 📺驱动显示效果: 🌿OLED屏幕:i2c ssd1306 oled 🔖驱动单片机型号:CH32F203
✨由于CH32F203
主频为96MHz,测试了144MHz下也可以驱动显示。如果是从屏幕厂商提供的程序,需要修改相应的延时时间来匹配通讯时序。
📑引脚定义
I2C1_SCL ( PB8)
I2C1_SDA ( PB9) .
📑OLED驱动程序
# include "oled.h"
# include "oledfont.h"
static u8 OLED_GRAM[ 144 ] [ 8 ] ;
void OLED_ColorTurn ( u8 i)
{
if ( i == 0 )
{
OLED_WR_Byte ( 0xA6 , OLED_CMD) ;
}
if ( i == 1 )
{
OLED_WR_Byte ( 0xA7 , OLED_CMD) ;
}
}
void OLED_DisplayTurn ( u8 i)
{
if ( i == 0 )
{
OLED_WR_Byte ( 0xC8 , OLED_CMD) ;
OLED_WR_Byte ( 0xA1 , OLED_CMD) ;
}
if ( i == 1 )
{
OLED_WR_Byte ( 0xC0 , OLED_CMD) ;
OLED_WR_Byte ( 0xA0 , OLED_CMD) ;
}
}
static void IIC_delay ( void )
{
u8 t = 3 * 10 ;
while ( t-- ) ;
}
static void I2C_Start ( void )
{
OLED_SDA_Set ( ) ;
OLED_SCL_Set ( ) ;
IIC_delay ( ) ;
OLED_SDA_Clr ( ) ;
IIC_delay ( ) ;
OLED_SCL_Clr ( ) ;
IIC_delay ( ) ;
}
static void I2C_Stop ( void )
{
OLED_SDA_Clr ( ) ;
OLED_SCL_Set ( ) ;
IIC_delay ( ) ;
OLED_SDA_Set ( ) ;
}
static void I2C_WaitAck ( void )
{
OLED_SDA_Set ( ) ;
IIC_delay ( ) ;
OLED_SCL_Set ( ) ;
IIC_delay ( ) ;
OLED_SCL_Clr ( ) ;
IIC_delay ( ) ;
}
static void Send_Byte ( u8 dat)
{
u8 i;
for ( i = 0 ; i < 8 ; i++ )
{
if ( dat & 0x80 )
{
OLED_SDA_Set ( ) ;
}
else
{
OLED_SDA_Clr ( ) ;
}
IIC_delay ( ) ;
OLED_SCL_Set ( ) ;
IIC_delay ( ) ;
OLED_SCL_Clr ( ) ;
dat <<= 1 ;
}
}
static void OLED_WR_Byte ( u8 dat, u8 mode)
{
I2C_Start ( ) ;
Send_Byte ( 0x78 ) ;
I2C_WaitAck ( ) ;
if ( mode)
{
Send_Byte ( 0x40 ) ;
}
else
{
Send_Byte ( 0x00 ) ;
}
I2C_WaitAck ( ) ;
Send_Byte ( dat) ;
I2C_WaitAck ( ) ;
I2C_Stop ( ) ;
}
void OLED_DisPlay_On ( void )
{
OLED_WR_Byte ( 0x8D , OLED_CMD) ;
OLED_WR_Byte ( 0x14 , OLED_CMD) ;
OLED_WR_Byte ( 0xAF , OLED_CMD) ;
}
void OLED_DisPlay_Off ( void )
{
OLED_WR_Byte ( 0x8D , OLED_CMD) ;
OLED_WR_Byte ( 0x10 , OLED_CMD) ;
OLED_WR_Byte ( 0xAE , OLED_CMD) ;
}
void OLED_Refresh ( void )
{
u8 i, n;
for ( i = 0 ; i < 8 ; i++ )
{
OLED_WR_Byte ( 0xb0 + i, OLED_CMD) ;
OLED_WR_Byte ( 0x00 , OLED_CMD) ;
OLED_WR_Byte ( 0x10 , OLED_CMD) ;
I2C_Start ( ) ;
Send_Byte ( 0x78 ) ;
I2C_WaitAck ( ) ;
Send_Byte ( 0x40 ) ;
I2C_WaitAck ( ) ;
for ( n = 0 ; n < 128 ; n++ )
{
Send_Byte ( OLED_GRAM[ n] [ i] ) ;
I2C_WaitAck ( ) ;
}
I2C_Stop ( ) ;
}
}
void OLED_Clear ( void )
{
u8 i, n;
for ( i = 0 ; i < 8 ; i++ )
{
for ( n = 0 ; n < 128 ; n++ )
{
OLED_GRAM[ n] [ i] = 0 ;
}
}
OLED_Refresh ( ) ;
}
void OLED_DrawPoint ( u8 x, u8 y, u8 t)
{
u8 i, m, n;
i = y / 8 ;
m = y % 8 ;
n = 1 << m;
if ( t)
{
OLED_GRAM[ x] [ i] |= n;
}
else
{
OLED_GRAM[ x] [ i] = ~ OLED_GRAM[ x] [ i] ;
OLED_GRAM[ x] [ i] |= n;
OLED_GRAM[ x] [ i] = ~ OLED_GRAM[ x] [ i] ;
}
}
void OLED_DrawLine ( u8 x1, u8 y1, u8 x2, u8 y2, u8 mode)
{
u16 t;
int xerr = 0 , yerr = 0 , delta_x, delta_y, distance;
int incx, incy, uRow, uCol;
delta_x = x2 - x1;
delta_y = y2 - y1;
uRow = x1;
uCol = y1;
if ( delta_x > 0 ) incx = 1 ;
else if ( delta_x == 0 ) incx = 0 ;
else
{
incx = - 1 ;
delta_x = - delta_x;
}
if ( delta_y > 0 ) incy = 1 ;
else if ( delta_y == 0 ) incy = 0 ;
else
{
incy = - 1 ;
delta_y = - delta_x;
}
if ( delta_x > delta_y) distance = delta_x;
else distance = delta_y;
for ( t = 0 ; t < distance + 1 ; t++ )
{
OLED_DrawPoint ( uRow, uCol, mode) ;
xerr += delta_x;
yerr += delta_y;
if ( xerr > distance)
{
xerr -= distance;
uRow += incx;
}
if ( yerr > distance)
{
yerr -= distance;
uCol += incy;
}
}
}
void OLED_DrawCircle ( u8 x, u8 y, u8 r)
{
int a, b, num;
a = 0 ;
b = r;
while ( 2 * b * b >= r * r)
{
OLED_DrawPoint ( x + a, y - b, 1 ) ;
OLED_DrawPoint ( x - a, y - b, 1 ) ;
OLED_DrawPoint ( x - a, y + b, 1 ) ;
OLED_DrawPoint ( x + a, y + b, 1 ) ;
OLED_DrawPoint ( x + b, y + a, 1 ) ;
OLED_DrawPoint ( x + b, y - a, 1 ) ;
OLED_DrawPoint ( x - b, y - a, 1 ) ;
OLED_DrawPoint ( x - b, y + a, 1 ) ;
a++ ;
num = ( a * a + b * b) - r * r;
if ( num > 0 )
{
b-- ;
a-- ;
}
}
}
void OLED_ShowChar ( u8 x, u8 y, u8 chr, u8 size1, u8 mode)
{
u8 i, m, temp, size2, chr1;
u8 x0 = x, y0 = y;
if ( size1 == 8 ) size2 = 6 ;
else size2 = ( size1 / 8 + ( ( size1 % 8 ) ? 1 : 0 ) ) * ( size1 / 2 ) ;
chr1 = chr - ' ' ;
for ( i = 0 ; i < size2; i++ )
{
if ( size1 == 8 )
{
temp = asc2_0806[ chr1] [ i] ;
}
else if ( size1 == 12 )
{
temp = asc2_1206[ chr1] [ i] ;
}
else if ( size1 == 16 )
{
temp = asc2_1608[ chr1] [ i] ;
}
else if ( size1 == 24 )
{
temp = asc2_2412[ chr1] [ i] ;
}
else return ;
for ( m = 0 ; m < 8 ; m++ )
{
if ( temp & 0x01 ) OLED_DrawPoint ( x, y, mode) ;
else OLED_DrawPoint ( x, y, ! mode) ;
temp >>= 1 ;
y++ ;
}
x++ ;
if ( ( size1 != 8 ) && ( ( x - x0) == size1 / 2 ) )
{
x = x0;
y0 = y0 + 8 ;
}
y = y0;
}
}
void OLED_ShowString ( u8 x, u8 y, u8* chr, u8 size1, u8 mode)
{
while ( ( * chr >= ' ' ) && ( * chr <= '~' ) )
{
OLED_ShowChar ( x, y, * chr, size1, mode) ;
if ( size1 == 8 ) x += 6 ;
else x += size1 / 2 ;
chr++ ;
}
}
static u32 OLED_Pow ( u8 m, u8 n)
{
u32 result = 1 ;
while ( n-- )
{
result *= m;
}
return result;
}
void OLED_ShowNum ( u8 x, u8 y, u32 num, u8 len, u8 size1, u8 mode)
{
u8 t, temp, m = 0 ;
if ( size1 == 8 ) m = 2 ;
for ( t = 0 ; t < len; t++ )
{
temp = ( num / OLED_Pow ( 10 , len - t - 1 ) ) % 10 ;
if ( temp == 0 )
{
OLED_ShowChar ( x + ( size1 / 2 + m) * t, y, '0' , size1, mode) ;
}
else
{
OLED_ShowChar ( x + ( size1 / 2 + m) * t, y, temp + '0' , size1, mode) ;
}
}
}
void OLED_ShowChinese ( u8 x, u8 y, u8 num, u8 size1, u8 mode)
{
u8 m, temp;
u8 x0 = x, y0 = y;
u16 i, size3 = ( size1 / 8 + ( ( size1 % 8 ) ? 1 : 0 ) ) * size1;
for ( i = 0 ; i < size3; i++ )
{
if ( size1 == 16 )
{
temp = Hzk1[ num] [ i] ;
}
else if ( size1 == 24 )
{
temp = Hzk2[ num] [ i] ;
}
else if ( size1 == 32 )
{
temp = Hzk3[ num] [ i] ;
}
else if ( size1 == 64 )
{
temp = Hzk4[ num] [ i] ;
}
else return ;
for ( m = 0 ; m < 8 ; m++ )
{
if ( temp & 0x01 ) OLED_DrawPoint ( x, y, mode) ;
else OLED_DrawPoint ( x, y, ! mode) ;
temp >>= 1 ;
y++ ;
}
x++ ;
if ( ( x - x0) == size1)
{
x = x0;
y0 = y0 + 8 ;
}
y = y0;
}
}
void OLED_ScrollDisplay ( u8 num, u8 space, u8 mode)
{
u8 i, n, t = 0 , m = 0 , r;
while ( 1 )
{
if ( m == 0 )
{
OLED_ShowChinese ( 128 , 0 , t, 16 , mode) ;
t++ ;
}
if ( t == num)
{
for ( r = 0 ; r < 16 * space; r++ )
{
for ( i = 1 ; i < 144 ; i++ )
{
for ( n = 0 ; n < 8 ; n++ )
{
OLED_GRAM[ i - 1 ] [ n] = OLED_GRAM[ i] [ n] ;
}
}
OLED_Refresh ( ) ;
}
t = 0 ;
}
m++ ;
if ( m == 16 )
{
m = 0 ;
}
for ( i = 1 ; i < 144 ; i++ )
{
for ( n = 0 ; n < 8 ; n++ )
{
OLED_GRAM[ i - 1 ] [ n] = OLED_GRAM[ i] [ n] ;
}
}
OLED_Refresh ( ) ;
}
}
void OLED_ShowPicture ( u8 x, u8 y, u8 sizex, u8 sizey, u8 BMP[ ] , u8 mode)
{
u16 j = 0 ;
u8 i, n, temp, m;
u8 x0 = x, y0 = y;
sizey = sizey / 8 + ( ( sizey % 8 ) ? 1 : 0 ) ;
for ( n = 0 ; n < sizey; n++ )
{
for ( i = 0 ; i < sizex; i++ )
{
temp = BMP[ j] ;
j++ ;
for ( m = 0 ; m < 8 ; m++ )
{
if ( temp & 0x01 ) OLED_DrawPoint ( x, y, mode) ;
else OLED_DrawPoint ( x, y, ! mode) ;
temp >>= 1 ;
y++ ;
}
x++ ;
if ( ( x - x0) == sizex)
{
x = x0;
y0 = y0 + 8 ;
}
y = y0;
}
}
}
void OLED_Init ( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE) ;
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init ( GPIOB, & GPIO_InitStructure) ;
GPIO_SetBits ( GPIOB, GPIO_Pin_8 | GPIO_Pin_9) ;
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init ( GPIOC, & GPIO_InitStructure) ;
GPIO_SetBits ( GPIOC, GPIO_Pin_12) ;
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init ( GPIOD, & GPIO_InitStructure) ;
GPIO_SetBits ( GPIOD, GPIO_Pin_2) ;
OLED_RES_Clr ( ) ;
Delay_Ms ( 200 ) ;
OLED_RES_Set ( ) ;
OLED_WR_Byte ( 0xAE , OLED_CMD) ;
OLED_WR_Byte ( 0x00 , OLED_CMD) ;
OLED_WR_Byte ( 0x10 , OLED_CMD) ;
OLED_WR_Byte ( 0x40 , OLED_CMD) ;
OLED_WR_Byte ( 0x81 , OLED_CMD) ;
OLED_WR_Byte ( 0xCF , OLED_CMD) ;
OLED_WR_Byte ( 0xA1 , OLED_CMD) ;
OLED_WR_Byte ( 0xC8 , OLED_CMD) ;
OLED_WR_Byte ( 0xA6 , OLED_CMD) ;
OLED_WR_Byte ( 0xA8 , OLED_CMD) ;
OLED_WR_Byte ( 0x3f , OLED_CMD) ;
OLED_WR_Byte ( 0xD3 , OLED_CMD) ;
OLED_WR_Byte ( 0x00 , OLED_CMD) ;
OLED_WR_Byte ( 0xd5 , OLED_CMD) ;
OLED_WR_Byte ( 0x80 , OLED_CMD) ;
OLED_WR_Byte ( 0xD9 , OLED_CMD) ;
OLED_WR_Byte ( 0xF1 , OLED_CMD) ;
OLED_WR_Byte ( 0xDA , OLED_CMD) ;
OLED_WR_Byte ( 0x12 , OLED_CMD) ;
OLED_WR_Byte ( 0xDB , OLED_CMD) ;
OLED_WR_Byte ( 0x40 , OLED_CMD) ;
OLED_WR_Byte ( 0x20 , OLED_CMD) ;
OLED_WR_Byte ( 0x02 , OLED_CMD) ;
OLED_WR_Byte ( 0x8D , OLED_CMD) ;
OLED_WR_Byte ( 0x14 , OLED_CMD) ;
OLED_WR_Byte ( 0xA4 , OLED_CMD) ;
OLED_WR_Byte ( 0xA6 , OLED_CMD) ;
OLED_Clear ( ) ;
OLED_WR_Byte ( 0xAF , OLED_CMD) ;
}
# ifndef __OLED_H
# define __OLED_H
# include "debug.h"
# include "stdlib.h"
# define OLED_SCL_Clr ( ) GPIO_ResetBits ( GPIOB, GPIO_Pin_8)
# define OLED_SCL_Set ( ) GPIO_SetBits ( GPIOB, GPIO_Pin_8)
# define OLED_SDA_Clr ( ) GPIO_ResetBits ( GPIOB, GPIO_Pin_9)
# define OLED_SDA_Set ( ) GPIO_SetBits ( GPIOB, GPIO_Pin_9)
# define OLED_RES_Clr ( ) GPIO_ResetBits ( GPIOA, GPIO_Pin_2)
# define OLED_RES_Set ( ) GPIO_SetBits ( GPIOA, GPIO_Pin_2)
# define OLED_CMD 0
# define OLED_DATA 1
void OLED_ClearPoint ( u8 x, u8 y) ;
void OLED_ColorTurn ( u8 i) ;
void OLED_DisplayTurn ( u8 i) ;
static void I2C_Start ( void ) ;
static void I2C_Stop ( void ) ;
static void I2C_WaitAck ( void ) ;
static void Send_Byte ( u8 dat) ;
static void OLED_WR_Byte ( u8 dat, u8 mode) ;
void OLED_DisPlay_On ( void ) ;
void OLED_DisPlay_Off ( void ) ;
void OLED_Refresh ( void ) ;
void OLED_Clear ( void ) ;
void OLED_DrawPoint ( u8 x, u8 y, u8 t) ;
void OLED_DrawLine ( u8 x1, u8 y1, u8 x2, u8 y2, u8 mode) ;
void OLED_DrawCircle ( u8 x, u8 y, u8 r) ;
void OLED_ShowChar ( u8 x, u8 y, u8 chr, u8 size1, u8 mode) ;
void OLED_ShowChar6x8 ( u8 x, u8 y, u8 chr, u8 mode) ;
void OLED_ShowString ( u8 x, u8 y, u8 * chr, u8 size1, u8 mode) ;
void OLED_ShowNum ( u8 x, u8 y, u32 num, u8 len, u8 size1, u8 mode) ;
void OLED_ShowChinese ( u8 x, u8 y, u8 num, u8 size1, u8 mode) ;
void OLED_ScrollDisplay ( u8 num, u8 space, u8 mode) ;
void OLED_ShowPicture ( u8 x, u8 y, u8 sizex, u8 sizey, u8 BMP[ ] , u8 mode) ;
void OLED_Init ( void ) ;
# endif
📝main主程序代码
# include "debug.h"
# include "oled.h"
# include "bmp.h"
int main ( void )
{
u8 t = ' ' ;
Delay_Init ( ) ;
USART_Printf_Init ( 115200 ) ;
printf ( "SystemClk:%d\r\n" , SystemCoreClock) ;
OLED_Init ( ) ;
printf ( "Init \r\n" ) ;
OLED_ColorTurn ( 0 ) ;
OLED_DisplayTurn ( 0 ) ;
OLED_DrawPoint ( 15 , 15 , 1 ) ;
OLED_Refresh ( ) ;
while ( 1 )
{
OLED_ShowPicture ( 0 , 0 , 128 , 64 , BMP1, 1 ) ;
OLED_Refresh ( ) ;
Delay_Ms ( 500 ) ;
OLED_Clear ( ) ;
OLED_ShowChinese ( 0 , 0 , 0 , 16 , 1 ) ;
OLED_ShowChinese ( 18 , 0 , 1 , 16 , 1 ) ;
OLED_ShowChinese ( 36 , 0 , 2 , 16 , 1 ) ;
OLED_ShowChinese ( 54 , 0 , 3 , 16 , 1 ) ;
OLED_ShowChinese ( 72 , 0 , 4 , 16 , 1 ) ;
OLED_ShowChinese ( 90 , 0 , 5 , 16 , 1 ) ;
OLED_ShowChinese ( 108 , 0 , 6 , 16 , 1 ) ;
OLED_ShowString ( 8 , 16 , "ZHONGJINGYUAN" , 16 , 1 ) ;
OLED_ShowString ( 20 , 32 , "2014/05/01" , 16 , 1 ) ;
OLED_ShowString ( 0 , 48 , "ASCII:" , 16 , 1 ) ;
OLED_ShowString ( 63 , 48 , "CODE:" , 16 , 1 ) ;
OLED_ShowChar ( 48 , 48 , t, 16 , 1 ) ;
t++ ;
if ( t > '~' ) t = ' ' ;
OLED_ShowNum ( 103 , 48 , t, 3 , 16 , 1 ) ;
OLED_Refresh ( ) ;
Delay_Ms ( 500 ) ;
OLED_Clear ( ) ;
OLED_ShowChinese ( 0 , 0 , 0 , 16 , 1 ) ;
OLED_ShowChinese ( 16 , 0 , 0 , 24 , 1 ) ;
OLED_ShowChinese ( 24 , 20 , 0 , 32 , 1 ) ;
OLED_ShowChinese ( 64 , 0 , 0 , 64 , 1 ) ;
OLED_Refresh ( ) ;
Delay_Ms ( 500 ) ;
OLED_Clear ( ) ;
OLED_ShowString ( 0 , 0 , "ABC" , 8 , 1 ) ;
OLED_ShowString ( 0 , 8 , "ABC" , 12 , 1 ) ;
OLED_ShowString ( 0 , 20 , "ABC" , 16 , 1 ) ;
OLED_ShowString ( 0 , 36 , "ABC" , 24 , 1 ) ;
OLED_Refresh ( ) ;
OLED_Clear ( ) ;
Delay_Ms ( 500 ) ;
OLED_ScrollDisplay ( 11 , 3 , 1 ) ;
}
}
📚程序源码
链接: https:
提取码: g85n