⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex8_1.c

📁 单片机应用技术(C语言版)程序源代码.rar
💻 C
字号:
//程序:ex8_1.c
//功能:EEPROM读写程序,从AT24C01的4个连续存储单元中读出4个字节的数据,然后将4
//	个新的数值写入AT24C01的对应4个存储单元中,再重新读出。
#include <reg51.h>
#include <intrins.h>     			//_nop_()函数所在的头文件
/******************************位定义及预定义*******************************/
#define AddWr 0xa0 				//器件地址选择及写数据地址0xa0
#define AddRd 0xa1 				//器件地址选择及读数据地址0xa1
sbit SDA= P3^4; 				//串行数据输入/输出位定义
sbit SCL= P3^3; 				//串行时钟位定义
bit  ack_bit;					//应答标志
/******************************函数声明************************************/
void mDelay(unsigned char ms);			//延时函数声明
void Start(void);				//开始函数
void Stop(void);				//停止函数
void Ack(void);					//应答函数
void NoAck(void);				//反向应答函数
void Shout(unsigned char Data);			//串行输出数据函数
unsigned char Shin(void);			//串行输入数据函数
void WrByte(unsigned char Data[],unsigned char Address,unsigned char Num);	//写字节函数
void RdRadom(unsigned char Data[],unsigned char Address,unsigned char Num);	//随机地址读函数
/******************************主函数************************************/
void main()
{
   unsigned char R1data[4]= {0,0,0,0};		//初始化读数据数组1为全0
   unsigned char R2data[4]= {0,0,0,0};		//初始化读数据数组2为全0
   unsigned char Wdata[4]={1,2,3,4};		//初始化写数据数组
   RdRadom(R1data,4,4); 			//读AT24C01中的4个字节数据到读数据数组1
   WrByte(Wdata,4,4);				//将初始化后的数值写入AT24C01
   mDelay(20);
   RdRadom(R2data,4,4);				//重新读出写入的数据到读数据数组2 
}
/******************************写字节************************************/
//函数名:WrByte
//函数功能:向AT24C**器件的指定地址按字节连续写入数据
//形式参数:待写入的数据Data[],起始地址Address,待写入的字节数Num
//返回值:返回为0表示操作成功,否则操作有误
void WrByte(unsigned char Data[],unsigned char Address,unsigned char Num)
{
   unsigned char i;
   unsigned char *PData;
   PData=Data;
   for(i=0;i<Num;i++)				//连续写入Num个字节数据
   {
      Start(); 					//发送启动信号
      Shout(AddWr); 				//发送写操作器件地址AddWr,0xa0 
      Ack();					//接收ACK应答
      Shout(Address+i); 			//发送地址
      Ack();					//接收ACK应答
      Shout(*(PData+i));			//发送待写入的数据
      Ack();					//接收ACK应答
      Stop();					//发送停止信号
      mDelay(20);				//等待内定时写入周期结束
   }
}
/*****************************随机地址读***********************************/
//函数名:RdRadom
//函数功能:从AT24C**器件的指定地址按字节读入数据
//形式参数:起始地址Address,待读入的字节数Num
//返回值:读出的字节放入data[],如果操作成功返回为0,否则操作有误
void RdRadom(unsigned char Data[],unsigned char Address,unsigned char Num)
{
   unsigned char i;
   unsigned char *PData;
   PData=Data;
   for(i=0;i<Num;i++)
   {
      Start();					//开始
      Shout(AddWr); 				//发送写操作器件地址AddWr
      Ack();
      shout(Address+i);				//发送字节地址
      Ack();
      Start();					//开始
      shout(AddRd);				//发送读操作器件地址AddRd
      Ack();
      *(PData+i)=shin();			//调用读数据函数
      SCL=0;
      NoAck();					//反向应答
      Stop();					//停止
   }
}
/*****************************开始函数***********************************/
//函数名: Start
//函数功能:发送START状态,定义为当SCL为高时SDA从高到低
//形式参数:无
//返回值:返回时SCL,SDA为低
void Start(void)
{
   SDA=1;					//升高SDA
   SCL=1;					//升高SCL
   _nop_();_nop_();_nop_();_nop_();		//保持数据建立延迟及周期延迟
   SDA=0;					//降低SDA
   _nop_();_nop_();_nop_();_nop_();		//保持SDA为低,保持时间hold delay
   SCL=0;					//降低SCL
}
/********************************停止函数*********************************/
//函数名:Stop
//函数功能:发送STOP状态,定义为当SCL为高时SDA从低变高
//形式参数:无
//返回值:返回时SCL,SDA为高
void Stop(void)
{
   SDA=0;
   _nop_();_nop_();				//保持SCL为低及数据稳定
   SCL=1;
   _nop_();_nop_();_nop_();_nop_();		//保持建立延迟
   SDA=1;
   _nop_();_nop_();_nop_();_nop_();
}

