1.调试的OLED 为单色128x32,也就是一个bit对应一个像素点。1点亮像素点,0熄灭像素点
OLED写数据的时候是一次写一个byte也就是8个像素点,因此,要实现画任意点函数,就必须要开辟一个显存空间,采用修改显存空间后,再去更新显示
/**
* OLED的显存 128x32 对应128x4的二维数组
* 存放格式如下. 每一行对应一个page也就是页,比如数组元素[0][0]就对应8个像素点
* [0]0 1 2 3 ... 127
* [1]0 1 2 3 ... 127
* [2]0 1 2 3 ... 127
* [3]0 1 2 3 ... 127
**/
2.画点函数 画点函数的本质就是先修改显存对应的点的信息,然后再把显存更新到OLED。可以采用局部更新OLED,也可以全部更新OLED
/**
* @name void OLED_DrawPoint(uint8_t x,uint8_t y,u8 t)
* @brief 画点
* @param x: 0~127 y: 0~32 t:1 填充 0 清空
* @retval none
*/
void OLED_DrawPoint(uint8_t x, uint8_t y, uint8_t t)
{
uint8_t pos, bitx, temp = 0;
if(x > OLED_X_SIZE || y > OLED_Y_SIZE)
{
return;//超出范围了.
}
pos = y/8; /* 计算y点对应显存的页坐标page */
bitx = y % 8; /* 计算y点对应显存的bit位置 */
temp = 1 << bitx;
t ? (OLED_GRAM[x][pos] |= temp) : (OLED_GRAM[x][pos] &= ~temp);
}
/**
* @name void OLED_Refresh_Gram(void)
* @brief 更新显存到OLED
* @param none
* @retval none
*/
void OLED_Refresh_Gram_Full(void)
{
uint8_t i, n;
for(i = 0; i < OLED_PAGE_SIZE; i++)
{
OLED_WR_Byte(0xb0 + i,OLED_CMD); //设置页地址(0~7) 页地址模式下,写完一页,需要手动设置下一页地址
OLED_WR_Byte(0x00,OLED_CMD); //设置显示位置—列低地址 低4位 bit3 bit2 bit1 bit0
OLED_WR_Byte(0x10,OLED_CMD); //设置显示位置—列高地址 低4位 bit7 bit6 bit5 bit4
for(n = 0; n < OLED_X_SIZE; n++)
{
OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
}
}
}
/* 局部刷新OLED
** para: x 横坐标 列地址
** y 纵坐标 页地址
** len x方向长度 以像素点为单位
** width y方向宽度 以像素点为单位
*/
void OLED_Refresh_Gram_Part(uint8_t x, uint8_t y,uint8_t len, uint8_t width)
{
uint8_t i, n;
for(i = (y/8); i <= ((y+width)/8); i++)
{
OLED_WR_Byte(0xb0 + i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00+(0x0f&x),OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte(0x10+(x>>4),OLED_CMD); //设置显示位置—列高地址
for(n = x; n < (x+len); n++)
{
OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
}
}
}
3.OLED初始化,这个一般用厂家的代码即可,然后对比手册,更改相应的显示模式,比较容易点亮OLED
/* 初始化SSD1306 */
void OLED_Init(void)
{
Init_I2C1_oled();
delay_ms(20);
OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示
OLED_WR_Byte(0xD5,OLED_CMD);//设置时钟分频
OLED_WR_Byte(0x80,OLED_CMD);//[3:0],分频因子;[7:4],震荡频率
OLED_WR_Byte(0xA8,OLED_CMD);//设置驱动路数,即只扫描哪些行
OLED_WR_Byte(0x1F,OLED_CMD);//默认为3F,1/64 显示为128x32所以1f即可
OLED_WR_Byte(0xD3,OLED_CMD);//设置显示偏移
OLED_WR_Byte(0x00,OLED_CMD);//默认为0
OLED_WR_Byte(0x40,OLED_CMD);//设置显示开始行 [5:0],行数.
OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵设置
OLED_WR_Byte(0x14,OLED_CMD);//bit2,开启/关闭
OLED_WR_Byte(0x20,OLED_CMD);//设置内存地址模式
OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
OLED_WR_Byte(0xA0,OLED_CMD);//[1:0],Seg列重映象,A0正常显示,A1列左右反置 bit0:0,0->0;1,0->127;
OLED_WR_Byte(0xC0,OLED_CMD);//[3:0],行扫描方向:C0正常扫描,C8上下反置 COM[N-1]->COM0;N:驱动路数
OLED_WR_Byte(0xDA,OLED_CMD);//设置硬件com引脚配置
OLED_WR_Byte(0x00,OLED_CMD);//[5:4]配置
OLED_WR_Byte(0xB0,OLED_CMD);//---set high column address
OLED_WR_Byte(0x81,OLED_CMD);//设置对比度
OLED_WR_Byte(0x3F,OLED_CMD);//1~255;默认0X7F (亮度设置,越大越亮)
OLED_WR_Byte(0xD9,OLED_CMD);//设置预充电周期
OLED_WR_Byte(0x1F,OLED_CMD);//[3:0],PHASE 1;[7:4],PHASE 2;
OLED_WR_Byte(0xDB,OLED_CMD);//[设置VCOMH 电压倍率
OLED_WR_Byte(0x40,OLED_CMD);//[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
OLED_WR_Byte(0xA4,OLED_CMD);//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
OLED_WR_Byte(0xA6,OLED_CMD);//设置显示方式;bit0:1,反相显示;0,正常显示
OLED_WR_Byte(0xAF,OLED_CMD);//设置显示模式为正常显示1点亮
OLED_Clear_All();
}