代码分享 STM32F103 OLED IIC CUBEIDE
最近一直在找IIC协议的oled屏幕hal代码,终于连抄带改找到一个能用的代码了。为了节省大家的时间特此分享出来。
硬件选择
这里作为演示的单片机为stm32f103c8t6最小系统板(蓝板),oled是某宝上12.5元的最普通的iic屏幕。
cube ide初始化配置
首先习惯性设置外部高速时钟(HSE)。
然后打开使能硬件IIC(这里以i2c1作为演示),下面的配置都不用调。
最后只需要设置一下时钟树就好
代码部分:
这里我就直接在Scr文档里头新建了一个oled.h文件和一个ascii.h文件。
ascii文件的程序可能有一点点小问题会报个warring但是不用管再编译一遍就好了。
先在main函数里包括一下这两个文件
#include"ascii.h"
#include"oled.h"
函数声明什么的都不用加。
这里是oled.h文件:
/*
* oled.h
*
* Created on: Oct 27, 2019
* Author: LIUJJ
*/
#ifndef INC_OLED_H_
#define INC_OLED_H_
#define OLED0561_ADD 0x78 // OLED��I2C��ַ����ֹ�ģ�
#define COM 0x00 // OLED ָ���ֹ�ģ�
#define DAT 0x40 // OLED ���ݣ���ֹ�ģ�
void WriteCmd(unsigned char I2C_Command)//写命�?????????
{
HAL_I2C_Mem_Write(&hi2c2,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT,&I2C_Command,1,100);
}
void WriteDat(unsigned char I2C_Data)//写数�?????????
{
HAL_I2C_Mem_Write(&hi2c2,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8BIT,&I2C_Data,1,100);
}
void OLED_Init(void)
{
HAL_Delay(100); //这里的延时很重要
WriteCmd(0xAE); //display off
WriteCmd(0x20); //Set Memory Addressing Mode
WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
WriteCmd(0xc8); //Set COM Output Scan Direction
WriteCmd(0x00); //---set low column address
WriteCmd(0x10); //---set high column address
WriteCmd(0x40); //--set start line address
WriteCmd(0x81); //--set contrast control register
WriteCmd(0xff); //亮度调节 0x00~0xff
WriteCmd(0xa1); //--set segment re-map 0 to 127
WriteCmd(0xa6); //--set normal display
WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
WriteCmd(0x3F); //
WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
WriteCmd(0xd3); //-set display offset
WriteCmd(0x00); //-not offset
WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
WriteCmd(0xf0); //--set divide ratio
WriteCmd(0xd9); //--set pre-charge period
WriteCmd(0x22); //
WriteCmd(0xda); //--set com pins hardware configuration
WriteCmd(0x12);
WriteCmd(0xdb); //--set vcomh
WriteCmd(0x20); //0x20,0.77xVcc
WriteCmd(0x8d); //--set DC-DC enable
WriteCmd(0x14); //
WriteCmd(0xaf); //--turn on oled panel
}
void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐�?????????
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_Data)//全屏填充
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
WriteDat(fill_Data);
}
}
}
void OLED_CLS(void)//清屏
{
OLED_Fill(0x00);
}
void OLED_ON(void)
{
WriteCmd(0X8D); //设置电荷�?????????
WriteCmd(0X14); //�?????????启电荷泵
WriteCmd(0XAF); //OLED唤醒
}
void OLED_OFF(void)
{
WriteCmd(0X8D); //设置电荷�?????????
WriteCmd(0X10); //关闭电荷�?????????
WriteCmd(0XAE); //OLED休眠
}
/*
* x,y初始坐标
* num�????显示的uint32型数
* lenth�????要显示的数字长度,从低位向高位数
* size暂未制作
* */
void OLED_ShowLagData(uint8_t x,uint8_t y,uint32_t num,uint8_t lenth,uint8_t size)
{
uint8_t j=lenth,i=0,c=0;
uint8_t GetData[10];
uint32_t CopeData=num;
for(i=0;i<lenth;i++)
{
GetData[i]=CopeData%10;
CopeData=CopeData/10;
}
while(j>0)
{
c=GetData[j-1]+16;
if(x> 126)//换行
{
x = 0;
y++;
}
OLED_SetPos(x,y);//setInte x y
for(i=0;i<6;i++)
{
WriteDat(F6x8[c][i]);}
//HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
//HAL_Delay(100);
x=x+6;
j--;
}
}
// Parameters : x,y -- 起始点坐�?????????(x:0~127, y:0~7); ch[] -- 要显示的字符�?????????; TextSize -- 字符大小(1:6*8 ; 2:8*16) lenth是字符串字数
// Description : 显示codetab.h中的ASCII字符,�?????????6*8�?????????8*16可�?�择
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[],unsigned char lenth, unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(j<lenth)
{
c = ch[j] - 32;
if(x> 126)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<6;i++)
{
WriteDat(F6x8[c][i]);}
//HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
//HAL_Delay(100);
x=x+6;
j++;
}
}break;
case 2:
{
while(j<lenth)
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
// Parameters : x,y -- 起始点坐�?????????(x:0~127, y:0~7); N:汉字�?????????.h中的索引
// Description : 显示ASCII_8x16.h中的汉字,16*16点阵
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
}
// Parameters : x0,y0 -- 起始点坐�?????????(x0:0~127, y0:0~7); x1,y1 -- 起点对角�?????????(结束�?????????)的坐�?????????(x1:1~128,y1:1~8)
// Description : 显示BMP位图
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
WriteDat(BMP[j++]);
}
}
}
void OLED_ShowChar(uint8_t x,uint8_t y,uint32_t chr,uint8_t Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的
if(x>128-1){
x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i+8]);
}
else {
OLED_SetPos(x,y);
for(i=0;i<6;i++)
WriteDat(F6x8[c][i]);
}
}
unsigned int oled_pow(unsigned int m,unsigned int n)
{
unsigned int result=1;
while(n--)result*=m;
return result;
}
#endif /* INC_OLED_H_ */
下面是ascii.h文件:
/*
* ascii.h
*
* Created on: Oct 27, 2019
* Author: LIUJJ
*/
#ifndef INC_ASCII_H_
#define INC_ASCII_H_
// ------------------ ASCII字模的数据表 ------------------------ //
// 码表从0x20~0x7e //
// 字库: 纵向取模下高位// (调用时要减512)
// -------------------------------------------------------------- //
unsigned char F16x16[] =
{
// 0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0x04,0x04,0x08,0xF0,0x00,0x00,0x00,0x00,0x00,
// 0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00,0x00,
0x10,0x94,0x53,0x32,0x1E,0x32,0x52,0x10,0x00,0x7E,0x42,0x42,0x42,0x7E,0x00,0x00,
0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00,/*"智”,0*/
0x08,0xCC,0x4A,0x49,0x48,0x4A,0xCC,0x18,0x00,0x7F,0x88,0x88,0x84,0x82,0xE0,0x00,
0x00,0xFF,0x12,0x12,0x52,0x92,0x7F,0x00,0x00,0x7E,0x88,0x88,0x84,0x82,0xE0,0x00,/*"能",1*/
0x40,0x20,0xF0,0x28,0x24,0x27,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00,
0x40,0x40,0x4F,0x49,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x49,0x4F,0x40,0x40,0x00,/*"鱼",2*/
0x50,0x48,0x47,0x44,0xFC,0x44,0x44,0x44,0x00,0x04,0x04,0xFC,0x04,0x04,0x04,0x00,
0x00,0x3E,0x20,0x20,0x3F,0x10,0x10,0x7E,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x00,/*"缸",3*/
0x04,0x24,0x44,0x84,0x64,0x9C,0x40,0x30,0x0F,0xC8,0x08,0x08,0x28,0x18,0x00,0x00,
0x10,0x08,0x06,0x01,0x82,0x4C,0x20,0x18,0x06,0x01,0x06,0x18,0x20,0x40,0x80,0x00,/*"欢",4*/
0x40,0x40,0x42,0xCC,0x00,0x00,0xFC,0x04,0x02,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,
0x00,0x40,0x20,0x1F,0x20,0x40,0x4F,0x44,0x42,0x40,0x7F,0x42,0x44,0x43,0x40,0x00,//迎5
0x40,0x40,0x42,0xCC,0x00,0x80,0x88,0x88,0xFF,0x88,0x88,0xFF,0x88,0x88,0x80,0x00,
0x00,0x40,0x20,0x1F,0x20,0x40,0x50,0x4C,0x43,0x40,0x40,0x5F,0x40,0x40,0x40,0x00,//进6
0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80,0x00,//入7
0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,//正8
0x08,0x08,0x88,0xC8,0x38,0x0C,0x0B,0x08,0x08,0xE8,0x08,0x08,0x08,0x08,0x08,0x00,