总述:
IIC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号
1.起始信号

- void IIC_Start()
- {
- sda = 1;
- scl = 1;
- _nop_();
- sda = 0;
- _nop_();
- }
2.终止信号

- void IIC_Stop()
- {
- sda = 0;
- scl = 1;
- _nop_();
- sda = 1;
- _nop_();
- }
3.应答信号
- char IIC_ACK()
- {
- char flag;//????为什么这个位置要用char
- sda = 1;//就在时钟脉冲9期间释放数据线
- _nop_();
- scl = 1;
- _nop_();
- flag = sda;
- _nop_();
- scl = 0;
- _nop_();
- return flag;
-
- }
3.IIC协议发送一个字节封装。

- void IIC_Send_Byte(char dataSend)
- {
- int i;
- for(i = 0;i<8;i++){
- scl = 0;//scl拉低,让sda做好数据准备
- sda = dataSend & 0x80;//1000 0000获得dataSend的最高位,给sda ??为什么字符串可以进行&运算
- _nop_();//发送数据建立时间
- scl = 1;//scl拉高开始发送
- _nop_();//数据发送时间
- scl = 0;//发送完毕拉低
- _nop_();//
- dataSend = dataSend << 1;//????搞不懂为什么dataSend << 1就是左移
- }
- }
2.OLED写命令,可以参考ssd1306手册和叁议电子oled说明书。

3.OLED寻址模式:页地址模式、水平地址模式、垂直地址模式。;页地址模式和水平地址模式用的比较多。
页地址模式:

写入入0x08(b00001000),显示如下


首先进行OLED初始化,初始化的代码是怎么来的呢?
- void Oled_Init(void){
- Oled_Write_Cmd(0xAE);//--display off
- Oled_Write_Cmd(0x00);//---set low column address
- Oled_Write_Cmd(0x10);//---set high column address
- Oled_Write_Cmd(0x40);//--set start line address
- Oled_Write_Cmd(0xB0);//--set page address
- Oled_Write_Cmd(0x81); // contract control
- Oled_Write_Cmd(0xFF);//--128
- Oled_Write_Cmd(0xA1);//set segment remap
- Oled_Write_Cmd(0xA6);//--normal / reverse
- Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
- Oled_Write_Cmd(0x3F);//--1/32 duty
- Oled_Write_Cmd(0xC8);//Com scan direction
- Oled_Write_Cmd(0xD3);//-set display offset
- Oled_Write_Cmd(0x00);//
- Oled_Write_Cmd(0xD5);//set osc division
- Oled_Write_Cmd(0x80);//
- Oled_Write_Cmd(0xD8);//set area color mode off
- Oled_Write_Cmd(0x05);//
- Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
- Oled_Write_Cmd(0xF1);//
- Oled_Write_Cmd(0xDA);//set com pin configuartion
- Oled_Write_Cmd(0x12);//
- Oled_Write_Cmd(0xDB);//set Vcomh
- Oled_Write_Cmd(0x30);//
- Oled_Write_Cmd(0x8D);//set charge pump enable
- Oled_Write_Cmd(0x14);//
- Oled_Write_Cmd(0xAF);//--turn on oled panel
- }
- void Oled_Write_Cmd(char dataCmd)
- {
- // 1. start()
- IIC_Start();
- // 2. 写入从机地址 b0111 1000 0x78
- IIC_Send_Byte(0x78); //???这个0x78是怎么得出来的
- // 3. ACK
- IIC_ACK();
- // 4. cotrol byte: (0)(0)000000 写入命令 (0)(1)000000写入数据
- IIC_Send_Byte(0x00);
- // 5. ACK
- IIC_ACK();
- //6. 写入指令/数据
- IIC_Send_Byte(dataCmd);
- //7. ACK
- IIC_ACK();
- //8. STOP
- IIC_Stop();
- }
清屏函数
- void Oled_Clear()
- {
- unsigned char i,j; //-128 --- 127
- for(i=0;i<8;i++){
- Oled_Write_Cmd(0xB0 + i);//page0--page7 ??为什么是0xB0,为什么要叫i
- //每个page从0列
- Oled_Write_Cmd(0x00);
- Oled_Write_Cmd(0x10);
- //0到127列,依次写入0,每写入数据,列地址自动偏移
- for(j = 0;j<128;j++){
- Oled_Write_Data(0);
- }
- }
- }
4.利用OLED来显示文字。
-
-
- void main()
- {
- unsigned char i;
- //1. OLED初始化
- Oled_Init();
- //2. 选择一个位置
- //2.1 确认页寻址模式
- Oled_Write_Cmd(0x20);
- Oled_Write_Cmd(0x02);
- Oled_Clear();
- //2.2 选择PAGE0 1011 0000
- // 0xB0
- 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(j1[i]);
- }
- for(i=0;i<16;i++){
-
- Oled_Write_Data(s1[i]);
- }
- for(i=0;i<16;i++){
-
- Oled_Write_Data(g1[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(j2[i]);
- }
- for(i=0;i<16;i++){
-
- Oled_Write_Data(s2[i]);
- }
- for(i=0;i<16;i++){
-
- Oled_Write_Data(g2[i]);
- }
- while(1);
- }
5.利用OLED来传入图片信息
- void Oled_Show_Image(unsigned char *image)
- {
- unsigned char i; //-128 --- 127
- unsigned int j;
- for(i=0;i<8;i++){
- Oled_Write_Cmd(0xB0 + i);//page0--page7
- //每个page从0列
- Oled_Write_Cmd(0x00);
- Oled_Write_Cmd(0x10);
- //0到127列,依次写入0,每写入数据,列地址自动偏移
- for(j = 128*i;j<(128 *(i+1));j++){
- Oled_Write_Data(image[j]);
- }
- }
- }