目前IICOLED屏幕是初学者常用的外设,本文将介绍STM32F407(所有STM32都大同小异)方面的oled驱动,下一篇文章将会介绍linux的IIC驱动。
OLED启动主要分为以下几步:
①屏幕初始化②开启屏幕显示③清屏(不清屏的话屏幕将会出现一片雪花)④发送要显示的字符串、数字、汉字等
一、工程建立
首先利用Stm32CubeMX软件建立工程,因屏幕是i2c通信因此此工程只配置i2c和时钟即可。
时钟配置:
i2c配置,本次选用的为i2c1:
然后生成工程即可。
二、代码编写
oled有写命令和写数据两种操作,写命令为配置某项功能时使用,写数据为向oled写显示内容时使用。具体实现代码如下:oled屏地址一般为0x78(可以根据屏幕后面有一电阻,看电阻连接0x78还是0x7A)。
//写命令void OLED_WR_CMD(uint8_t cmd){HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);}//写数据void OLED_WR_DATA(uint8_t data){HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);}
①屏幕初始化部分
网上有各种各样的初始化代码,这个一个是匹配我手上的oled屏幕的配置,如果驱动不成功,可以试一下其他的初始化代码。
void WriteCmd(){ OLED_WR_CMD(0xAE);//--turn off oled panelOLED_WR_CMD(0x00);//---set low column addressOLED_WR_CMD(0x10);//---set high column addressOLED_WR_CMD(0x40);//--set start line address Set Mapping RAM Display Start Line OLED_WR_CMD(0x81);//--set contrast control registerOLED_WR_CMD(0xCF);// Set SEG Output Current BrightnessOLED_WR_CMD(0xA1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常OLED_WR_CMD(0xC8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常OLED_WR_CMD(0xA6);//--set normal displayOLED_WR_CMD(0xA8);//--set multiplex ratio(1 to 64)OLED_WR_CMD(0x3f);//--1/64 dutyOLED_WR_CMD(0xD3);//-set display offsetShift Mapping RAM Counter (0x00~0x3F)OLED_WR_CMD(0x00);//-not offsetOLED_WR_CMD(0xd5);//--set display clock divide ratio/oscillator frequencyOLED_WR_CMD(0x80);//--set divide ratio, Set Clock as 100 Frames/SecOLED_WR_CMD(0xD9);//--set pre-charge periodOLED_WR_CMD(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WR_CMD(0xDA);//--set com pins hardware configurationOLED_WR_CMD(0x12);OLED_WR_CMD(0xDB);//--set vcomhOLED_WR_CMD(0x40);//Set VCOM Deselect LevelOLED_WR_CMD(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)OLED_WR_CMD(0x02);//OLED_WR_CMD(0x8D);//--set Charge Pump enable/disableOLED_WR_CMD(0x14);//--set(0x10) disableOLED_WR_CMD(0xA4);// Disable Entire Display On (0xa4/0xa5)OLED_WR_CMD(0xA6);// Disable Inverse Display On (0xa6/a7) OLED_Clear();OLED_WR_CMD(0xAF);}
②开启屏幕显示
//开启OLED显示 void OLED_Display_On(void){OLED_WR_CMD(0X8D); //SET DCDC命令OLED_WR_CMD(0X14); //DCDC ONOLED_WR_CMD(0XAF); //DISPLAY ON}//关闭OLED显示 void OLED_Display_Off(void){OLED_WR_CMD(0X8D); //SET DCDC命令OLED_WR_CMD(0X10); //DCDC OFFOLED_WR_CMD(0XAE); //DISPLAY OFF}
③清屏操作:
void OLED_Clear(){uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i);OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++)OLED_WR_DATA(0x00);} }
④配置显示内容:
其中F8x16和F6x8是自己添加的字符库。
/*输入内容为oled屏幕的显示坐标,要显示的字符、字符大小*/void OLED_ShowChar(uint8_t x,uint8_t y,uint8_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_Set_Pos(x,y);for(i=0;i<8;i++)OLED_WR_DATA(F8x16[c*16+i]);OLED_Set_Pos(x,y+1);for(i=0;i<8;i++)OLED_WR_DATA(F8x16[c*16+i+8]);}else {OLED_Set_Pos(x,y);for(i=0;i120){x=0;y+=2;}j++;}}unsigned char Hzk[][16]={ {0x00,0x80,0xC0,0xBC,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0xC0,0x80,0x00}, {0x00,0x40,0x20,0x10,0x0C,0x40,0x80,0x7F,0x00,0x00,0x04,0x08,0x30,0x60,0x00,0x00}, {0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x06,0x55,0x84,0x7E,0x04,0x00}, {0x40,0x3F,0x02,0x3F,0x40,0x3F,0x42,0x7F,0x10,0x13,0x12,0x12,0x5A,0x92,0x7E,0x00},};//显示汉字//hzk 用取模软件得出的数组void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no){ uint8_t t,adder=0;OLED_Set_Pos(x,y); for(t=0;t<16;t++){OLED_WR_DATA(Hzk[2*no][t]);adder+=1; }OLED_Set_Pos(x,y+1); for(t=0;t<16;t++){OLED_WR_DATA(Hzk[2*no+1][t]);adder+=1; }}//水平滚动void OLED_ver_scroll(){ OLED_WR_CMD(0x2e);//关滚动 OLED_WR_CMD(0x27);//29向右,2a向左 OLED_WR_CMD(0x00);//A:空字节 OLED_WR_CMD(0x02);//B:水平起始页 OLED_WR_CMD(0x07);//C:水平滚动速度 OLED_WR_CMD(0x03);//D:水平结束页 OLED_WR_CMD(0x00);//E:每次垂直滚动位移 OLED_WR_CMD(0xFF);//E:每次垂直滚动位移 OLED_WR_CMD(0x2f);//开滚动 }
主函数为:
int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); HAL_Delay(500); OLED_Display_On(); uint8_t A[]="hellow world !!!!"; uint8_t B[]="hellow world !!"; OLED_Init(); HAL_Delay(500); OLED_Display_On();pei OLED_Clear(); /*OLED_ShowString(0,0,A,sizeof(A));OLED_ShowString(0,4,A,sizeof(B));*/ OLED_ShowCHinese(0,2,0); OLED_ShowCHinese(16,2,1); OLED_ver_scroll(); while (1) { }}
至此就可以实现OLED的简单驱动了,下一期将会更新此olde屏幕在linux系统上的驱动配置。
本人并称开源思想以下我将附上我的代码希望大家多读点赞收藏支持。如失效,请及时与我联系
链接:https://pan.baidu.com/s/1_CTN0VSClB4VggR8OyRIcA
提取码:lpfx
创作不易,未经许可禁止转载