一、OLED显示屏

STC15W408AS单片机并没有提供IIC总线的接口,但是我们可以通过模拟IIC的方式实现。关于IIC总线的只是大家可以自行上网搜索。这里以驱动SSD1306芯片的0.96寸的128*64的OLED显示屏为例。下图为OLED的外观图。

二、SSD1306芯片的IIC时序图

这里我们需要看清楚START信号和STOP信号。关于时间,芯片的数据手册也有说明。

IIC数据传输格式

这个是芯片的数据传输格式。

2) The slave address is following the start condition for recognition use. For the SSD1306, the slave  address is either “b0111100” or “b0111101” by changing the SA0 to LOW or HIGH (D/C pin acts as  SA0).

手册中的这句话和上图右下角的,也说明了芯片的器件地址是0x78或者0x79。至于我们用的OLED液晶是哪一个,需要我们用这两个地址测试,我没找到哪个手册有说明,具体是哪一个。关于芯片的寄存器,手册上面有很多,这里不做说明,自己查阅手册即可。

三、测试程序

1.IIC.h文件

#ifndef __IIC_H_
#define __IIC_H_
#define u16 unsigned int
#define u8  unsigned charvoid IIC_Start();
void IIC_Stop();
void IIC_Write_Byte(u8 byte);
void IIC_Wait_Ack();
void IIC_Write_Command(u8 cmd);
void IIC_Write_Data(u8 dat);
#endif

2.IIC.c文件

