• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

关于AT24C02 c51的问题.

用c51写的at24c02的读写程序,先写后读,全是ff.

元件是好的,我用汇编写过一个,运行是ok的.

查了两天没找到问题.
#include   /*51标准库函数*/
#include /*定义了_nop_()*/

#define uchar unsigned char
#define uint unsigned int

sbit SCL=P1^6;
sbit SDA=P1^7;


/*
* 1,函数介绍:延时8us(以12M晶振为准)
* 输入参数: 无
* 输出参数: 无
* 返回值:   无
*/
void delay8us(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
}

/*
* 2,函数介绍:延时n_msec ms(以12M晶振为准)
* 输入参数: n_msec,最大256
* 输出参数: 无
* 返回值:   无
*/
void delay_ms(uchar n_msec)
{
uchar i;
do
{  
  i=245;
  while(--i);
  i=245;
  while(--i);    
}
while(--n_msec);
}

/*
* 3,函数介绍:I2C起动总线函数  
* 输入参数: 无
* 输出参数: 无
* 返回值:      无
*/
void i2c_start(void)
{
SDA=1;
SCL=1;
delay8us();
SDA=0;  
SCL=0;
}

/*
* 4,函数介绍:I2C结束函数  
* 输入参数: 无
* 输出参数: 无
* 返回值:      无
*/
void i2c_stop(void)
{
  
SDA=0; /*发送结束条件的数据信号*/
SCL=1;
delay8us();
SDA=1;
SCL=1;
}

/*
* 5,函数介绍:I2C写一个字节str
* 输入参数: str
* 输出参数: 返回应答位
* 返回值:      为0 成功
*/
bit i2c_write_byte(uchar str)
{
uchar bitnum;
uchar temp;
bit ack;
temp=str;
for(bitnum=0;bitnum<8;bitnum++)
{
  SCL=0;    
  SDA=temp&0x80;  
  SCL=1;  
  delay8us();
  temp=temp<<1;
}
SCL=0;
SDA=1;
delay8us();
SCL=1;  
ack=SDA;  
return(ack); /*判断是否接收到应答,1表示没有应答*/
}




/*AT24C02eeprom系列函数

,函数介绍:(以12M晶振为准)*/

void delay8us(void);/*延时子程序*/
void delay_ms(uchar);/*延时子程序*/
void i2c_start(void);
void i2c_stop(void);
bit i2c_write_byte(uchar str);

/*
* 1,函数介绍:发送应答        
* 输入参数: 址
* 输出参数:
* 返回值:      
*/
void send_ack(void)
{
SCL=0;
delay8us();
SDA=0;
delay8us();
SCL=1;
SDA=1;
}

/*
* 2,函数介绍:发送不应答        
* 输入参数:
* 输出参数:
* 返回值:      
*/
void send_no_ack(void)
{
SCL=0;
delay8us();
SDA=1;
delay8us();
SCL=1;
SDA=1;
}

/*
* 3,函数介绍:I2C读一个字节str
* 输入参数: str
* 输出参数: 返回读得的字节
* 返回值:    
*/
uchar i2c_read_byte()
{
bit bdata onebit=0;
uchar bitnum;
uchar read_abyte=0;

for(bitnum=0;bitnum<8;bitnum++)
{
  read_abyte<<=1;
  SCL=0;    
  SDA=1;
  delay8us();    
  SCL=1;
  delay8us();
  onebit=SDA;
  if(onebit==1)
  read_abyte++;
}
return(read_abyte);
}


/*
* 4,函数介绍:EEPROM页读n个字节从起始到结束        
* 输入参数: part_add:器件地址
            ram_add:片内字节地址,
            write_num:欲写个数
            data_add:欲写数据地址
* 输出参数:
* 返回值:      
*/
void eeprom_read_page(part_add,ram_add,read_num,data_add)

uchar part_add;
uchar ram_add;
uchar read_num;
uchar *data_add;
{
uchar i;
i2c_start();
i2c_write_byte(part_add);
i2c_write_byte(ram_add);
i2c_start();
i=part_add|0x01;
i2c_write_byte(i);
for(i=0;i {
  *(data_add+i)=i2c_read_byte();
  if(i!=read_num-1)send_ack();
  else send_no_ack();
}
i2c_stop();
}

/*
* 5,函数介绍:EEPROM发送页写n个字节从起始到结束        
* 输入参数: part_add:器件地址
            ram_add:片内字节地址,
            write_num:欲写个数
            data_add:欲写数据地址
* 输出参数:
* 返回值:      
*/
void eeprom_write_page(part_add,ram_add,write_num,data_add)
uchar part_add;
uchar ram_add;
uchar write_num;
uchar *data_add;
{
uchar i;
bit ack;
i2c_start();
ack=i2c_write_byte(part_add);
if(ack==1)FRONT_LED=0;
i2c_write_byte(ram_add);
REAR_LED=0;
for(i=0;i {
  i2c_write_byte(*(data_add+i));
  delay_ms(1);
}
i2c_stop();
delay_ms(20);
_nop_();
_nop_();
}
全部回复(5)
正序查看
倒序查看
2008-04-09 21:04
检查过时序,没发现什么问题.看来有空得研究下汇编,C交叉应用了.
0
回复
lauvictor
LV.1
3
2008-05-14 18:44
没看出有啥问题.能讲讲是实现啥功能的吗?还有,你仿真单片机用什么软件啊?我做数字电源的课题,好像没办法仿真,不知有没有什么解决方案.
0
回复
2008-05-17 23:14
@lauvictor
没看出有啥问题.能讲讲是实现啥功能的吗?还有,你仿真单片机用什么软件啊?我做数字电源的课题,好像没办法仿真,不知有没有什么解决方案.
我这是一个EEPROM的读写子程序.后来查到问题是在写一个BYTE到EERPOM时检查应答的时间不够引起的.

软件仿真我用MedWin.电源仿真没试过..

仿真还不如果直接装硬件上去调.
0
回复
lauvictor
LV.1
5
2008-05-20 10:07
@zj47988302
我这是一个EEPROM的读写子程序.后来查到问题是在写一个BYTE到EERPOM时检查应答的时间不够引起的.软件仿真我用MedWin.电源仿真没试过..仿真还不如果直接装硬件上去调.
主要是时间不够,没办法实物调试.谢谢了
0
回复
2008-08-22 14:43
LZ你好,能否将汇编的发给我一份吗?我现在正在学习写这个!谢谢!
0
回复