概述
由于 51 单片机没有硬件 IIC 接口,即使有硬件接口我们通常还是采用软件模拟 I2C。主要原因是硬件 IIC 设计的比较复杂,而且稳定性不怎么好,程序移植比较麻烦,用软件模拟 IIC,最大的好处就是移植方便,同一个代码兼容所有单片机,任何一个单片机只要有 IO 口(不需要特定 IO),都可以很快的移植过去。
一、数据位的有效性规定
IIC总线进行数据传送时,SCL信号为高电平期间,SDA上的数据必须保持稳定;只有在SCL上的信号为低电平期间,SDA上的高电平或低电平状态才允许变化。
注:IIC只有两根双向信号线,一个是数据线SDA,一个是时钟线SCL。
二、总线寻址方式
IIC 总线寻址按照从机地址位数可分为两种,一种是 7 位,另一种是 10位。本单片机中采用 7 位的寻址字节(寻址字节是起始信号后的第一个字节)的位定义如下:
D7~D1 位组成从机的地址。D0 位是数据传送方向位,为“ 0”时表示主机
向从机写数据,为“1”时表示主机由从机读数据。
1、编写i2c.h
#include "i2c.h"
void Delay10us()
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
void I2cStart()
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();
SDA=0;
Delay10us();
SCL=0;
Delay10us();
}
void I2cStop()
{
SDA=0;
Delay10us();
SCL=1;
Delay10us();
SDA=1;
Delay10us();
}
unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0;
for(a=0;a<8;a++)
{
SDA=dat>>7;
dat=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 I2cReadByte()
{
unsigned char a=0,dat=0;
SDA=1;
Delay10us();
for(a=0;a<8;a++)
{
SCL=1;
Delay10us();
dat<<=1;
dat|=SDA;
Delay10us();
SCL=0;
Delay10us();
}
return dat;
}
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2cStart();
I2cSendByte(0xa0);
I2cSendByte(addr);
I2cSendByte(dat);
I2cStop();
}
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0);
I2cSendByte(addr);
I2cStart();
I2cSendByte(0xa1);
num=I2cReadByte();
I2cStop();
return num;
}
2、编写i2c.h文件
#ifndef _I2C_H_
#define _I2C_H_
#include <reg52.h>
sbit SCL=P2^1;
sbit SDA=P2^0;
void I2cStart();
void I2cStop();
unsigned char I2cSendByte(unsigned char dat);
unsigned char I2cReadByte();
void At24c02Write(unsigned char addr,unsigned char dat);
unsigned char At24c02Read(unsigned char addr);
#endif
3、编写主程序main.c
#include "reg52.h"
#include "i2c.h"
#include "intrins.h"
typedef unsigned int ui;
typedef unsigned char uc;
//#define led P2 //×¢Ò⣡£¡²»¼Ó";"
//sbit beep=P1^5;
//sbit led=P2^0;
//sbit moto=P1^0;
sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;
sbit LSA=P2^2;//×îµÍλ
sbit LSB=P2^3;//´ÎµÍλ
sbit LSC=P2^4;//¸ßλ
char num=0;
uc disp[4];
uc code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(ui i)
{
while(i--);
}
void Keypros()
{
if(k1==0)
{
delay(1000);
if(k1==0)
{
At24c02Write(1,num);
}
while(!k1);
}
if(k2==0)
{
delay(1000);
if(k2==0)
{
num=At24c02Read(1);
}
while(!k2);
}
if(k3==0)
{
delay(1000);
if(k3==0)
{
num++;
if(num>255)num=0;
}
while(!k3);
}
if(k4==0)
{
delay(1000);
if(k4==0)
{
num=0;
}
while(!k4);
}
}
void Datapros()
{
disp[0]=smgduan[num/1000];//千位
disp[1]=smgduan[num%1000/100];//百位
disp[2]=smgduan[num%100/10];//十位
disp[3]=smgduan[num%10];//个位
}
void DigDisplay()
{
ui i;
for(i=0;i<4;i++)
{
switch(i)
{
case(0):
LSA=1;LSB=1;LSC=1; break;//led-8
case(1):
LSA=0;LSB=1;LSC=1; break;//led-7
case(2):
LSA=1;LSB=0;LSC=1; break;//led-6
case(3):
LSA=0;LSB=0;LSC=1; break;//led-5
}
P0=disp[i];
delay(100);
P0=0x00;
}
}
void main()
{
while(1)
{
Keypros();
Datapros();
DigDisplay();
}
}
最后
以上就是机灵菠萝为你收集整理的51单片机之EEPROM-IIC的全部内容,希望文章能够帮你解决51单片机之EEPROM-IIC所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复