STM32 硬件IIC OLED
Posted 一只小阿大:)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32 硬件IIC OLED相关的知识,希望对你有一定的参考价值。
目录
OLED屏幕
OLED即有机发光管(Organic Light-Emitting Diode,OLED)。OLED显示技术具有自发光、广视角、几乎无穷高的对比度、较低功耗、极高反应速度、可用于绕曲性面板、使用温度范围广、构造及制程简单等有点,被认为是下一代的平面显示屏新兴应用技术。
OLED显示和传统的LCD显示不同,其可以自发光,所以不需要背光灯,这使得OLED显示屏相对于LCD显示屏尺寸更薄,同时显示效果更优。
常用的OLED屏幕有蓝色、黄色、白色等几种。屏的大小为0.96寸,像素点为128*64,所以我们称为0.96oled屏或者12864屏。
OLED屏幕特点
1.模块尺寸:23.7 *23.8mm
2.电源电压:3.3-5.5V
3.驱动芯片:SSD1306
4.测试平台:提供 k60/k10,9s12XS128,51,stm32,stm8等单片机
OLED屏幕接线说明
OLED屏幕显存
OLED本身是没有显存的,他的现存是依赖SSD1306提供的,而SSD1306提供一块显存。
SSD1306显存总共为128*64bit大小,SSD1306将这些显存分成了8页。每页包含了128个字节。
OLED屏幕原理
STM32内部建立一个缓存(共128*8个字节),每次修改的时候,只是修改STM32上的缓存(实际上就是SRAM),修改完后一次性把STM32上的缓存数据写入到OLED的GRAM。
这个方法也有坏处,对于SRAM很小的单片机(51系列)就比较麻烦。
OLED屏幕常用指令
命令0X81: 设置对比度。包含两个字节,第一个0X81为命令,随后方法是的一个字节要设置这个对比度,值越大屏幕越亮。
命令0XAE/0XAF: 0XAE为关闭显示命令,0XAF为开启显示命令
0X8D: 包含两个字节,第一个为命令字,第二个为设置值,第二个字节的BIT2表示电荷泵的开关状态,该位为1开启电荷泵,为0则关闭。模块初始化的时候,这个必须要开启,否则看不到屏幕显示。
命令0XB0~B7:用于设置页地址,其低三位的值对应GRAM页地址。
命令0X00~0X0F:用于设置显示时的起始列地址低四位。
命令0X10~0X1F: 用于设置显示时的起始列地址高四位。
OLED屏幕字模软件的使用
OLED点阵的点亮方式,举个显示”P”的例子,最左边位最高位P7。
1.可以看出,要想显示”P”,首先写入0x1f,则显示一个竖杠,之后控制器自动水平移动到下一列。
2.再写入0X05,则出现两个小横杆,这个两个横杆就是0X05中0000 0101中两个1所处的位置,写完第二列后,控制器自动跳到第三列.
3.再写入0X07,第四列写入0X00后,P就显示出来了。这也说明,即使你只想再一列的最上端显示一个小点,即写入0X01.
4.即你不能一次性控制一个点阵,只能一次性控制八位点阵,即一列点阵。这也决定了字模选择的取模方式为“列行式“。
代码
main.c
#include "stm32f10x.h"
#include "SysTick.h"
#include "oled.h"
extern const unsigned char BMP2[];
int main()
unsigned char i = 0;
initSysTick();
I2C_Config();
OLED_Init();
delay_ms(2000);
OLED_Fill(0XFF); //ÆÁÄ»ÁÁ
delay_ms(2000);
OLED_Fill(0X00); //ÆÁÄ»Ãð
delay_ms(2000);
// OLED_ShowStr(0, 3, "Hello World", 1);
// OLED_ShowStr(0, 4, "Hello World", 2);
while (1)
for(i=0;i<3;i++)
OLED_ShowMouMou(i*16, 0, i);
delay_ms(2000);
//显示图片
OLED_DrawBMP(0, 0, 128, 8, (unsigned char *)BMP2);
delay_ms(2000);
oled.h
#ifndef _OLED_H_
#define _OLED_H_
#include "stm32f10x.h"
#define OLED_ADDRESS 0x78
void I2C_Config(void);
void I2C_WriteByte(uint8_t addr,uint8_t data);
void I2C_WriteCmd(unsigned char I2C_Command);
void I2C_WriteData(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 y,unsigned char ch[],unsigned TextSize);
void OLED_ShowCN(unsigned char x,unsigned y,unsigned char N);
void OLED_ShowMouMou(unsigned char x,unsigned char y,unsigned char N);
#endif
oled.c
#include "stm32f10x.h"
#include "oled.h"
#include "delay.h"
#include "codetab.h"
/**
*¹¦ÄÜ£ºI2CÅäÖÃ
*²ÎÊý£ºvoid
*·µ»ØÖµ£ºvoid
*/
void I2C_Config(void)
GPIO_InitTypeDef GPIO_initStruct;
I2C_InitTypeDef I2C_initStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
//PB6 -- SCL PB7 -- SDA
GPIO_initStruct.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_initStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_initStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_initStruct);
I2C_DeInit(I2C1);
I2C_initStruct.I2C_Ack = I2C_Ack_Enable; //Ó¦´ðÊÇ·ñʹÄÜ
I2C_initStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //µØÖ·£¬Êý¾ÝλÊǶàÉÙ£¬ÓÐ7bitºÍ10bit
I2C_initStruct.I2C_ClockSpeed = 400000; //ʱÖÓËÙ¶È 400Kb
I2C_initStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 2:1 »òÕß16:9¶¼ÐÐ
I2C_initStruct.I2C_Mode = I2C_Mode_I2C; //ģʽI2Cģʽ
I2C_initStruct.I2C_OwnAddress1 = 0x30; //Ö÷»úµØÖ·£¬0x30Ëæ±ã¸øµÄ
I2C_Init(I2C1, &I2C_initStruct);
I2C_Cmd(I2C1, ENABLE);
/**
*¹¦ÄÜ£ºI2Cд×Ö½Ú
*²ÎÊý£ºaddr µØÖ·£¬data Êý¾Ý
*·µ»ØÖµ£ºvoid
*/
/* ΪɶÏÂÃæûEV8_2¾ÍÖ±½Ó¹Ø±ÕÁË£¬ÓÐwhileÑ»·»áµÈ´ýдÍ꣬ËùÒÔû±ØÒª */
void I2C_WriteByte(uint8_t addr,uint8_t data)
while( I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //¼ì²éI2C×ÜÏßÊÇ·ñ·±Ã¦
I2C_GenerateSTART( I2C1, ENABLE); //¿ªÆôI2C1
while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_MODE_SELECT )); //EV5 Ö÷ģʽ
I2C_Send7bitAddress(I2C1, OLED_ADDRESS , I2C_Direction_Transmitter ); //·¢ËÍÆ÷¼þµØÖ·
while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )); //EV6
I2C_SendData( I2C1 , addr ); //¼Ä´æÆ÷µØÖ·
while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_BYTE_TRANSMITTING )); //EV8
I2C_SendData( I2C1 , data ); //Òª·¢Ë͵ÄÊý¾Ý
while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_BYTE_TRANSMITTING )); //EV8
I2C_GenerateSTOP( I2C1, ENABLE ); //¹Ø±ÕI2C×ÜÏß
/**
*¹¦ÄÜ£ºÐ´ÃüÁî
*²ÎÊý£ºI2C_Command ÐèҪдÈëµÄÃüÁî
*·µ»ØÖµ£ºvoid
*/
void WriteCmd(unsigned char I2C_Command)
I2C_WriteByte(0x00,I2C_Command);
/**
*¹¦ÄÜ£ºÐ´Êý¾Ý
*²ÎÊý£ºI2C_Data ÐèҪдÈëµÄÊý¾Ý
*·µ»ØÖµ£ºvoid
*/
void WriteData(unsigned char I2C_Data)
I2C_WriteByte(0x40,I2C_Data);
/**
*¹¦ÄÜ£º³õʼ»¯OLED
*²ÎÊý£ºvoid
*·µ»ØÖµ£ºvoid
*/
void OLED_Init(void)
delay_ms(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
/**
*¹¦ÄÜ£ºÉèÖÃ×ø±ê
*²ÎÊý£ºx xÖᣬy yÖá
*·µ»ØÖµ£ºvoid
*/
void OLED_SetPos(unsigned char x,unsigned char y)
WriteCmd(0xb0 + y);
WriteCmd((x&0xf0)>>4|0x10);
WriteCmd((x&0x0f)|0x01);
/**
*¹¦ÄÜ£ºÈ«ÆÁÌî³ä
*²ÎÊý£ºFill_Data ÐèÒªÌî³äµÄÊý¾Ý
*·µ»ØÖµ£ºvoid
*/
void OLED_Fill(unsigned char Fill_Data)
unsigned char n;
unsigned char m;
for(m=0;m<8;m++)
WriteCmd(0xb0 + m);
WriteCmd(0x00);
WriteCmd(0x10);
for(n=0;n<128;n++)
WriteData(Fill_Data);
/**
*¹¦ÄÜ£ºÇåÆÁ
*²ÎÊý£ºvoid
*·µ»ØÖµ£ºvoid
*/
void OLED_CLS(void)
OLED_Fill(0x00);
/**
*¹¦ÄÜ£º¿ªÆôOLED
*²ÎÊý£ºvoid
*·µ»ØÖµ£ºvoid
*/
void OLED_ON(void)
WriteCmd(0x8D); //ÉèÖõçºÉ±Ã
WriteCmd(0x14); //¿ªÆôµçºÉ±Ã
WriteCmd(0xAF); //¿ªÆôÏÔʾ
/**
*¹¦ÄÜ£º¹Ø±ÕOLED
*²ÎÊý£ºvoid
*·µ»ØÖµ£ºvoid
*/
void OLED_OFF(void)
WriteCmd(0x8D); //ÉèÖõçºÉ±Ã
WriteCmd(0x10); //¹Ø±ÕµçºÉ±Ã
WriteCmd(0xAE); //¹Ø±ÕÏÔʾ
void OLED_ShowStr(unsigned char x,unsigned y,unsigned char ch[],unsigned TextSize)
unsigned char c = 0;
unsigned char i = 0;
unsigned char j = 0;
switch(TextSize) //Ñ¡Ôñģʽ
case 1:
while(ch[j] != '\\0') //ÅжÏÊÇ·ñµ½´ï×îºóһλ
c = ch[j] - 32; //´óСдת»»
if(x > 126) //ÅжÏÆÁÄ»ÊÇ·ñ·ÅµÃÏÂ,OLEDÊÇ128*8×Ö½Ú
x = 0;
y++;
OLED_SetPos(x,y);//ÉèÖÃ×ø±ê
for(i=0;i<6;i++)
WriteData(F6x8[c][i]);
x+=6;
j++;
break;
case 2:
while(ch[j] != '\\0') //ÅжÏÊÇ·ñµ½´ï×îºóһλ
c = ch[j] - 32; //´óСдת»»
if(x > 120) //ÅжÏÆÁÄ»ÊÇ·ñ·ÅµÃÏÂ,OLEDÊÇ128*8×Ö½Ú
x = 0;
y++;
OLED_SetPos(x,y); //ÉèÖÃ×ø±ê
for(i=0;i<8;i++) //ÒòΪÊÇ16½øÖƵÄËùÒÔ·ÖΪÁ½¸ö8λÀ´Ð´£¬ÕâÊÇÉϰ벿·Ö
WriteData(F8X16[c*16+i]);
OLED_SetPos(x,y+1); //ÉèÖÃ×ø±ê Èç¹ûÕâÀïÉèÖõÄÊÇy²»ÊÇy+1»áµ¼ÖÂÏÔʾµÄ×Ö·û´®Ö»ÏÔʾһ°ë
for(i=0;i<8;i++) //Ìøתµ½ÏÂÒ»Ò³£¬ÕâÊÇÏ°벿·Ö
WriteData(F8X16[c*16+i+8]);
x+=8;
j++;
break;
void OLED_ShowCN(unsigned char x,unsigned y,unsigned char N)
unsigned char i;
unsigned int addr = 32*N;
OLED_SetPos(x,y);
for(i=0;i<16;i++)
WriteData(F16X16[addr]);
addr += 1;
OLED_SetPos(x,y+1);
for(i=0;i<16;i++)
WriteData(F16X16[addr]);
addr += 1;
void OLED_ShowMouMou(unsigned char x,unsigned char y,unsigned char N)
unsigned char i;
unsigned int addr = 32*N;
OLED_SetPos(x,y);
for(i=0;i<16;i++)
WriteData(MouMou[addr]);
addr += 1;
OLED_SetPos(x,y+1);
for(i=0;i<16;i++)
WriteData(MouMou[addr]);
addr += 1;
codetab.h
//unsigned char F16X16[] =
//
// 0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
// 0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"ζÈ",0*/
// 0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
// 0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"ʪ¶È",1*/
//;
unsigned char F16X16[] =
0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30,0x00,0x00,
0x00,0x0F,0x04,0x04,0x0F,0x08,0x0A,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x08,0x00,/*"ßè",0*/
0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30,0x00,0x00,
0x00,0x0F,0x04,0x04,0x0F,0x08,0x0A,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x08,0x00,/*"ßè",1*/
;
unsigned char MouMou[] =
0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30,0x00,0x00,
0x00,0x0F,0x04,0x04,0x0F,0x08,0x0A,0x09,0x09,0x09,0xFF,0x09,0x09以上是关于STM32 硬件IIC OLED的主要内容,如果未能解决你的问题,请参考以下文章
STM32使用IIC总线通讯协议在OLED屏幕上显示字符串汉字图像(硬件IIC)
STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)