51单片机学习30-AT24C02
这篇讲AT24C02
实现的功能是 每次关机在开机 数码管显示的数字加1 从0到9 这样循环。实现了AT24C02存储功能。
仿真图用的是我自己做的一个51单片机开发板 图纸比较大,截图可能看不清,需要的话可以私信联系我。
/*单片机模拟I2C总线通信时,需要以下几个关键部分的程序
1.总线初始化
2.启动信号
3.应答信号
4.停止信号
5.写一个字节
6.读一个字节
7.封装一个写程序
8.封装一个读程序*/
程序:
源代码:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL=P2^0;
sbit SDA=P2^1;
uchar code smg_dm[]={ //数码管显示编码
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
//////延时函数声明//////////
void delay_50us(uint);
void delay_10us();
/////i2c操作相关函数声明///////////
void i2c_init();
void i2c_start();
void i2c_respond();
void i2c_no_respond();
void i2c_stop();
void i2c_write_Byte(uchar dat);
uchar i2c_read_Byte();
void write_Byte(uchar add,uchar dat);
uchar read_Byte(uchar add);
//////////////////////////////////
void main()
{
uchar k;
k=read_Byte(3);
k=k%10;
P1=smg_dm[k];
k++;
write_Byte(3,k); //关机开机后数码管自加一
while(1);
}
void delay_50us(uint z) //延时子程序
{
uchar y;
for(;z>0;z--)
for(y=19;y>0;y--);
}
void delay_10us() //NOP执行一句1us 调用延时函数2us,结束调用2us一共10us
{
_nop_();_nop_(); _nop_();
_nop_(); _nop_(); _nop_();
}
void i2c_init()//总线初始化
{
SCL=1;
delay_10us();
SDA=1;
delay_10us();
}
void i2c_start()//启动信号
{
SCL=1;
delay_10us();
SDA=1;
delay_10us();
SDA=0;
delay_10us();
}
void i2c_respond()//应答信号
{
uchar i;
SCL=1;
delay_10us();
//while((SDA==1)&&(i<255));
while((SDA==1)&&(i<255))i++;//实际程序不能一直等着 当SDA变低电平或者i++超过255时
//表示没有收到从机的应答信号,而主机默认已经收到数据而不再等待
SCL=0;
delay_10us();
}
void i2c_no_respond()//非应答信号
{
SDA=1;
delay_10us();
SCL=1;
delay_10us();
SCL=0;
delay_10us();
}
void i2c_stop()//停止信号
{
SDA=0;
delay_10us();
SCL=1;
delay_10us();
//SDA=0; //原先这两句在这里程序不会执行加一,与停止信号的时序不符
//delay_10us();
SDA=1;
delay_10us();
}
void i2c_write_Byte(uchar dat)//写一个字节
{
uchar i;
SCL=0;//在时钟信号低电平期间,数据线上高地电平状态才允许变化
for(i=0;i<8;i++)
{
if(dat&0x80)//判断高位是0还是1 &单一位与运算 &&按位与 dat&&0x80 相当于dat&10000000
//传送数据高位在前 判断dat&0x80相当于dat&1 真执行if后面的语句 否则执行else后面语句
{SDA=1;} ////////////////////////////////
else ////////////////////////////////
{SDA=0;} ////////////////////////////////
dat=dat<<1;//高位在前,往左移
delay_10us();
SCL=1; //芯片会来读数据
delay_10us();
SCL=0;
delay_10us();
}
SDA=1;//释放数据线
delay_10us();
}
uchar i2c_read_Byte()//读一个字节
{
uchar i;
uchar dat;
SCL=0;//在时钟信号低电平期间,数据线上高地电平状态才允许变化
delay_10us();
SDA=1;//释放数据线
delay_10us();
for(i=0;i<8;i++)
{
SCL=1;//准备读数据
delay_10us();
dat=dat<<1;//判断8次移位7次
if(SDA)//判断SDA的电平
{ dat++; } //个位加1
SCL=0;//时钟线拉低
delay_10us();
}
return dat;
}
仿真结果:
仿真停止后,再次运行仿真
数据加1 实现了要求的功能
单片机 基于AT24C02的多机通信 写入程序
#include <reg51.h> // 包含51单片机寄存器定义的头文件
#include <intrins.h> //包含_nop_()函数定义的头文件
#defineOP_READ0xa1// 器件1地址以及读取操作,0xa1即为1010 0001B
#defineOP_WRITE 0xa0// 器件1地址以及写入操作,0xa1即为1010 0000B
sbit SDA=P3^4; //将串行数据总线SDA位定义在为P3.4引脚
sbit SCL=P3^3; //将串行时钟总线SDA位定义在为P3.3引脚
sbit flag=P3^0;
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/***************************************************
函数功能:开始数据传送
***************************************************/
void start()
// 开始位
{
SDA = 1; //SDA初始化为高电平“1”
SCL = 1; //开始数据传送时,要求SCL为高电平“1”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA = 0; //SDA的下降沿被认为是开始信号
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
_nop_(); //等待一个机器周期
}
/***************************************************
函数功能:结束数据传送
***************************************************/
void stop()
// 停止位
{
SDA = 0; //SDA初始化为低电平“0”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 1; //结束数据传送时,要求SCL为高电平“1”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA = 1; //SDA的上升沿被认为是结束信号
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
}
/***************************************************
函数功能:向AT24Cxx的当前地址写入数据
入口参数:y (储存待写入的数据)
***************************************************/
//在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0
bit WriteCurrent(unsigned char y)
{
unsigned char i;
bit ack_bit; //储存应答位
for(i = 0; i < 8; i++)// 循环移入8个位
{
SDA = (bit)(y&0x80); //通过按位“与”运算将最高位数据送到S
//因为传送时高位在前,低位在后
_nop_(); //等待一个机器周期
SCL = 1; //在SCL的上升沿将数据写入AT24Cxx
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 0; //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
y <<= 1; //将y中的各二进位向左移一位
}
SDA = 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
//以让SDA线转由接收设备(AT24Cxx)控制
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 1; //根据上述规定,SCL应为高电平
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
//若送高电平,表示没有接收到,传送异常
SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
return ack_bit;// 返回AT24Cxx应答位
}
/***************************************************
函数功能:向AT24Cxx中的指定地址写入数据
入口参数:add (储存指定的地址);dat(储存待写入的数据)
***************************************************/
void WriteSet(unsigned char add, unsigned char dat)
// 在指定地址addr处写入数据WriteCurrent
{
start(); //开始数据传递
WriteCurrent(OP_WRITE); //选择要操作的第一个AT24Cxx芯片,并告知要对其写入数据
WriteCurrent(add); //写入指定地址
WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据
stop(); //停止数据传递
delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上
}
/***************************************************
函数功能:主函数
***************************************************/
main(void)
{
TMOD=0x01;
TH0=(65536-46083)/256;
TL0=(65536-46083)%256;
EA=1;
ET0=1;
TR0=1;
flag=1;
while(1)
{
while(flag==1)
{
WriteSet(0x36,0xf0); //将数据"0xf0"写入第一个AT24C02的指定地址"0x36"
delaynms(50); //延时50ms
}
while(flag==0)
;
}
}
/***************************************************
函数功能:定时器T0的中断函数,使P3.0引脚输出100ms方波
***************************************************/
void Time0(void) interrupt 1 using 1
{
TH0=(65536-46083)/256;
TL0=(65536-46083)%256;
flag=!flag;
}
相关问答
24C02 是什么集成块-ZOL问答24C02是一款常见的EEPROM芯片,使用I²C接口,容量为256Byte。AT24c02的SDA,SCL分别上拉5.1k电阻与单片机IO口连接EESDAEESCL接单片机的引脚。EEVC...
24c02 n芯片引脚定义?24C02与单片机的接口非常简单E0,E1,E2为器件地址线,WP为写保护引脚,SCL,SDA为二线串行接口,符合I2C总线协议。在一般单片机系统中,24C02数据受到干扰的...
请问 24C02 是什么芯片-ZOL问答贴片24c02有问题《,线路有问题,或程序本来就还没调试好24C01,24C04,24C08,除了容量不同,其他的一样,可以上网找一下驱动程序。EESDAEESCL接单片机的引脚。...
AT 89 C 51 单片机 主要功能有哪些啊?AT89C51是一种带4K字节闪存可编程可擦除只读存储器(FPEROM—FlashProgrammableandErasableReadOnlyMemory)的低电压、高性能CMOS8位...
存储器EEPROM通俗叫法是什么?-ZOL问答现在的单片机,ROM一般就是指的FlashROM,从来保存程序的,即程序存储器。EEPROM专指“可以进行字节擦除和编程”的存储器,比如28C64、24C02这样的存储器。还有...
89 c 51真的过时了吗?89C51单片机是一款8位单片机,最常用的是艾特梅尔产的AT89C51,我在上学时是用的最多的一款单片机芯片,现在来说它早已停产多年了。我认为尽管这样,作为一种性...8...
rom ram eeprom分别肿么读-ZOL问答现在的单片机,ROM一般就是指的FlashROM,从来保存程序的,即程序存储器。EEPROM专指“可以进行字节擦除和编程”的存储器,比如28C64、24C02这样的存储器。还有...
单片机 仿真软件中如何设置数码管与 24C 04?这个题目看着东西多,实际上没有太大的难度。需要知道单片机如何控制数码管显示即可,其他题目中更多的是一些业务逻辑,你需要设置一个交互逻辑即可,比如通过按...
单片机 如何通过ADC模块采集模拟信号?朋友们好,我是电子及工控技术,我来回答这个问题。众所周知单片机是一种超大规模的集成电路,它只能“读懂”并处理数字信号,对于连续量的模拟信号则无能为力。...
51 单片机 开发板有什么用,对初学 单片机 有什么帮助?51单片机开发板对初学单片机的帮助,就像学步车对于刚学走路的儿童一样,可以帮助它少摔跤,快速学会走路。一、单片机学习板的重要性单片机的学习,包含两大方...