以下是对at89c0808c加密芯片的memory test zone 读写数据的程序,但是有些数据读写正确,有些数据读写就错误,请指点!!
#include"string.h"
#include <stdio.h>
#include "altera_avalon_pio_regs.h"
#include "system.h"
#include "time.h"
#define Set_SDA IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE, 0x1)
#define Clr_SDA IOWR_ALTERA_AVALON_PIO_DATA(SDA_BASE, 0x0)
#define Set_SCL IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE, 0x1)
#define Clr_SCL IOWR_ALTERA_AVALON_PIO_DATA(SCL_BASE, 0x0)
void delay1us()
{int a1;
for(a1=0;a1<50;a1++);
}
void delay1ms()
{int a2;
for(a2=0;a2<50000;a2++);
}
void I2C_Start(void)
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
Set_SDA;
Set_SCL;
delay1us();
Clr_SDA;
delay1us();
Clr_SCL;
delay1us();
}
void I2C_Stop(void)
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
Clr_SDA;
Clr_SCL;
delay1us();
Clr_SDA;
Set_SCL;
delay1us();
Set_SDA;
delay1us();
}
void I2C_Ack(void)
{ IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
Clr_SDA;
delay1us();
Set_SCL;
delay1us();
Clr_SCL;
delay1us();
}
void Check_Ack(void)
{int a=1;
IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x0);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
Clr_SCL;
delay1us();
Set_SCL;
delay1us();
while(a)
{
a=IORD_ALTERA_AVALON_PIO_DATA(SDA_BASE);
delay1us();
printf("waiting ACK .a is %d\n",a);
}
delay1us();
printf("detected ACK\n");
Clr_SCL;
delay1us();
}
void I2C_Nack(void)
{ IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
Set_SDA;
delay1us();
Set_SCL;
delay1us();
Clr_SCL;
delay1us();
}
void I2C_Send_Byte(int d)
{
int i = 8;
IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
delay1us();
Clr_SDA;
Clr_SCL;
delay1us();
while( i-- )
{
if (d&0x80)
Set_SDA;
else
Clr_SDA;
delay1us();
Set_SCL;
delay1us();
Clr_SCL;
delay1us();
Clr_SDA;
Clr_SCL;
delay1us();
d = d << 1;
}
delay1us();
}
int I2C_Receive_Byte(void)
{ int retc,bitcnt;
retc=0;
IOWR_ALTERA_AVALON_PIO_DIRECTION(SDA_BASE, 0x0);
IOWR_ALTERA_AVALON_PIO_DIRECTION(SCL_BASE, 0x1);
delay1us();
for(bitcnt=0;bitcnt<8;bitcnt++)
{ Set_SCL;
delay1ms();
retc=retc<<1;
if((int)IORD_ALTERA_AVALON_PIO_DATA(SDA_BASE)) retc=retc+1;
Clr_SCL;
delay1ms();
}
return(retc);
}
int main()
{int data[500]={0}; int cnt;
I2C_Start();
I2C_Send_Byte(0xb4);
Check_Ack();
I2C_Send_Byte(0x00);
Check_Ack();
I2C_Send_Byte(0x0a);
Check_Ack();
I2C_Send_Byte(0x02);
Check_Ack();
I2C_Send_Byte(0x39);
Check_Ack();
I2C_Send_Byte(0x8d);
Check_Ack();
I2C_Stop();
delay1ms();
I2C_Start();
I2C_Send_Byte(0xb6);
Check_Ack();
I2C_Send_Byte(0x00);
Check_Ack();
I2C_Send_Byte(0x0a);
Check_Ack();
I2C_Send_Byte(0x02);
Check_Ack();
for(cnt=0;cnt<2;cnt++)
{data[cnt]=I2C_Receive_Byte();
printf("data=%x\n",data[cnt]);
I2C_Ack();
}
data[cnt+1]=I2C_Receive_Byte();
printf("data=%x\n",data[cnt+1]);
I2C_Nack();
I2C_Stop();
}
I2C最简单了,看了你的代码,用IO模拟的一个I2C时序,应该没有什么问题,不知道的你延时够不够。
延时也不应该有问题啊 不然应该一个数据都读不出来 为什么有的数据可以,有的数据不可以 ,头疼啊
确定你的芯片没有问题吗?延时有问题可能有的,时间正好处在你的临界可能出现这样的问题。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |