I2C EEPROM24C02

1.main.c

#include <reg52.h>
#include "..\lib\delay.h"
#include "..\lib\display.h"
#include "..\lib\i2c.h"

#define AddWr 0xae //写数据地址,需要参考24c02芯片文档
#define AddRd 0xaf //读数据地址

sbit WP = P1^0;

/*------------------------------------------------
写入数据
------------------------------------------------
*/
void WrToRom(unsigned char buffer[], unsigned char address, unsigned char length)
{
unsigned char i;
unsigned char *pData;
pData = buffer;
for(i=0;i<length;i++)
{
Start_I2C(); //启动IIC总线
SendByte(AddWr); //写入芯片地址
Ack(); //应答
SendByte(address + i); //写入存储地址
Ack(); //应答
SendByte(*(pData + i)); //写数据
Ack();
Stop_I2C(); //停止IIC总线
delay_ms(20);
}
}
/*------------------------------------------------
读出数据
------------------------------------------------
*/
void RdFromRom(unsigned char buffer[], unsigned char address, unsigned char length)
{
unsigned char i;
unsigned char *pData;
pData = buffer;
for(i =0;i<length;i++)
{
Start_I2C(); //启动IIC总线
SendByte(AddWr); //写入芯片地址
Ack(); //应答
SendByte(address + i); //写入存储地址
Ack(); //应答

Start_I2C();
SendByte(AddRd); //读入地址
Ack();
*(pData + i) = RecvByte(); //读数据
NoAck();
Stop_I2C(); //停止IIC总线
}
}
/*------------------------------------------------

------------------------------------------------
*/
void main()
{
unsigned char i;
unsigned char number[4] = {1,2,3,4};
WP = 0; //写保护关掉
P2 = 0x00;

WrToRom(number, 4, 4);
delay_ms(200);

number[0] = 0;
number[1] = 0;
number[2] = 0;
number[3] = 0;

RdFromRom(number, 4, 4);

while(1)
{
for(i=0;i<4;i++)
{
Display(0, number[i]);
delay_ms(200);
delay_ms(200);
}
}
}
/*------------------------------------------------
------------------------------------------------
*/

 

2.delay

#ifndef __DELAY_H__
#define __DELAY_H__

void delay_us(unsigned char t);
void delay_ms(unsigned char t);

#endif


#include "delay.h"

/******************************************************************/
/* 延时函数 */
/******************************************************************/
void delay_us(unsigned char t)
{
while(--t);
}
/******************************************************************/
/* 延时函数 */
/******************************************************************/
void delay_ms(unsigned char t)
{
while(t--)
{
//大致延时1ms
delay_us(245);
delay_us(245);
}
}

 

3.display

#ifndef __DISPLAY_H__
#define __DISPLAY_H__

#include <reg52.h>

/******************************************************************/
/* 定义端口 */
/******************************************************************/
sbit LATCH1 = P2^2; //定义锁存使能端口 段锁存
sbit LATCH2 = P2^3; // 位锁存

extern unsigned char TempData[8]; //存储显示值的全局变量
/*
*****************************************************************/
/**/
/******************************************************************/
void Display(unsigned char fbit, unsigned char num);

#endif

#include "display.h"

/******************************************************************/
/* 定义端口 */
/******************************************************************/
#define DataPort P0
#define SegPort P2

unsigned char code dofly_DuanMa[] =
{
0x3f, 0x06, 0x5b, 0x4f,
0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c,
0x39, 0x5e, 0x79, 0x71
};
//unsigned char code dofly_WeiMa[] = {0,1,2,3,4,5,6,7};
/*
*****************************************************************/
/* 显示函数,用于动态扫描数码管 */
/* bit 表示需要显示的第几位 */
/* num 表示需要显示的位数,如需要显示99两位数值则该值输入2 */
/******************************************************************/
void Display(unsigned char fbit, unsigned char num)
{
//static unsigned char i = 0;
DataPort = 0x00; //清空数据,防止有交替重影
SegPort = fbit;
DataPort = dofly_DuanMa[num];
//if(++i == num)
//i = 0;
}

 

