STM32F1xx外设IIC驱动四线OLED
1、打开Keil uVision5,建立STM32F1xx工程。
Toolchain : MDK-ARM Professional Version: 5.30.0.0
STM32F1xx支持包 : Keil.STM32F1xx_DFP.2.3.0.pack



2、OLED GPIO定义
#define OLED_GPIO GPIOB
#define OLED_SCK_Pin GPIO_Pin_10
#define OLED_SDA_Pin GPIO_Pin_11
#define OLED_SCK_SET() GPIO_SetBits(OLED_GPIO, OLED_SCK_Pin)
#define OLED_SCK_CLR() GPIO_ResetBits(OLED_GPIO, OLED_SCK_Pin)




3、IIC写字节。
wByte字节数据
static void vIIC_WriteByte(u8 wByte)
{
u8 i = 0;
OLED_SCK_CLR();
for(i=0; i<BYTE_BIT; i++)
{
if((wByte << i) & 0x80)
OLED_SDA_SET();
else
OLED_SDA_CLR();
OLED_SCK_SET();
OLED_SCK_CLR();
}
}



4、写命令。
static void vIIC_WriteCmd(u8 wCmd)
{
vIIC_Start();
vIIC_WriteByte(0x78);
vIIC_WaitAck();
vIIC_WriteByte(0x00);
vIIC_WaitAck();
vIIC_WriteByte(wCmd);
vIIC_WaitAck();
vIIC_Stop();
}
写数据。
static void vIIC_WriteData(u8 wDat)
{
vIIC_Start();
vIIC_WriteByte(0x78);
vIIC_WaitAck();
vIIC_WriteByte(0x40);
vIIC_WaitAck();
vIIC_WriteByte(wDat);
vIIC_WaitAck();
vIIC_Stop();
}








5、画点函数
static void vOLED_DrawPoint(u8 x, u8 y, u8 mode)
{
u8 pos = 0, bx = 0, temp = 0;
if((x > (OLED_XWIDTH_PHYSICS - 1)) || (y > (OLED_YHEIGHT_PHYSICS - 1)))//Valid site
return;
pos = (OLED_PAGE_SIZE - 1) - (y / OLED_PAGE_SIZE);
bx = y % OLED_PAGE_SIZE;
temp = 1 << ((OLED_PAGE_SIZE - 1) - bx);
if(mode)
OLED_GRAM[x][pos] |= temp;
else
OLED_GRAM[x][pos] &= ~temp;
}
填充或者清空矩形
void vOLED_FillClearRectangle(u8 x1, u8 y1, u8 x2, u8 y2, u8 mode)
{
u8 x,y;
for(x=x1; x<=x2; x++)
{
for(y=y1; y<=y2; y++)
vOLED_DrawPoint(x,y, mode);
}
}









6、显示一个字符
static void vOLED_ShowChar(u8 x, u8 y, u8 chr, u8 size)
{
u8 bChar = 0, t = 0, i = 0;
u8 cbSize = 0, y0 = y;
cbSize = ((size/BYTE_BIT) + ((size%BYTE_BIT) ? 1 : 0)) * (size/HALF_WORD_BYTE);//Get byte number of a char
chr = chr-' ';
for(t=0; t<cbSize; t++)
{
if(size == OLED_FONT_1206_SIZE)
bChar = ASCII_1206[chr][t];
else if(size == OLED_FONT_1608_SIZE)
bChar = ASCII_1608[chr][t];
else if(size == OLED_FONT_2412_SIZE)
bChar = ASCII_2412[chr][t];
else
return;
for(i=0; i<BYTE_BIT; i++)
{
if((bChar << i) & 0x80)
vOLED_DrawPoint(x, y, 1);
y++;
if((y-y0) == size)
{
y = y0;
x++;
break;
}
}
}
}
显示字符串
void vOLED_ShowString(u8 x, u8 y, u8 size, const u8 * pStr)
{
while((*pStr <= '~') && (*pStr >= ' '))
{
if(x > (OLED_XWIDTH_PHYSICS - (size/HALF_WORD_BYTE)))
{
y += size;
x = 0;
}
if(y > (OLED_YHEIGHT_PHYSICS - size))
{
y = x= 0;
vOLED_Clear();
}
vOLED_ShowChar(x, y, *pStr, size);
x += (size/HALF_WORD_BYTE);
pStr++;
}
}