#include "stc15.h"
#include "iic.h"
#define IIC_SCL   P10   // 时钟
#define IIC_SDA   P11   // 数据
// IIC 开始信号
void IIC_Start()
{IIC_SCL = 1 ;IIC_SDA = 1;IIC_SDA = 0;IIC_SCL = 0;
}
// IIC 停止信号
void IIC_Stop()
{IIC_SCL = 1 ;
//  IIC_SCL = 0;IIC_SDA = 0;IIC_SDA = 1;
}
// IIC 应答信号
void IIC_Wait_Ack()
{IIC_SCL = 1 ;IIC_SCL = 0;
}
// IIC 写一字节数据
void IIC_Write_Byte(u8 IIC_Byte)
{u8 i;u8 m,da;da = IIC_Byte;IIC_SCL = 0;for(i = 0;i < 8;i++)     {m = da;//  IIC_SCL = 0;m = m&0x80;if(m==0x80){IIC_SDA = 1;}else IIC_SDA = 0;da = da<<1;IIC_SCL = 1;IIC_SCL = 0;}
}

3.OLED.h文件

#ifndef __OLED_H_
#define __OLED_H_
#define u16 unsigned int
#define u8  unsigned char#define OLED_CMD  0  // 写命令
#define OLED_DATA 1  // 写数据
#define OLED_MODE 0 // 显示模式
//OLED模式设置
//0:4线串行模式
//1:并行8080模式
#define OLED_Address 0x78
#define OLED_Cmd  0x00
#define OLED_Data 0x40
#define SIZE 16
#define XLevelL    0x02
#define XLevelH    0x10
#define Max_Column  128
#define Max_Row    64
#define  Brightness  0xFF
#define X_WIDTH   128
#define Y_WIDTH   64
//OLED控制用函数
void OLED_WR_Byte(u8 dat,u8 cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
void OLED_ShowNum(u8 x,u8 y,u16 num,u8 len,u8 size2);
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);
void OLED_Set_Pos(u8 x, u8 y);
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
void OLED_DrawBMP(u8 x0, u8 y0,u8 x1, u8 y1,u8 BMP[]);
void fill_picture(u8 fill_Data);
void Picture();
#endif

4.OLED.c文件

#include "oled.h"
#include "iic.h"
#include "oledfont.h"
// IIC 写命令
void IIC_Write_Command(u8 IIC_Command)
{IIC_Start();IIC_Write_Byte(OLED_Address);           IIC_Wait_Ack();   IIC_Write_Byte(OLED_Cmd);       IIC_Wait_Ack();   IIC_Write_Byte(IIC_Command);  IIC_Wait_Ack();   IIC_Stop();
}
// IIC 写数据
void IIC_Write_Date(u8 IIC_Data)
{IIC_Start();IIC_Write_Byte(OLED_Address);     IIC_Wait_Ack();   IIC_Write_Byte(OLED_Data);   IIC_Wait_Ack();   IIC_Write_Byte(IIC_Data);IIC_Wait_Ack();   IIC_Stop();
}
// 往OLED写一字节数据
void OLED_WR_Byte(u8 dat,u8 cmd)
{if(cmd){IIC_Write_Date(dat);}else {IIC_Write_Command(dat);   }
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(u8 fill_Data)
{u8 m,n;for(m=0;m<8;m++){OLED_WR_Byte(0xb0+m,0);    //page0-page1OLED_WR_Byte(0x00,0);    //low column start addressOLED_WR_Byte(0x10,0);    //high column start addressfor(n=0;n<128;n++){OLED_WR_Byte(fill_Data,1);}}
}
//坐标设置
void OLED_Set_Pos(u8 x, u8 y)
{    OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ONOLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{   u8 i,n;         for(i=0;i<8;i++)   {   OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);  } //更新显示
}
void OLED_On(void)
{   u8 i,n;         for(i=0;i<8;i++)   {   OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);  } //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{         u8 c=0,i=0;   c=chr-' ';//得到偏移后的值      if(x>Max_Column-1){x=0;y=y+2;}if(Char_Size ==16){OLED_Set_Pos(x,y);   for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);OLED_Set_Pos(x,y+1);for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);}else {   OLED_Set_Pos(x,y);for(i=0;i<6;i++)OLED_WR_Byte(F6x8[c][i],OLED_DATA);}
}
//m^n函数
u16 oled_pow(u8 m,u8 n)
{u16 result=1;    while(n--)result*=m;     return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式  0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u16 num,u8 len,u8 size2)
{            u8 t,temp;u8 enshow=0;                for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(size2/2)*t,y,' ',size2);continue;}else enshow=1;  }OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);  }
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{u8 j=0;while (chr[j]!='\0'){     OLED_ShowChar(x,y,chr[j],Char_Size);x+=8;if(x>120){x=0;y+=2;}j++;}
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{                 u8 t;OLED_Set_Pos(x,y);   for(t=0;t<16;t++){OLED_WR_Byte(Hzk[no][t],OLED_DATA);}   OLED_Set_Pos(x,y+1);   for(t=0;t<16;t++){   OLED_WR_Byte(Hzk[no][t+16],OLED_DATA);}
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(u8 x0, u8 y0,u8 x1, u8 y1,u8 BMP[])
{    u16 j=0;u8 x,y;if(y1%8==0) y=y1/8;       else y=y1/8+1;for(y=y0;y<y1;y++){OLED_Set_Pos(x0,y);for(x=x0;x<x1;x++){       OLED_WR_Byte(BMP[j++],OLED_DATA);         }}
}
//初始化SSD1306
void OLED_Init(void)
{    OLED_WR_Byte(0xAE,OLED_CMD);//Set Display ON/OFF 关闭显示OLED_WR_Byte(0x40,OLED_CMD);//Set Display Start LineOLED_WR_Byte(0xB0,OLED_CMD);//Set Page Start Address for Page Addressing ModeOLED_WR_Byte(0xC8,OLED_CMD);//重映射模式OLED_WR_Byte(0x81,OLED_CMD);//设置对比度OLED_WR_Byte(0xFF,OLED_CMD);OLED_WR_Byte(0xA1,OLED_CMD);//垂直寻址方式OLED_WR_Byte(0xA6,OLED_CMD);//正常显示OLED_WR_Byte(0xA8,OLED_CMD);//设置驱动路数OLED_WR_Byte(0x1F,OLED_CMD);OLED_WR_Byte(0xD3,OLED_CMD);//Set Display Offset 设置垂直移位0d~63dOLED_WR_Byte(0x00,OLED_CMD);OLED_WR_Byte(0xD5,OLED_CMD);//Set Display Clock Divide Ratio/ Oscillator FrequencyOLED_WR_Byte(0xF0,OLED_CMD);OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-charge PeriodOLED_WR_Byte(0x22,OLED_CMD);//Set Page AddressOLED_WR_Byte(0xDA,OLED_CMD);//设置COM引脚硬件配置OLED_WR_Byte(0x02,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD);//调整VCOMH调节器输出OLED_WR_Byte(0x49,OLED_CMD);OLED_WR_Byte(0x8D,OLED_CMD);OLED_WR_Byte(0x14,OLED_CMD);OLED_WR_Byte(0xAF,OLED_CMD);//Set Display ON/OFF 打开显示OLED_Clear();
} 

关于字体文件和图片数据文件这里不贴代码了。关于其他的显示代码也不写了,网上很多。

5.main.c文件

#include "stc15.h"
#include "delay.h"
#include "oled.h"
#include "bmp.h"
int main(void)
{  OLED_Init();//初始化OLED  OLED_Clear() ;   while(1)  {     OLED_ShowCHinese(0,0,0);//小OLED_ShowCHinese(18,0,1);//猿OLED_ShowCHinese(36,0,2);//猪 OLED_ShowCHinese(54,0,3);//哥  }
}

四、显示效果

14.STC15W408AS单片机IIC驱动OLED相关推荐

  1. STC15W408AS单片机IIC驱动0.96寸OLED显示

    STC15W408AS单片机IIC驱动0.96寸OLED显示 不同页的滚动效果() 全页的滚动效果 STC15W408AS最新系统板 注意图片上的0欧姆电阻贴错了位置,应该是与GND相连的,图片上是P ...

  2. 51单片机IIC 12864 OLED屏幕滚动显示仿真

    51单片机IIC 12864 OLED屏幕滚动显示仿真 程序代码接着前面文章<STC15W408AS单片机IIC驱动0.96寸OLED显示> 这里不再贴出代码了,前面有一篇有实物效果演示, ...

  3. IIC 驱动OLED

    IIC总线可以驱动很多器件,比较常见的有OLED.EEPROM存储器(AT24C02).温度传感器(LM75A).温湿度传感器(DHT11)等.有关IIC总线协议的基本原理可以看我之前的文章介绍.这一 ...

  4. 15. STM32——软件IIC驱动OLED屏幕显示字符、字符串、数字、汉字

    STM32--软件IIC驱动OLED屏幕显示 OLED屏幕 写命令 写内容 对OLED写入一个字节 设置光标 启动OLED 关闭OLED 全屏填充(清屏) 显示字符 显示字符串 获取次方 显示数字 显 ...

  5. 12. STM32——硬件IIC驱动OLED屏幕显示

    STM32--硬件IIC驱动OLED屏幕显示 OLED屏幕 OLED屏幕特点 OLED屏幕接线说明 OLED屏幕显存 OLED屏幕原理 OLED屏幕常用指令 OLED屏幕字模软件的使用 写命令 写数据 ...

  6. RA4M2开发(2)----基于IIC驱动OLED

    概述 在e2studio中创建新的工程并导入必要的文件,包括I2C驱动代码和SSD1306 OLED显示驱动代码. 配置RA4M2的I2C接口,使其作为I2C master进行通信. 初始化SSD13 ...

  7. ESP8266(NodeMCU)+Lua语言+IIC驱动OLED屏幕

    前言 本来打算用Arduino IDE驱动OLED屏幕,但是因为在家无法安装Arduino的第三方库,改用ESPlorer和Lua语言驱动. 硬件准备 1. NodeMCU开发板 2. OLED屏幕( ...

  8. esp32 Arduino(九)u8g2图形库 IIC驱动OLED

    一.简介: LED驱动芯片:SSD1306 开发平台: vscode+platformIO 开发板:ESP32 Divkit v1 目前Arduino平台上使用最广泛的OLED库: U8G2 gith ...

  9. STM32模拟IIC驱动OLED屏 原理+源码

    处理器和芯片间的通信可以形象的比喻成两个人讲话:1.你说的别人得能听懂:双方约定信号的协议.2.你的语速别人得能接受:双方满足时序要求. 一.IIC总线的信号类型 1.开始信号:处理器让SCL时钟保持 ...

  10. 15.STC15W408AS单片机驱动BH1750FVI光强度传感器

    https://mp.weixin.qq.com/s/id9sVd_uRSxIEgwgwlw31A 在上一篇中,我们介绍了IIC驱动OLED显示屏.这一篇是IIC驱动BH1750FVI光强度传感器.其 ...

最新文章

  1. 农科院张西美组助研招聘(事业编、解决北京户口)
  2. 未来,AI可用于5G网络分析
  3. KB244036_PXE 客户端、DHCP 和 RIS 服务器之间的 PXE 交互过程说明
  4. 微信基础服务肯定不收费
  5. Spring 三种注入方式
  6. 7 种分布式全局 ID 生成策略,你更爱哪种?
  7. C++ opengl 复合运动
  8. 彩虹DS6.6免授权版源码+后台同步更新+独家防黑策略
  9. java valueof null,String.valueOf(null) 遇到的坑
  10. 前端学习之touch.js与swiper学习
  11. NLP的12种后BERT预训练方法
  12. listView多布局
  13. spring boot redis分布式锁
  14. C++执行shell命令
  15. 手把手搭建VuePress文档
  16. Mac系统升级后开发者证书不被信任,报错/usr/bin/codesign --force --sign
  17. SQL Sever奇葩问题踩坑记
  18. 转发 微博 Qzone 微信 iPhone 11曝光,卢伟冰怒批的5伏1安亮了,网友:价格才是重点
  19. 如何修改wamp5的端口号,默认页。
  20. [2018.11.05 T1] 喝牛奶

热门文章

  1. 科学计算机的删除键在哪里,电脑删除键是哪个?
  2. Python基础之文件操作
  3. CVPR引起巨大争议的新技术Face2Face:当科技先进到让人害怕
  4. 预充电电路工作原理_课堂 | 为什么锂电池在充电过程中首先要进行预充电
  5. 自己的旧手机做html服务器,旧手机改座机_怎么将手机改成为座机
  6. 什么是3d建模,3D建模师可以从事哪些职业?
  7. 开源开放 | OMAHA 联合 OpenKG 发布新冠诊疗图谱数据
  8. spss变量视图转数据视图_教大家SPSS如何导入数据进行分析
  9. PHP 将百度地图上的一条线的点位进行平滑处理,画出一条曲线
  10. 小米手机无限重启怎么办?