#define EEP_PORT PORTC //定义是使用PROTC口
#define EEP_DDR DDRC //定义是使用PROTC口
#define SDA 0X10 //定义sda连接的是portd1
#define SCL 0X20 //定义scl连接的是portd0
//#define WP 0X04 //定义wp连接的是portd2
#define EEP_ADD_R 0xa1 //写I2C从器件地址和读方式 a0,a1接地
#define EEP_ADD_W 0xa0 //写I2C从器件地址和写方式 a0,a1接地
void delay(unsigned int us)
{
while(us--);
}
void eep_init(void)
{
EEP_DDR|= SDA | SCL ;//| WP ;
EEP_PORT|=SDA | SCL ;//| WP ;
}
void send(void)
{
EEP_PORT|=SCL;
asm("nop");
EEP_PORT&=~SCL;
}
/********************************************
内部函数,I2C开始
********************************************/
void Start(void)
{
EEP_PORT|=SDA; //sda
EEP_PORT|=SCL; //scl
asm("nop");
EEP_PORT&=~SDA;
asm("nop");
EEP_PORT&=~SCL;
}
/********************************************
内部函数,I2C结束
********************************************/
void Stop(void)
{
EEP_PORT&=~SDA;
EEP_PORT&=~SCL;
asm("nop");
EEP_PORT|=SCL;
asm("nop");
EEP_PORT|=SDA;
asm("nop");
}
/********************************************
内部函数,等待ACK
********************************************/
void ACK(void)
{
unsigned char errtime=20;
EEP_PORT|=SDA; //上拉
EEP_DDR&=~SDA; //设置为输入口
EEP_PORT|=SCL;
asm("nop");
while(PINC&SDA)
{ errtime--;
if(!errtime)
{
Stop();
EEP_PORT&=~SDA; //超时,给他个离开的理由
}
}
EEP_PORT&=~SCL;
asm("nop");
EEP_DDR|=SDA; //设置为输出口
}
/********************************************
内部函数.输出数据字节
********************************************/
void writebyte(unsigned char wdata)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((wdata&0x80)){EEP_PORT|=SDA;}else{EEP_PORT&=~SDA;}
wdata<<=1;
send(); //发送一个位
}
}
/********************************************
内部函数.输入数据
********************************************/
unsigned char Readbyte(void)
{
unsigned char i,bytedata;
EEP_DDR&=~SDA; //设置为输入?
for(i=0;i<8;i++)
{
EEP_PORT|=SCL;
bytedata<<=1;
if(PINC&SDA){
bytedata|=0X01;
}else{
bytedata&=~0X01;
}
EEP_PORT&=~SCL;
asm("nop");
}
EEP_DDR|=SDA;
return(bytedata);
}
/********************读24cxx--外部调用********************/
unsigned char read_eep(unsigned char add1,unsigned char add2)
{ unsigned char mdata;
Start(); //起始位
writebyte(EEP_ADD_W); //写eeprom地址+1个写命令
ACK(); //等待应答信号
writebyte(add1); //写如访问地址
ACK(); //等待应答信号
writebyte(add2); //写入访问地址
ACK(); //等待应答信号
Start(); //起始位
writebyte(EEP_ADD_R); //写eeprom地址+1个读命令
ACK(); //等待应答信号
mdata=Readbyte(); //获取数据
Stop(); //发送停止位置
asm("nop"); //此处延时根据实际情况,如果不延时,可能会不正常
return(mdata);
}
/********************写24cxx--外部调用********************/
void write_eep(unsigned char add1,unsigned char add2,unsigned char udata)
{
//EEP_PORT&=~WP; //关闭写保护
Start(); //起始位
writebyte(EEP_ADD_W); //写eeprom地址+1个写命令
ACK(); //等待应答信号
writebyte(add1); //写如访问地址
ACK(); //等待应答信号
writebyte(add2); //写如访问地址
ACK(); //等待应答信号
writebyte(udata); //写入数据
ACK(); //等待应答信号
Stop(); //发送停止位
delay(24000);
//delay_nms(4); //此处延时根据实际情况,大多EEPROM都需要3毫秒的写入时间,如果不延时,可能会不正常
//EEP_PORT|=WP; //打开写保护
}
void main(void)
{
unsigned char tmp;
eep_init();
DDRC|=(1<<0);
PORTC&=~(1<<0);
write_eep(0,2,7);
tmp=read_eep(0,2);
if(tmp==7)
PORTC|=(1<<0);
while(1);
}
上一篇:基于物流运输过程监测的振动测量系统
下一篇:ATMEGA16用IO模拟SPI驱动ADS7843
推荐阅读最新更新时间:2024-03-16 15:11