7、显示数字
void vOLED_ShowNum(u8 x, u8 y, u8 size, u8 len, u32 num)
{
u8 t,temp;
u8 enshow=0;
for(t=0; t<len; t++)
{
temp = (num/mypow(10, len-t-1)) % 10;
if((!enshow) && (t < (len-1)))
{
if(temp == 0)
{
vOLED_ShowChar(x+(size/2)*t, y, ' ', size);
continue;
}
else
enshow=1;
}
vOLED_ShowChar(x+(size/2)*t, y, temp+'0', size);
}
}
显示中文
void vOLED_ShowChinese(u8 x, u8 y, const u8 (*pFont)[16], u8 index)
{
u8 i = 0;
u8 n = 0;
u8 y0 = y;
u8 dat = 0;
for(n=0; n<HALF_WORD_BIT; n++)
{
for(i=0; i<BYTE_BIT; i++)
{
dat = *(pFont[index*2] + n);
if((dat << i) & 0x80)
vOLED_DrawPoint(x, y, 1);
y++;
if((y-y0) == 16)
{
y = y0;
x++;
break;
}
}
}
for(n=0; n<HALF_WORD_BIT; n++)
{
for(i=0; i<BYTE_BIT; i++)
{
dat = *(pFont[index*2 + 1] + n);
if((dat << i) & 0x80)
vOLED_DrawPoint(x, y, 1);
y++;
if((y-y0) == 16)
{
y = y0;
x++;
break;
}
}
}
}
显示图片
void vOLED_ShowBitmp(u8 x, u8 y, u8 xWidth, u8 yHeight, const u8 * pImage)
{
u8 k = 0, j = 0;
u8 i = 0, n = 0;
u8 yMax = 0;
u8 y0 = y;
yMax = ((yHeight % BYTE_BIT) == 0) ? (yHeight / BYTE_BIT) : (( yHeight / BYTE_BIT) + 1);
for(k=0; k<xWidth; k++)
{
for(j=0; j<yMax; j++)
{
for(i=0; i<BYTE_BIT; i++)
{
if((pImage[n] << i) & 0x80)
vOLED_DrawPoint(x, y, 1);
y++;
if((y-y0) == yHeight)
{
y = y0;
x++;
break;
}
}
n++;
}
}
}






8、 vOLED_ShowChinese(0, 0, ZHtest, 0);
vOLED_ShowChinese(16, 0, ZHtest, 1);
vOLED_ShowChinese(32, 0, ZHtest, 2);
vOLED_ShowChinese(48, 0, ZHtest, 3);
vOLED_ShowChinese(64, 0, ZHtest, 4);
vOLED_ShowChinese(80, 0, ZHtest, 5);
vOLED_ShowBitmp(105, 0, 24, 16, IMGtest);
vOLED_ShowNum(45, 14, 24, 3, 888);
vOLED_ShowString(10, 39, 12, (const u8 *)"xSuper Raphael Ceo");
vOLED_ShowString(0, 52, 12, (const u8 *)__DATE__);
vOLED_ShowString(80, 52, 12, (const u8 *)__TIME__);
vOLED_GRAM_Update();
void vIWDG_Task(void *pdata)
{
u8 i = 0;
while(1)
{
OSTimeDlyHMSM(0, 0, 1, 0);
vOLED_FillClearRectangle(45, 16, 80, 38, 0);
vOLED_ShowNum(45, 14, 24, 3, i++);
vOLED_GRAM_Update();
LED3 = ~LED3;
}
}









