首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

nios i2c 读写数据程序的问题

nios i2c 读写数据程序的问题

以下是对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时序,应该没有什么问题,不知道的你延时够不够。

在交流中前进,共同实现nios的应用。

延时

延时也不应该有问题啊 不然应该一个数据都读不出来  为什么有的数据可以,有的数据不可以 ,头疼啊

确定你的芯片没有问题吗?延时有问题可能有的,时间正好处在你的临界可能出现这样的问题。

在交流中前进,共同实现nios的应用。
返回列表