STM8 模拟I2C驱动0.91寸OLED屏
#define OLED_SCLK_Clr() GPIO_ResetBits(I2C_PORT, I2C_SDA_PIN )//SDA IIC接口的时钟信号
#define OLED_SCLK_Set() GPIO_SetBits(I2C_PORT, I2C_SDA_PIN )
#define OLED_SDIN_Clr() GPIO_ResetBits(I2C_PORT, I2C_SCL_PIN)//SCL IIC接口的数据信号
#define OLED_SDIN_Set() GPIO_SetBits(I2C_PORT, I2C_SCL_PIN)
/**************************************************
* 函数名称:Delay()
* 函数功能:简单延时
* 输入参数:nCount -计数时间
**************************************************/
void Delay(uint16_t nCount)
{
while (nCount != 0)
{
nCount--;
WWDG_SetCounter(0x7F); //喂狗
}
}
void Delay_(u32 nTime)
{
volatile unsigned int i;
WWDG_SetCounter(0x7F); //喂狗
while(nTime--)
{
i=1000;
while(i--);
WWDG_SetCounter(0x7F); //喂狗
}
}
void IIC_Start()
{
OLED_SCLK_Set() ;
OLED_SDIN_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
OLED_SCLK_Set();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
void IIC_Wait_Ack()
{
OLED_SCLK_Set() ;
OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
WWDG_SetCounter(0x7F); //喂狗
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
// OLED_SCLK_Clr();
m=m&0x80;
if(m==0x80)
{OLED_SDIN_Set();}
else OLED_SDIN_Clr();
da=da<<1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
Write_IIC_Data(dat);
}
else
{
Write_IIC_Command(dat);
}
}
/**************************************************
* 函数名称:OLED_WrDat()
* 函数功能:I2C向OLED发送数据
**************************************************/
void OLED_WrDat(uint8_t IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
void OLED_WrDat32(uint8_t IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x20); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
/**************************************************
* 函数名称:OLED_WrCmd()
* 函数功能:I2C向OLED发送命令
**************************************************/
void OLED_WrCmd(uint8_t IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
WWDG_SetCounter(0x7F); //喂狗
}
/**************************************************
* 函数名称:OLED_Set_Pos()
* 函数功能:OLED设置坐标点
**************************************************/
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
OLED_WrCmd(0xb0+y);
OLED_WrCmd(((x&0xf0)>>4)|0x10);
OLED_WrCmd((x&0x0f)|0x01);
}
/**************************************************
* 函数名称:OLED_Fill()
* 函数功能:OLED全屏写入
**************************************************/
void OLED_Fill(uint8_t bmp_dat)
{
uint8_t y,x;
for(y=0;y<Y_WIDTH/4;y++)
{
OLED_WrCmd(0xb0+y);
OLED_WrCmd(0x01);
OLED_WrCmd(0x10);
for(x=0;x<X_WIDTH;x++)
{OLED_WrDat(bmp_dat);}
}
}
/**************************************************
* 函数名称:OLED_CLS()
* 函数功能:OLED清屏
**************************************************/
void OLED_CLS(void)
{
uint8_t y,x;
for(y=0;y<Y_WIDTH/4;y++)
{
OLED_WrCmd(0xb0+y);
OLED_WrCmd(0x01);
OLED_WrCmd(0x10);
for(x=0;x<X_WIDTH;x++)
{OLED_WrDat(0x00);}
}
}
/**************************************************
* 函数名称:OLED_Init()
* 函数功能:OLED初始化
**************************************************/
void OLED_Init(void)
{
Delay(500); //初始化之前的延时很重要!
OLED_WrCmd(0xAE);//--turn off oled panel 关闭显示
OLED_WrCmd(0x00);//---set low column address
OLED_WrCmd(0x10);//---set high column address
OLED_WrCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WrCmd(0x81);//--set contrast control register设置对比度
OLED_WrCmd(Brightness); // Set SEG Output Current Brightness 设置对比度
OLED_WrCmd(0xA0);//--Set SEG/Column Mapping 0xA0左右反置 0xA1正常(显示前预设)
OLED_WrCmd(0xC0);//Set COM/Row Scan Direction 0xC0上下反置 0xC8正常
OLED_WrCmd(0xA6);//--set normal display
OLED_WrCmd(0xA8);//--set multiplex ratio(1 to 64)
OLED_WrCmd(0x3F);//--1/64 duty
OLED_WrCmd(0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WrCmd(0x00);//-not offset
OLED_WrCmd(0xD5);//--set display clock divide ratio/oscillator frequency
OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WrCmd(0xD9);//--set pre-charge period
OLED_WrCmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WrCmd(0xDA);//--set com pins hardware configuration
OLED_WrCmd(0x12);
OLED_WrCmd(0xDB);//--set vcomh
OLED_WrCmd(0x40);//Set VCOM Deselect Level
OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WrCmd(0x02);//
OLED_WrCmd(0x8D);//--set Charge Pump enable/disable
OLED_WrCmd(0x14);//--set(0x10) disable
OLED_WrCmd(0xA4);// Disable Entire Display On 0xA4全显 0xA5部分显示
OLED_WrCmd(0xA6);// Disable Inverse Display On 0xA6正显 0xA7反显
OLED_WrCmd(0xAF);//--turn on oled panel 开启显示
OLED_Fill(0x00); //初始清屏
OLED_Set_Pos(0,0);
}
/**************************************************
* 函数名称:OLED_Wakeup()
* 函数功能:将OLED从休眠中唤醒
**************************************************/
void OLED_Wakeup(void)
{
OLED_WrCmd(0X8D); //设置电荷泵
OLED_WrCmd(0X14); //开启电荷泵
OLED_WrCmd(0XAF); //OLED唤醒
}
/**************************************************
* 函数名称:OLED_Wakeup()
* 函数功能:OLED休眠,功耗不到10uA
**************************************************/
void OLED_Sleep(void)
{
OLED_WrCmd(0X8D); //设置电荷泵
OLED_WrCmd(0X10); //关闭电荷泵
OLED_WrCmd(0XAE); //OLED休眠
}
/**************************************************************************
* 函数名称:OLED_ShowStr(uint8_t x, uint8_t y, uint8_t ch[], uint8_t TextSize)
* 函数功能:OLED显示codetab.h中的ASCII字符,有6*8和8*16可选择
* 输入参数:x,y -- 起始点坐标(x:0~127, y:0~7);
ch[] -- 要显示的字符串;
TextSize -- 字符大小(1:6*8 ; 2:8*16)
**************************************************************************/
void OLED_ShowStr(uint8_t x, uint8_t y, uint8_t ch[], uint8_t TextSize)
{
uint8_t c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WrDat(F6x8[c][i]);
x += 6;
j++;
}
}break;
case 2:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WrDat(F8X16[c*16+i]);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WrDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
/**************************************************************************
* 函数名称:OLED_ShowCN(uint8_t x, uint8_t y, uint8_t N)
* 函数功能:显示codetab.h中的汉字,16*16点阵
* 输入参数:x,y -- 起始点坐标(x:0~127, y:0~7);
tab16[] -- 汉字编码表
N -- 汉字在codetab.h中的索引
**************************************************************************/
void OLED_ShowCN(uint8_t x, uint8_t y, uint8_t tab16[], uint8_t N)
{
uint8_t wm=0;
uint8_t adder=32*N;
OLED_Set_Pos(x, y);
for(wm = 0;wm < 16;wm++)
{
OLED_WrDat(tab16[adder]);
adder += 1;
}
OLED_Set_Pos(x,y+1);
for(wm = 0;wm < 16;wm++)
{
OLED_WrDat(tab16[adder]);
adder += 1;
}
}
/**************************************************************************
* 函数名称:OLED_DrawBMP(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[])
* 函数功能:显示BMP位图
* 输入参数:x0,y0 -- 起始点坐标(x0:0~127, y0:0~7);
x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
BMP[] -- 位图编码
**************************************************************************/
void OLED_ShowCN32(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[])
{
uint16_t j=0;
uint8_t x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_Set_Pos(x0,y);
for(x=x0;x<x1;x++)
{
OLED_WrDat(BMP[j++]);
}
}
WWDG_SetCounter(0x7F); //喂狗
}
/**************************************************************************
* 函数名称:OLED_ShowCN(uint8_t x, uint8_t y, uint8_t N)
* 函数功能:显示codetab.h中的汉字串,16*16点阵
* 输入参数:x,y -- 起始点坐标(x:0~127, y:0~7);
tab16[] -- 汉字编码表
len -- 字符串长度
**************************************************************************/
void OLED_ShowCNStr(uint8_t x, uint8_t y, uint8_t tab16[], uint8_t len)
{
uint8_t i;
OLED_Set_Pos(x, y);
for(i=0;i<len;i++)
{
OLED_ShowCN(22+i*16, y, (uint8_t *)tab16, i);//测试显示中文
}
}
/**************************************************************************
* 函数名称:OLED_DrawBMP(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[])
* 函数功能:显示BMP位图
* 输入参数:x0,y0 -- 起始点坐标(x0:0~127, y0:0~7);
x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
BMP[] -- 位图编码
**************************************************************************/
void OLED_DrawBMP(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[])
{
uint16_t j=0;
uint8_t x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_Set_Pos(x0,y);
for(x=x0;x<x1;x++)
{
OLED_WrDat(BMP[j++]);
}
}
}
/**************************************************************************
* 函数名称:OLED_DrawAll(uint8_t BMP[])
* 函数功能:全屏显示BMP位图,最大128*64像素
* 输入参数:BMP[] -- 位图编码
**************************************************************************/
void OLED_DrawAll(uint8_t BMP[])
{
uint16_t j=0;
uint8_t x,y;
for(y=0;y<Y_WIDTH/4;y++)
{
OLED_Set_Pos(0,y);
for(x=0;x<X_WIDTH;x++)
{
OLED_WrDat(BMP[j++]);
}
}
}