1. 定义方法
a.定义起始信号
b.定义终止信号
c.定义单片机写入函数
d.定义单片机读出函数
e.写入到指定元器件
f.从指定元器件读出
g.写一个头文件作为中转
h.写一个主函数实现对写入读出的调用
2. 定义起始信号
a.SDA 高电平延时
b.SCL高电平延时
c.SDA低电平延时
d.SCL低电平延时
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
SDA = 1; Delay10us(); SCL = 1; Delay10us(); SDA = 0; Delay10us(); SCL = 0; Delay10us();
3. 终止信号
a.SDA低电平延时
b.SCL高电平延时
c.SDA高电平延时
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
SDA = 0; Delay10us(); SCL = 1; Delay10us(); SDA = 1; Delay10us();
4. 单片机写入函数
a.定义函数需要返回值,需要一个8位形式参数
b.for循环8次,每次发送一个数据,通过数据左移右移实现,每次写入SDA后要把SCL电平拉低
c.循环完成后拉高SDA延时后拉高SCL让SDA保持不变
d.while(SDA)循环等待元器件应答,应答后SDA会被拉低跳出循环
e.返回值
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
unsigned char sendaddr(unsigned char dat) { unsigned char a=0,b=0; for(a=0;a<8;a++) { SDA=dat>>7; dat<<=1; Delay10us(); SCL = 1; Delay10us(); SCL = 0; Delay10us(); } SDA = 1; Delay10us(); SCL = 1; while(SDA) { b++; if(b>200) { SCL = 0; Delay10us(); return 0; } } SCL = 0; Delay10us(); return 1; }
5. 单片机读出函数
a.定义函数需要返回值不需要形式参数
b.定义变量作为容器接收数据
c.for循环8次,先拉高电平保持SDA稳定,num<<=1,num|=SDA 拉低电平
e.返回num
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
unsigned char reader() { unsigned char a,num; num = 0; //SDA = 1; Delay10us(); for(a=0;a<8;a++) { SCL = 1; Delay10us(); num<<=1; num|=SDA; Delay10us(); SCL=0; Delay10us(); } return num; }
6. 写入元器件函数
a.定义函数不需要返回值,需要两个形式参数
b.起始信号>>写入函数(元器件地址0)>>写入函数(元器件首地址)>>写入函数(写入值)>>终止信号
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
void A204write(unsigned char addr,unsigned char dat) { start(); sendaddr(0xa0); sendaddr(addr); sendaddr(dat); stop(); }
7. 从元器件读出函数
a.定义带返回值的函数不需要形式参数
b.起始信号>>写入函数(元器件地址0)>>写入函数(元器件首地址)>>起始信号>>写入函数(元器件地址1)>>接收SDA的值>>终止信号
c.返回值
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
unsigned char A204read(unsigned char addr) { unsigned char num; start(); sendaddr(0xa0); sendaddr(addr); start(); sendaddr(0xa1); num = reader(); stop(); return num; }
8.总代码
a.主函数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<reg52.h> #include"i2c.h" /* 1.延时函数 2.定义每个按键的作用 3.根据num选择数码管的值赋值给P0 */ typedef unsigned char u8; typedef unsigned int u16; sbit LA=P2^2; sbit LB=P2^3; sbit LC=P2^4; sbit K1=P3^1; sbit K2=P3^0; sbit K3=P3^2; sbit K4=P3^3; u8 num=0; u8 disp[4]; u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //延时函数 void lay10us(i) { while(i--); } //独立按键函数 void Keypros() { if(K1==0) { lay10us(10); if(K1==0) { A204write(1,num); } while(!K1); } if(K2==0) { lay10us(10); if(K2==0) { num = A204read(1); } while(!K2); } if(K3==0) { lay10us(10); if(K3==0) { num++; } while(!K3); } if(K4==0) { lay10us(10); if(K4==0) { num=0; } } while(!K4); } //num按键次数转换为数码管段函数 void dat() { disp[0]=smgduan[num%1000%100%10]; disp[1]=smgduan[num%1000%100/10]; disp[2]=smgduan[num%1000/100]; disp[3]=smgduan[num/1000]; } //点亮数码管函数 void dispaly() { u8 a; for(a=0;a<4;a++) { switch(a) { case(0): LA=0;LB=0;LC=0; break; //数码管第0个 case(1): LA=1;LB=0;LC=0; break; case(2): LA=0;LB=1;LC=0; break; case(3): LA=1;LB=1;LC=0; //数码管第4个 } P0=disp[a]; lay10us(100); P0=0x00; //数码管消隐 } } void main() { while(1) { Keypros(); dat(); dispaly(); } }
b.子函数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<reg52.h> #include"i2c.h" unsigned char u8; /* 1.起始函数 2.终止函数 3.写入函数 4.接收函数 5.芯片发送函数 6.芯片接收函数 */ /* 延时函数,延时6us */ void Delay10us() { unsigned char a,b; for(b=1;b>0;b--) for(a=2;a>0;a--); } /* 这是起始信号函数 */ void start() { SDA = 1; Delay10us(); SCL = 1; Delay10us(); SDA = 0; Delay10us(); SCL = 0; Delay10us(); } /*void start() { SDA=1; Delay10us(); SCL=1; Delay10us();//建立时间是SDA保持时间>4.7us SDA=0; Delay10us();//保持时间是>4us SCL=0; Delay10us(); } */ /* 这是终止信号函数 */ void stop() { SDA = 0; Delay10us(); SCL = 1; Delay10us(); SDA = 1; Delay10us(); } /* 写入函数,将主机内容发送到芯片中 */ unsigned char sendaddr(unsigned char dat) { unsigned char a=0,b=0; for(a=0;a<8;a++) { SDA=dat>>7; dat<<=1; Delay10us(); SCL = 1; Delay10us(); SCL = 0; Delay10us(); } SDA = 1; Delay10us(); SCL = 1; while(SDA) { b++; if(b>200) { SCL = 0; Delay10us(); return 0; } } SCL = 0; Delay10us(); return 1; } /* 读出函数,将芯片的数据读出到主机中 */ unsigned char reader() { unsigned char a,num; num = 0; //SDA = 1; Delay10us(); for(a=0;a<8;a++) { SCL = 1; Delay10us(); num<<=1; num|=SDA; Delay10us(); SCL=0; Delay10us(); } return num; } /* 写入芯片 1.起始函数 2.写入函数发送地址 3.写入函数发送器件内部地址 4.写入函数发送数据 5.终止函数 */ void A204write(unsigned char addr,unsigned char dat) { start(); sendaddr(0xa0); sendaddr(addr); sendaddr(dat); stop(); } unsigned char A204read(unsigned char addr) { unsigned char num; start(); sendaddr(0xa0); sendaddr(addr); start(); sendaddr(0xa1); num = reader(); stop(); return num; }
c.头文件
#ifndef _I2C_H #define _I2C_H #include<reg52.h> sbit SCL = P2^1; sbit SDA = P2^0; void delay6us(void); void start(); void stop(); unsigned char sendaddr(unsigned char dat); unsigned char reader(); void A204write(unsigned char addr,unsigned char dat); unsigned char A204read(unsigned char addr); #endif