/*******************************串行输出数据*****************************/
//函数名:Shout
//函数功能:串行发送一个字节(包括地址和数据)给AT24C**器件,高位在前
//形式参数:待发送的字节Data,调用前SCL,SDA为低,返回时SCL为低。
//返回值:无
void Shout(unsigned char Data)
{
   unsigned char BitCounter=8;			//设置位计数器
   unsigned char temp;				//中间变量控制
   do
   {
      temp=Data;
      SCL=0;					//时钟为低电平
      _nop_();_nop_();_nop_();_nop_();		//保持SCL为低
      if((temp&0x80)==0x80) SDA=1;		//输出一位,如果最高位是1,则输出1到SDA
         else	SDA=0;				//如果最高位是0,则输出0到SDA
      SCL=1;					//时钟为高电平
      temp=Data<<1;				//左移一位(高位在前)
      Data=temp;
      BitCounter--;
   } while(BitCounter);				//传送下一位
   SCL=0;
}
/*******************************串行输入数据******************************/
//函数名:Shin
//函数功能:从AT24C**串行读入一个字节数据,高位在前
//形式参数:调用前SCL为低
//返回值:返回读入的字节,返回时SCL为低
unsigned char Shin(void) 
{
   unsigned char temp=0;
   unsigned char temp1=0;
   unsigned char BitCounter=8;			//设置位计数器
   SDA=1;					//使SDA为高,准备读
   do {
         SCL=0;					//降低时钟
         _nop_();_nop_();_nop_();_nop_();	//保持SCL为低且使数据稳定
         SCL=1;					//升高时钟
         _nop_();_nop_();_nop_();_nop_();	//保持SCL为高
         if(SDA) temp=temp|0x01;		//输入一位,如果SDA=1则temp的最低位置1
             else  temp=temp&0xfe;		//否则temp的最低位清0
         if(BitCounter-1)
         {
            temp1=temp<<1;			//左移一位(高位在前)
            temp=temp1;
         }
         BitCounter--;
      } while(BitCounter);			//传送下一位
   return(temp);					//返回读入的数据
}
//********************************应答**************************************/
//函数名:Ack
//函数功能:检测来自AT24C**器件的ACK应答
//形式参数:无
//返回值:返回ack_bit,为0表示操作成功,否则操作有误
bit Ack(void)
{
   bit   ack_bit;
   SDA=1;					//置SDA为高,准备接收ACK应答
   _nop_();_nop_();_nop_();_nop_();
   SCL=1;					//第9个时钟脉冲
   _nop_();_nop_();_nop_();_nop_();
   ack_bit = SDA;				//读入应答
   SCL=0;
   return(ack_bit);				//返回应答标志ack_bit
}
/*******************************反向应答*************************************/
//函数名:NoAck
//函数功能:向AT24C**器件发送NAK反向应答,随时钟输出一个高电平的负应答位,调用前
//          SCL为低,返回时SCL为低,SDA为高
//形式参数: 无
//返回值: 无
void NoAck(void)
{
   SDA=1;
   _nop_();_nop_();_nop_();_nop_();
   SCL=1;
   _nop_();_nop_();_nop_();_nop_();
   SCL=0;
}
/**********************************延时************************************/
//函数名:mDelay
//函数功能:延时函数
//函数形式参数:ms用来控制循环次数,从而控制延时时间长短
//函数返回值: 无
void mDelay(unsigned char ms)
{ 
   unsigned int i;
   while(ms--)
   {
      for(i=0;i<125;i++);
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -