硬件
- 之前讲过了,就不讲了
软件需求
- STM32CubeMX生成一个基本的I2C,用的是I2C1
软件配置
上一篇文章记录的很清楚了,这里就不多讲了
- I2C配置
- 时钟配置
程序
- 字符库
- 显存
//引用I2C1
extern I2C_HandleTypeDef hi2c1;
//命令操作数
#define OLED_CMD_HAL (0x00)
#define OLED_DATA_HAL (0x01)
//定义OLED地址
#define OLED_I2C_ADDRESS (0x78)
//最大像素值
#define MAX_COLUMN 128
#define MAX_ROW 64
#define X_WIDTH MAX_COLUMN
#define Y_WIDTH MAX_ROW
//最大宽、高
#define CHAR_SIZE_WIDTH 6
#define CHAR_SIZE_HIGHT 12
//定义显示方式
typedef enum{
PEN_CLEAR = 0x00,//将所有像素熄灭
PEN_WRITE = 0x01,//将所有像素点亮
PEN_INVERSION = 0x02//将所有像素状态反转
} pen_typedef;
//定义显示数据
char OLED_GRAM_HAL[128][8] = {0};
- oled写入操作
void oled_write_byte(uint8_t dat, uint8_t cmd)
{
static uint8_t cmd_data[2];
if(cmd == OLED_CMD_HAL)
{
cmd_data[0] = 0x00;
}
else
{
cmd_data[0] = 0x40;
}
cmd_data[1] = dat;
HAL_I2C_Master_Transmit(&hi2c1, OLED_I2C_ADDRESS, cmd_data, 2, 10);
}
- 设置坐标点
//设置光标位置
void OLED_set_pos(uint8_t x,uint8_t y)
{
oled_write_byte((0xb0 + y), OLED_CMD_HAL); //set page address y
oled_write_byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD_HAL); //set column high address
oled_write_byte((x & 0x0f), OLED_CMD_HAL); //set column low address
}
- 刷新显存
//刷新oled内部的GRAM
void OLED_refresh_gram(void)
{
uint8_t i,n;
for (i = 0; i< 8; i++)
{
OLED_set_pos(0,i);
for (n = 0; n < 128; n++)
{
oled_write_byte(OLED_GRAM_HAL[n][i], OLED_DATA_HAL );
}
}
}
- 画一个像素点
/对(x,y)坐标的一个像素点进行操作
void OLED_draw_point(int8_t x, int8_t y, pen_typedef pen)
{
uint8_t page = 0, row = 0;
/* check the corrdinate */
if ((x < 0) || (x > (X_WIDTH - 1)) || (y < 0) || (y > (Y_WIDTH - 1)))
{
return;
}
page = y / 8;
row = y % 8;
if (pen == PEN_WRITE)
{
OLED_GRAM_HAL[x][page] |= 1 << row;
}
else if (pen == PEN_INVERSION)
{
OLED_GRAM_HAL[x][page] ^= 1 << row;
}
else
{
OLED_GRAM_HAL[x][page] &= ~(1 << row);
}
}
- 显示一个字符
//显示一个字符
void OLED_show_char(uint8_t row, uint8_t col, uint8_t chr)
{
uint8_t x = col * 6;
uint8_t y = row * 12;
uint8_t temp, t, t1;
uint8_t y0 = y;
chr = chr - ' ';
for (t = 0; t < 12; t++)
{
temp = asc2_1206[chr][t];
for (t1 = 0; t1 < 8; t1++)
{
if (temp&0x80)
OLED_draw_point(x, y, PEN_WRITE);
else
OLED_draw_point(x, y, PEN_CLEAR);
temp <<= 1;
y++;
if ((y - y0) == 12)
{
y = y0;
x++;
break;
}
}
}
}
- oled初始化
void HAL_OLED_init(void)
{
oled_write_byte(0xAE,OLED_CMD_HAL);//--turn off oled panel
oled_write_byte(0x00,OLED_CMD_HAL);//---set low column address
oled_write_byte(0x10,OLED_CMD_HAL);//---set high column address
oled_write_byte(0x40,OLED_CMD_HAL);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
oled_write_byte(0x81,OLED_CMD_HAL);//--set contrast control register
oled_write_byte(0xCF,OLED_CMD_HAL);// Set SEG Output Current Brightness
oled_write_byte(0xA1,OLED_CMD_HAL);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
oled_write_byte(0xC8,OLED_CMD_HAL);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
oled_write_byte(0xA6,OLED_CMD_HAL);//--set normal display
oled_write_byte(0xA8,OLED_CMD_HAL);//--set multiplex ratio(1 to 64)
oled_write_byte(0x3f,OLED_CMD_HAL);//--1/64 duty
oled_write_byte(0xD3,OLED_CMD_HAL);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
oled_write_byte(0x00,OLED_CMD_HAL);//-not offset
oled_write_byte(0xd5,OLED_CMD_HAL);//--set display clock divide ratio/oscillator frequency
oled_write_byte(0x80,OLED_CMD_HAL);//--set divide ratio, Set Clock as 100 Frames/Sec
oled_write_byte(0xD9,OLED_CMD_HAL);//--set pre-charge period
oled_write_byte(0xF1,OLED_CMD_HAL);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
oled_write_byte(0xDA,OLED_CMD_HAL);//--set com pins hardware configuration
oled_write_byte(0x12,OLED_CMD_HAL);
oled_write_byte(0xDB,OLED_CMD_HAL);//--set vcomh
oled_write_byte(0x40,OLED_CMD_HAL);//Set VCOM Deselect Level
oled_write_byte(0x20,OLED_CMD_HAL);//-Set Page Addressing Mode (0x00/0x01/0x02)
oled_write_byte(0x02,OLED_CMD_HAL);//
oled_write_byte(0x8D,OLED_CMD_HAL);//--set Charge Pump enable/disable
oled_write_byte(0x14,OLED_CMD_HAL);//--set(0x10) disable
oled_write_byte(0xA4,OLED_CMD_HAL);// Disable Entire Display On (0xa4/0xa5)
oled_write_byte(0xA6,OLED_CMD_HAL);// Disable Inverse Display On (0xa6/a7)
oled_write_byte(0xAF,OLED_CMD_HAL);
}
主函数
- 包含头文件
- 函数初始化
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C1_Init();
HAL_OLED_init();
MX_GPIO_Init();
while (1)
{
OLED_show_char(0, 0, 'C');//显示ASCII字符
OLED_show_char(1, 2, 'D');//显示ASCII字符
OLED_refresh_gram();
HAL_Delay(500);
}
}
结语
记录一下STM32硬件I2C使用oled