简单的说下OLED
OLED,即有机发光二极管。LCD 需要背光,而且OLED不需要,因为它是自发光的。同样的显示OLED效果更好。OLED分辨率是128*64 供电电压可为3-5V 使用4针支持8600和8080通信协议IIC协议控制通信IIC我不会详细介绍通讯,也不会说太多。我们直接上代码
使用下面的代码stm32f基于标准库的103单片机
注:如果要更换不同型号的单片机,只需修改端口,与引用文件相同。我还在代码中标记了修改点
OLED_I2C.h
#ifndef __OLED_I2C_H #define __OLED_I2C_H #include "stm32f10x.h" #define OLED_ADDRESS 0x78 //通过调整0R电阻,屏幕可以0x78和0x7A两个地址 -- 默认0x78 #define I2C_Speed 400000 /*I2C接口 代码迁移修改点 */ #define OLED_I2C I2C1 #define OLED_I2C_CLK RCC_APB1Periph_I2C1 #define OLED_I2C_CLK_INIT RCC_APB1PeriphClockCmd #define OLED_I2C_SCL_PIN GPIO_Pin_6 #define OLED_I2C_SCL_GPIO_PORT GPIOB #define OLED_I2C_SCL_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_I2C_SCL_SOURCE GPIO_PinSource6 #define OLED_I2C_SCL_AF GPIO_AF_I2C1 #define OLED_I2C_SDA_PIN GPIO_Pin_7 #define OLED_I2C_SDA_GPIO_PORT GPIOB #define OLED_I2C_SDA_GPIO_CLK RCC_APB2Periph_GPIOB #define OLED_I2C_SDA_SOURCE GPIO_PinSource7 #define OLED_I2C_SDA_AF GPIO_AF_I2C1
void I2C_Configuration(void);
void I2C_WriteByte(uint8_t addr,uint8_t data);
void WriteCmd(unsigned char I2C_Command);
void WriteDat(unsigned char I2C_Data);
void OLED_Init(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
#endif
OLED_I2C.c
/* * 功能列表: * 1. void I2C_Configuration(void) -- 配置CPU的硬件I2C * 2. void I2C_WriteByte(uint8_t addr,uint8_t data) -- 向寄存器地址写一个byte的数据 * 3. void WriteCmd(unsigned char I2C_Command) -- 写命令 * 4. void WriteDat(unsigned char I2C_Data) -- 写数据 * 5. void OLED_Init(void) -- OLED屏初始化 * 6. void OLED_SetPos(unsigned char x, unsigned char y) -- 设置起始点坐标 * 7. void OLED_Fill(unsigned char fill_Data) -- 全屏填充 * 8. void OLED_CLS(void) -- 清屏 * 9. void OLED_ON(void) -- 唤醒 * 10. void OLED_OFF(void) -- 睡眠 * 11. void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize) -- 显示字符串(字体大小有6*8和8*16两种) * 12. void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N) -- 显示中文(中文需要先取模,然后放到codetab.h中) * 13. void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]) -- BMP图片 * */ #include "OLED_I2C.h" //OLED_IIC通讯h文件 #include "codetab.h" //字模h文件 #include "./systick/bsp_SysTick.h" //延时函数h文件 void I2C_Configuration(void) /* 代码迁移修改点 */ { //开启IIC和IIC端口配置 I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /*I2C1外设时钟使能 */ OLED_I2C_CLK_INIT(OLED_I2C_CLK,ENABLE); /*I2C1外设GPIO时钟使能 */ RCC_APB2PeriphClockCmd(OLED_I2C_SCL_GPIO_CLK | OLED_I2C_SDA_GPIO_CLK,ENABLE); /* I2C_SCL、I2C_SDA*/ GPIO_InitStructure.GPIO_Pin = OLED_I2C_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出 GPIO_Init(OLED_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = OLED_I2C_SDA_PIN; GPIO_Init(OLED_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); /* I2C 配置 */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */ I2C_InitStructure.I2C_OwnAddress1 =OLED_ADDRESS; //主机的I2C地址 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* I2C的寻址模式 */ I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; /* 通信速率 */ I2C_Init(OLED_I2C, &I2C_InitStructure); /* I2C1 初始化 */ I2C_Cmd(OLED_I2C, ENABLE); /* 使能I2C1*/ } void I2C_WriteByte(uint8_t addr,uint8_t data) { while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/ I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 默认0x78 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, addr);//寄存器地址 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1, data);//发送数据 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线 } void WriteCmd(unsigned char I2C_Command)//写命令 { I2C_WriteByte(0x00, I2C_Command); } void WriteDat(unsigned char I2C_Data)//写数据 { I2C_WriteByte(0x40, I2C_Data); } void OLED_Init(void) { //这个延时函数就根据单片机自己构建一个,没准确时间要求,这里我就不提供库文件 Delay_s(1); // 1s,这里的延时很重要,上电后延时,没有错误的冗余设计,也就是等待oled工作稳定 WriteCmd(0xAE); //关闭显示 WriteCmd(0x20); //设置内存地址模式 WriteCmd(0x10); //00,列地址模式;01,行地址模式;10(默认),页地址模式;11,无效 WriteCmd(0xb0); //设置页地址,其中低三位的值对应GRAM地址:B0-B7 WriteCmd(0xc8); //设置COM输出扫描方向 WriteCmd(0x00); //---设置低列地址 WriteCmd(0x10); //---设置高列地址 WriteCmd(0x40); //--设置起始行地址 WriteCmd(0x81); //--设置对比度控制寄存器 WriteCmd(0xff); //亮度调节 0x00~0xff WriteCmd(0xa1); //--将段重新映射0设置为127 WriteCmd(0xa6); //--设置正常显示 WriteCmd(0xa8); //--设置多路复用比率(1到64) WriteCmd(0x3F); // WriteCmd(0xa4); //0xa4,输出跟随RAM内容;0xa5,输出忽略RAM内容 WriteCmd(0xd3); //-设置显示偏移 WriteCmd(0x00); //-不抵消 WriteCmd(0xd5); //--设置显示时钟分频比/
振荡器频率 WriteCmd(0xf0); //--设定分割比率 WriteCmd(0xd9); //--设定预充电时间 WriteCmd(0x22); // WriteCmd(0xda); //--设置com引脚硬件配置 WriteCmd(0x12); WriteCmd(0xdb); //--set vcomh WriteCmd(0x20); //0x20,0.77xVcc WriteCmd(0x8d); //--设置DC-DC启用 WriteCmd(0x14); // WriteCmd(0xaf); //--开启显示 } 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) //让OLED休眠 { WriteCmd(0X8D); //设置电荷泵 WriteCmd(0X10); //关闭电荷泵 WriteCmd(0XAE); //OLED休眠 } /** * @brief OLED_ShowStr,显示codetab.h中的ASCII字符,有6*8和8*16可选择 * @param x,y : 起始点坐标(x:0~127, y:0~7); * ch[] :- 要显示的字符串; * Size : 字符大小(1:6*8 ; 2:8*16) * @retval 无 */ void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char Size) { unsigned char c = 0,i = 0,j = 0; switch(Size) { case 1: { while(ch[j] != '\0') { c = ch[j] - 32; if(x > 126) { x = 0; y++; } OLED_SetPos(x,y); for(i=0;i<6;i++) WriteDat(F6x8[c][i]); x += 6; j++; } }break; case 2: { while(ch[j] != '\0') { 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; } } /** * @brief OLED_ShowCN,显示codetab.h中的汉字,16*16点阵 * @param x,y: 起始点坐标(x:0~127, y:0~7); * N:汉字在codetab.h中的索引 * @retval 无 */ 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; } } /** * @brief OLED_DrawBMP,显示BMP位图 * @param x0,y0 :起始点坐标(x0:0~127, y0:0~7); * x1,y1 : 起点对角线(结束点)的坐标(x1:1~128,y1:1~8) * @retval 无 */ 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++]); } } }
codetab.h
#ifndef __CODETAB_H #define __CODETAB_H /***************************16*16的点阵字体取模方式:共阴——列行式——逆向输出*********/ unsigned char F16x16[] = { 0x00,0x40,0x40,0x5F,0xF5,0x55,0x55,0x55,0x55,0x55,0xF5,0x5F,0x40,0x40,0x00,0x00, 0x09,0x09,0x85,0x45,0x2B,0x51,0x81,0x7D,0x01,0x11,0x2B,0x45,0x85,0x09,0x09,0x00,/*"暴",0*/ 0x10,0xEC,0x27,0xE4,0x34,0xEC,0x00,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x00,0x00, 0x40,0xCF,0x49,0x2F,0x29,0x2F,0x40,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x40,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*/ }; /************************************6*8的点阵************************************/ const unsigned char F6x8[][6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// ! 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// " 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// # 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23, 标签:
二极管sp0402u7a3二极管