#include "oled.h"
//显示格式
// L0 L1 ..... LOLED_L
//Y1 HEX HEX
//Y2 HEX HEX
//...
//YOLED_H
uint8_t OLED_BUF_TEMP[OLED_H][OLED_L]={0x00};//y,x
uint8_t OLED_BUF_SHOW[OLED_H][OLED_L]={0x00};
//IIC start
void OLED_IIC_Start()
{
OLED_SCLK_SET();
OLED_SDIN_SET();
OLED_SDIN_CLR();
OLED_SCLK_CLR();
}
//IIC stop
void OLED_IIC_STOP()
{
OLED_SCLK_SET();
OLED_SDIN_CLR();
OLED_SDIN_SET();
}
//IIC WAIT ACK
void OLED_IIC_WAIT_ACK()
{
OLED_SCLK_SET();
OLED_SCLK_CLR();
}
//IIC Write Byte
void OLED_Write_IIC_Byte(uint8_t IIC_Byte)
{
for(uint8_t i=0;i<8;i++)
{
(IIC_Byte & 0x80)?OLED_SDIN_SET():OLED_SDIN_CLR();
IIC_Byte<<=1;
OLED_SCLK_SET();
OLED_SCLK_CLR();
}
}
//OLED COM
void OLED_Write_IIC_COM(uint8_t IIC_Com)
{
OLED_IIC_Start();
OLED_Write_IIC_Byte(OLED_IIC_SITE);
OLED_IIC_WAIT_ACK();
OLED_Write_IIC_Byte(0x00);
OLED_IIC_WAIT_ACK();
OLED_Write_IIC_Byte(IIC_Com);
OLED_IIC_WAIT_ACK();
OLED_IIC_STOP();
}
//OLED DATA
void OLED_Write_IIC_DATA(uint8_t IIC_Data)
{
OLED_IIC_Start();
OLED_Write_IIC_Byte(OLED_IIC_SITE);
OLED_IIC_WAIT_ACK();
OLED_Write_IIC_Byte(0x40);
OLED_IIC_WAIT_ACK();
OLED_Write_IIC_Byte(IIC_Data);
OLED_IIC_WAIT_ACK();
OLED_IIC_STOP();
}
//OLED Write COM/DATA
void OLED_Write_CD(uint8_t dat,uint8_t cmd)
{
cmd?OLED_Write_IIC_DATA(dat):OLED_Write_IIC_COM(dat);
}
//开启OLED显示
void OLED_Display_On(void)
{
OLED_Write_CD(0X8D,OLED_CMD); //SET DCDC命令
OLED_Write_CD(0X14,OLED_CMD); //DCDC ON
OLED_Write_CD(0XAF,OLED_CMD); //SHOW ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_Write_CD(0X8D,OLED_CMD); //SET DCDC命令
OLED_Write_CD(0X10,OLED_CMD); //DCDC OFF
OLED_Write_CD(0XAE,OLED_CMD); //SHOW OFF
}
//坐标设置
void OLED_Set_Pos(uint8_t y, uint8_t x)
{
OLED_Write_CD(0xB0+y,OLED_CMD);
OLED_Write_CD(((x&0xF0)>>4)|0x10,OLED_CMD);
OLED_Write_CD((x&0x0F),OLED_CMD);
}
//数据填充至temp
void OLED_Fill(uint8_t dat)
{
for(uint8_t i=0;i<OLED_H;i++)
for(uint8_t j=0;j<OLED_L;j++)OLED_BUF_TEMP[i][j]=dat;
}
//显示更新
void OLED_SHOW_Update()
{
for(uint8_t i=0;i<OLED_H;i++)
{
for(uint8_t j=0;j<OLED_L;j++)
{
if(OLED_BUF_SHOW[i][j]!=OLED_BUF_TEMP[i][j])
{
OLED_Set_Pos(i,j);
OLED_BUF_SHOW[i][j]=OLED_BUF_TEMP[i][j];
OLED_Write_CD(OLED_BUF_SHOW[i][j],OLED_DATA);
}
}
}
}
//GPIO INIT
void OLED_GPIO_INIT()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = OLED_SCLK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(OLED_SCLK_POR, &GPIO_InitStruct);
GPIO_InitStruct.Pin = OLED_SDIN_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(OLED_SDIN_POR, &GPIO_InitStruct);
}
//初始化SSD1306
void OLED_Init()
{
OLED_GPIO_INIT();
HAL_Delay(200);
OLED_Write_CD(0xAE,OLED_CMD);//--display off
OLED_Write_CD(0x00,OLED_CMD);//---set low column address——设置低列地址
OLED_Write_CD(0x10,OLED_CMD);//---set high column address——设置高列地址
OLED_Write_CD(0x40,OLED_CMD);//--set start line address 设置起始行地址
OLED_Write_CD(0xB0,OLED_CMD);//--set page address——设置页面地址
OLED_Write_CD(0x81,OLED_CMD); // contract control合同控制
OLED_Write_CD(0xFF,OLED_CMD);//--128
OLED_Write_CD(0xA1,OLED_CMD);//set segment remap 设置部分重新映射
OLED_Write_CD(0xA6,OLED_CMD);//--normal / reverse——正常/反向
OLED_Write_CD(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)——设置多重比(1到64)
OLED_Write_CD(0x3F,OLED_CMD);//--1/32 duty——1/32的责任
OLED_Write_CD(0xC8,OLED_CMD);//Com scan directionCom扫描方向
OLED_Write_CD(0xD3,OLED_CMD);//-set display offset设置显示抵消
OLED_Write_CD(0x00,OLED_CMD);//
OLED_Write_CD(0xD5,OLED_CMD);//set osc division设置osc部门
OLED_Write_CD(0x80,OLED_CMD);//
OLED_Write_CD(0xD8,OLED_CMD);//set area color mode off关闭区域颜色模式
OLED_Write_CD(0x05,OLED_CMD);//
OLED_Write_CD(0xD9,OLED_CMD);//Set Pre-Charge Period设置Pre-Charge时期
OLED_Write_CD(0xF1,OLED_CMD);//
OLED_Write_CD(0xDA,OLED_CMD);//set com pin configuartion设置com引脚配置
OLED_Write_CD(0x12,OLED_CMD);//
OLED_Write_CD(0xDB,OLED_CMD);//set Vcomh设置Vcomh
OLED_Write_CD(0x30,OLED_CMD);//
OLED_Write_CD(0x8D,OLED_CMD);//set charge pump enable设定充电泵开启
OLED_Write_CD(0x14,OLED_CMD);//
OLED_Write_CD(0xAF,OLED_CMD);//--turn on oled panel——打开oled面板
for(uint8_t i=0;i<OLED_H;i++)
{
for(uint8_t j=0;j<OLED_L;j++)
{
OLED_Set_Pos(i,j);
OLED_BUF_SHOW[i][j]=OLED_BUF_TEMP[i][j];
OLED_Write_CD(OLED_BUF_SHOW[i][j],OLED_DATA);
}
}
}
//画点
//0 : 去掉点
//1 : 画上点
//2 : 对点状态进行翻转
void OLED_SET_Poin(uint16_t y,uint16_t x,uint8_t mod)
{
if(x < OLED_L && y < OLED_H*8)//防止数组越界操作
{
if(OLED_Show_flip)//屏幕颠倒
{
x = OLED_L - x;
y = (OLED_H*8)-y;
}
switch(mod)
{
case 0:OLED_BUF_TEMP[y/8][x] &=~(0x01<<(y%8));break;
case 1:OLED_BUF_TEMP[y/8][x] |= (0x01<<(y%8));break;
case 2:OLED_BUF_TEMP[y/8][x] ^= (0x01<<(y%8));break;
default:break;
}
}
}
//在缓冲区中读取一个点的状态
uint8_t OLED_GetPoin(uint8_t y,uint8_t x)
{
if(x < OLED_L && y < OLED_H*8)//防止数组越界操作
{
if(OLED_Show_flip)//屏幕颠倒
{
x = OLED_L - x;
y = (OLED_H*8) - y;
}
return (OLED_BUF_TEMP[y/8][x] & 0x01<<(y%8))?1:0;//返回状态
}
return 0;
}
//快速填充至BUF_TEM
void OLED_Fast_Fill_To_BUF(uint16_t y,uint16_t x,uint16_t h,uint16_t l,uint8_t *data)
{
for(uint16_t i=0;i<(h/8);i++)
for(uint16_t j=0;j<l;j++)
OLED_BUF_TEMP[y+i][x+j]=data[(i*l)+j];
}
//填充至BUF_TEM
void OLED_Fill_To_BUF(uint16_t y,uint16_t x,uint16_t h,uint16_t l,uint8_t *data)
{
for(uint16_t i=0;i<h/8;i++)
for(uint16_t j=0;j<l;j++)
for(uint8_t k=0;k<8;k++)
OLED_SET_Poin(y+(i*8)+k,x+j,(data[(i*l)+j]&(0x01<<k))?1:0);
}
//示例程序
void example_code()
{
uint8_t cs[]={
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,/*"A",0*/
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,/*"B",1*/
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,/*"C",2*/
};
OLED_Init();
for(uint8_t n=0;n<2;n++)
{
for(uint8_t i=0;i<OLED_H*8;i++)
{
for(uint8_t j=0;j<OLED_L;j++)
{
OLED_SET_Poin(i,j,2);
OLED_SHOW_Update();
}
}
}
OLED_Fast_Fill_To_BUF(0,0,16,8,cs);
while(1)
{
OLED_Fill_To_BUF(16,16,16,8,cs);
OLED_SHOW_Update();
HAL_Delay(10);
}
}
评论0