4.I2C

#ifndef __I2C_H__
#define __I2C_H__

#include <reg52.h>
#include <intrins.h>

extern bit _ack; //应答标志位

void Start_I2C(void); //启动IIC总线
void Stop_I2C(void); //结束IIC总线

void SendByte(unsigned char c);
unsigned char RecvByte(void);
void Ack(void); //应答IIC总线
void NoAck(void); //非应答IIC总线

#endif


/*-----------------------------------------------------------------
名称:IIC协议
内容:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改
(本例是1us机器周期,即晶振频率要小于12MHZ)
------------------------------------------------------------------
*/
#include "i2c.h"

/******************************************************************/
/* 定义变量 */
/******************************************************************/
bit _ADFlag; //定义AD采样标志位
bit _ack; //应答标志位
/*
*****************************************************************/
/* 定义端口 */
/******************************************************************/
sbit SCL = P1^1;
sbit SDA = P1^2;
/******************************************************************/
/* 启动IIC总线 */
/******************************************************************/
void Start_I2C(void)
{
SDA = 1; //发送起始条件的数据信号
_nop_();_nop_();
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_(); //起始条件建立时间大于4.7us,延时
SDA = 0; //发送起始信号
_nop_();_nop_();_nop_();_nop_();_nop_(); //起始条件锁定时间大于4μ
SCL = 0; //钳住I2C总线,准备发送或接收数据
}
/******************************************************************/
/* 停止IIC总线 */
/******************************************************************/
void Stop_I2C(void)
{
SDA = 0; //发送结束条件的数据信号
_nop_(); //发送结束条件的时钟信号
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_(); //结束条件建立时间大于4μ
SDA = 1; //发送I2C总线结束信号
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 0;
}
/******************************************************************/
/* 应答IIC总线 */
/******************************************************************/
void Ack(void)
{
SDA = 0;
_nop_();_nop_();_nop_();
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 0;
_nop_();_nop_();
}
/******************************************************************/
/* 非应答IIC总线 */
/******************************************************************/
void NoAck(void)
{
SDA = 1;
_nop_();_nop_();_nop_();
SCL = 1;
_nop_();_nop_();_nop_();_nop_();_nop_(); //时钟低电平周期大于4μ
SCL = 0;
_nop_();_nop_();
}
/******************************************************************/
/* 发送一个字节 */
/******************************************************************/
void SendByte(unsigned char b)
{
unsigned char count = 8;
do
{
SCL = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
if((b & 0x80) == 0x80)
SDA = 1;
else
SDA = 0;

SCL = 1;
b = b << 1;
//_nop_();_nop_();_nop_();_nop_();_nop_();
//SCL = 0;
}
while(--count);

// _nop_();_nop_();
// SDA = 1; //8位发送完后释放数据线,准备接收应答位
// _nop_();_nop_();
// SCL = 1;
// _nop_();_nop_();_nop_();
// if(SDA == 1)
// _ack = 0;
// else
// _ack = 1;
// SCL = 0;
// _nop_();_nop_();
SCL = 0;
}
/******************************************************************/
/* 读入一个字节并返回 */
/******************************************************************/
unsigned char RecvByte(void)
{
unsigned char temp = 0;
unsigned char count = 8;

SDA = 1; //置数据线为输入方式
do
{
SCL = 0; //置时钟线为低,准备接收数据位
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL = 1; //置时钟线为高使数据线上数据有效
_nop_();_nop_();_nop_();_nop_();_nop_();

if(SDA)
temp = temp | 0x01; //读数据位,接收的数据位放入temp中
else
temp = temp & 0xfe;

if(count - 1)
{
temp = temp << 1;
}
}
while(--count);
SCL = 0;
return temp;
}

 

posted @ 2012-01-28 10:34  一浩瀚星空一  阅读(437)  评论(0编辑  收藏  举报