IIC协议概述
IIC全称Inter-Integrated Circuit (集成电路总线)是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双工同步通信方式 特点
由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件
其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。 构成 IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL,其时钟信号是由主控器件产生。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。对于并联在一条总线上的每个IC都有唯一的地址。
IIC协议
IIC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。 //起始位,停止位,数据位,速度 这些信号中,起始信号是必需的,结束信号和应答信号
- 起始信号
- 终止信号
- 应答信号
发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该节; 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
- 数据发送的时序
SCL高电平期间在传输数据,SDA数据不能翻转;SDL低电平期间,SDA数据可以翻转。
sbit scl = P0^1;
sbit sda = P0^3;
void IIC_Start()
{
sda = 1;
scl = 1;
_nop_();
sda = 0;
_nop_();
}
void IIC_Stop()
{
sda = 0;
scl = 1;
_nop_();
sda = 1;
_nop_();
}
char IIC_ACK()
{
char flag;
sda = 1;
_nop_();
scl = 1;
_nop_();
flag = sda;
_nop_();
scl = 0;
_nop_();
return flag;
}
void IIC_Send_Byte(char dataSend)
{
int i;
for(i = 0;i<8;i++){
scl = 0;
sda = dataSend & 0x80;
_nop_();
scl = 1;
_nop_();
scl = 0;
_nop_();
dataSend = dataSend << 1;
}
}
OLED的寻址模式
如何显示一个点? 有三种,分别位页地址模式,水平地址模式和垂直地址模式,可以通过一下表格进行配置内存管理 页地址模式 水平地址模式 垂直地址模式 列地址选择(选择PAGE) 如果写入0x08(b00001000)会显示什么呢 一个字节负责一个Page的一列显示
#include "reg52.h"
#include "intrins.h"
sbit scl = P0^1;
sbit sda = P0^3;
void IIC_Start()
{
scl = 0;
sda = 1;
scl = 1;
_nop_();
sda = 0;
_nop_();
}
void IIC_Stop()
{
scl = 0;
sda = 0;
scl = 1;
_nop_();
sda = 1;
_nop_();
}
char IIC_ACK()
{
char flag;
sda = 1;
_nop_();
scl = 1;
_nop_();
flag = sda;
_nop_();
scl = 0;
_nop_();
return flag;
}
void IIC_Send_Byte(char dataSend)
{
int i;
for(i = 0;i<8;i++){
scl = 0;
sda = dataSend & 0x80;
_nop_();
scl = 1;
_nop_();
scl = 0;
_nop_();
dataSend = dataSend << 1;
}
}
void Oled_Write_Cmd(char dataCmd)
{
IIC_Start();
IIC_Send_Byte(0x78);
IIC_ACK();
IIC_Send_Byte(0x00);
IIC_ACK();
IIC_Send_Byte(dataCmd);
IIC_ACK();
IIC_Stop();
}
void Oled_Write_Data(char dataData)
{
IIC_Start();
IIC_Send_Byte(0x78);
IIC_ACK();
IIC_Send_Byte(0x40);
IIC_ACK();
IIC_Send_Byte(dataData);
IIC_ACK();
IIC_Stop();
}
void Oled_Init(void){
Oled_Write_Cmd(0xAE);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
Oled_Write_Cmd(0x40);
Oled_Write_Cmd(0xB0);
Oled_Write_Cmd(0x81);
Oled_Write_Cmd(0xFF);
Oled_Write_Cmd(0xA1);
Oled_Write_Cmd(0xA6);
Oled_Write_Cmd(0xA8);
Oled_Write_Cmd(0x3F);
Oled_Write_Cmd(0xC8);
Oled_Write_Cmd(0xD3);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0xD5);
Oled_Write_Cmd(0x80);
Oled_Write_Cmd(0xD8);
Oled_Write_Cmd(0x05);
Oled_Write_Cmd(0xD9);
Oled_Write_Cmd(0xF1);
Oled_Write_Cmd(0xDA);
Oled_Write_Cmd(0x12);
Oled_Write_Cmd(0xDB);
Oled_Write_Cmd(0x30);
Oled_Write_Cmd(0x8D);
Oled_Write_Cmd(0x14);
Oled_Write_Cmd(0xAF);
}
void Oled_Clear()
{
unsigned char i,j;
for(i=0;i<8;i++){
Oled_Write_Cmd(0xB0 + i);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
for(j = 0;j<128;j++){
Oled_Write_Data(0);
}
}
}
code l1[]={0x20,0x20,0x24,0x24,0x24,0x24,0xBF,0x64,0x24,0x34,0x28,0x24,0x22,0x20,0x20,0x00};
code l2[]={0x10,0x08,0x04,0x02,0x3F,0x45,0x44,0x44,0x42,0x42,0x42,0x41,0x78,0x00,0x00,0x00};
code p1[]={0x44,0x58,0xC1,0x26,0x10,0xC0,0x3E,0x12,0x32,0x52,0x9F,0x92,0x52,0x32,0x06,0x00};
code p2[]={0x04,0x84,0x85,0x94,0x5D,0x56,0x24,0x25,0x25,0x55,0x4C,0x44,0x85,0x05,0x05,0x00};
code w1[]={0x20,0x24,0x24,0x24,0xFE,0x23,0x22,0x20,0x20,0xFF,0x20,0x22,0x2C,0xA0,0x20,0x00};
code w2[]={0x00,0x08,0x48,0x84,0x7F,0x02,0x41,0x40,0x20,0x13,0x0C,0x14,0x22,0x41,0xF8,0x00};
code a1[]={0x80,0x64,0x2C,0x34,0x24,0x24,0xEC,0x32,0x22,0x22,0x32,0x2E,0x23,0xA2,0x60,0x00};
code a2[]={0x00,0x41,0x21,0x91,0x89,0x87,0x4D,0x55,0x25,0x25,0x55,0x4D,0x81,0x80,0x80,0x00};
code n1[]={0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00};
code n2[]={0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00};
void main()
{
int i;
Oled_Init();
Oled_Write_Cmd(0x20);
Oled_Write_Cmd(0x02);
Oled_Clear();
Oled_Write_Cmd(0xB0);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
for(i=0;i<16;i++){
Oled_Write_Data(l1[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(p1[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(w1[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(a1[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(n1[i]);
}
Oled_Write_Cmd(0xB1);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
for(i=0;i<16;i++){
Oled_Write_Data(l2[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(p2[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(w2[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(a2[i]);
}
for(i=0;i<16;i++){
Oled_Write_Data(n2[i]);
}
while(1);
}
|