打印
[AVR单片机]

铁电真铁,FM24C256写不进去,贴出程序-M32

[复制链接]
4743|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
thankw|  楼主 | 2010-4-22 10:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#define uint8     unsigned char
#define uint16    unsigned int
#define uint32    unsigned long

#define SETBIT(x, y)        (x |= y)
#define CLEARBIT(x, y)    (x &= ~y)
#define CHECKBIT(x, y)   (x & y)

#define PCBIT7 0x80
#define PCBIT6 0x40
#define PCBIT5 0x20
#define PCBIT4 0x10
#define PCBIT3 0x08
#define PCBIT2 0x04
#define PCBIT1 0x02
#define PCBIT0 0x01

/*-------------
FM24C256
--------------*/
#define SCL PCBIT0
#define SDA PCBIT1
#define I2CPORT       PORTC
#define I2CPORTD     DDRC
#define I2CPORTIN    PINC

/*-------------------------------------------------------------
2010-04-16
CPU:Atmega32
晶振:4MHz
FM24C256-GTR
I/O模拟I2C时序控制铁电子程序  
---------------------------------------------------------------*/

#define I2CReadCMD  0xa1
#define I2CWriteCMD 0xa0
#define SomeNops NOP();NOP();NOP()

uint8 I2CSlaveAckFlag=0;

void I2CPORTInit (void)
{
  SETBIT(I2CPORTD,SCL);    //设置SCL为输出
  NOP();NOP();NOP();
  SETBIT(I2CPORTD,SDA);    //设置SDA为输出
  NOP();NOP();NOP();
  
  SETBIT(I2CPORT,SCL);     //SCL=1
  NOP();NOP();NOP();
  SETBIT(I2CPORT,SDA);     //SDA=1
  NOP();NOP();NOP();
}

void I2CStart (void)
{
  SETBIT(I2CPORTD,SDA);    //设置SDA为输出
  NOP();NOP();NOP();

  SETBIT(I2CPORT,SCL);     //SCL=1
  SomeNops;
  SETBIT(I2CPORT,SDA);     //SDA=1
  SomeNops;
  CLEARBIT(I2CPORT,SDA);   //SDA=0
  SomeNops;
  CLEARBIT(I2CPORT,SCL);   //SCL=0
  SomeNops;
}

void I2CStop (void)
{
  SETBIT(I2CPORTD,SDA);    //设置SDA为输出

  CLEARBIT(I2CPORT,SCL);   //SCL=0   
  SomeNops;
  CLEARBIT(I2CPORT,SDA);   //SDA=0   
  SomeNops;   
  SETBIT(I2CPORT,SCL);     //SCL=1
  SomeNops;   
  SETBIT(I2CPORT,SDA);     //SDA=1   
  SomeNops;
  CLEARBIT(I2CPORT,SCL);   //SCL=0   
  SomeNops;
}

void I2CHostAck (void)
{
  SETBIT(I2CPORTD,SDA);   //设置SDA为输出

  CLEARBIT(I2CPORT,SCL);  //SCL=0
  SomeNops;
  CLEARBIT(I2CPORT,SDA);  //SDA=0
  SomeNops;
  SETBIT(I2CPORT,SCL);    //SCL=1
  SomeNops;
  CLEARBIT(I2CPORT,SCL);  //SCL=0
  SomeNops;
}

void I2CSlaveAck (void)
{
  SETBIT(I2CPORTD,SDA);   //设置SDA为输出

  CLEARBIT(I2CPORT,SCL);  //SCL=0
  SomeNops;
  SETBIT(I2CPORT,SDA);    //SDA=1
  SomeNops;
  SETBIT(I2CPORT,SCL);    //SCL=1
  CLEARBIT(I2CPORTD,SDA); //设置SDA为输入
  SomeNops;
  I2CSlaveAckFlag=(I2CPORTIN&0x02);
  CLEARBIT(I2CPORT,SCL);  //SCL=0
  SomeNops;
}

void I2CNoAck(void)
{
  SETBIT(I2CPORTD,SDA);   //设置SDA为输出

  SETBIT(I2CPORT,SDA);    //SDA=1
  SomeNops;
  SETBIT(I2CPORT,SCL);    //SCL=1
  SomeNops;   
  CLEARBIT(I2CPORT,SCL);  //SCL=0
  SomeNops;
}

/*-----------------------------------------------
读一个字节从I2C总线上
-----------------------------------------------*/
uint8 Read1Byte2I2c (void)
{
  uint8 I2CByte=0;
  uint8 I2CByteTemp=0;
  uint8 i=0;

  SETBIT(I2CPORTD,SDA);      //设置SDA为输出
  SETBIT(I2CPORT,SDA);       //SDA=1
  SomeNops;

  CLEARBIT(I2CPORTD,SDA);    //设置SDA为输入
  SomeNops;

  for(i=0;i<8;i++)
  {
     I2CByte<<=1;
   
     SETBIT(I2CPORT,SCL);    //SCL=1
     SomeNops;
     I2CByteTemp=(I2CPORTIN&0x02);
     I2CByteTemp>>=1  ;
     I2CByte |= I2CByteTemp;
     CLEARBIT(I2CPORT,SCL);  //SCL=0
     SomeNops;
   }

   return (I2CByte);
}

/*-----------------------------------------------
写一个字节到I2C总线上
-----------------------------------------------*/
void Write1Byte2I2C (uint8 I2CByte)
{
  uint8 i=0;

  SETBIT(I2CPORTD,SDA);          //设置SDA为输出

  for(i=0;i<8;i++)
  {
    CLEARBIT(I2CPORT,SCL);       //SCL=0
    if( (I2CByte&0x80) == 0x80 )  
      SETBIT(I2CPORT, SDA);      //SDA=1
    else  
      CLEARBIT(I2CPORT,SDA);     //SDA=0
    NOP();NOP();
    SETBIT(I2CPORT,SCL);         //SCL=1   
    SomeNops;
   
    I2CByte<<=1;
   }
}

/*----------------------------------------------
从FM24C256中读出单个个字节
-----------------------------------------------*/
uint8 FM24C256Read1Byte (uint16 Address)
{
  uint8 I2CByte=0;

  I2CStart();
  Write1Byte2I2C(I2CWriteCMD);
  I2CSlaveAck();
  Write1Byte2I2C(Address/256);
  I2CSlaveAck();
  Write1Byte2I2C(Address%256);
  I2CSlaveAck();
  I2CStart();
  Write1Byte2I2C(I2CReadCMD);
  I2CSlaveAck();
  I2CByte=Read1Byte2I2c();
  I2CNoAck();
  I2CStop();

  return (I2CByte);
}

/*----------------------------------------------
从FM24C256中读出多个个字节
-----------------------------------------------*/
void FM24C256Read (uint16 Address , uint16 ByteNumber , uint8 * DataPoint)
{
  uint8   I2CDataTemp=0;
  uint16  i=0;

  I2CStart();
  Write1Byte2I2C(I2CWriteCMD);
  I2CSlaveAck();
  Write1Byte2I2C(Address/256);
  I2CSlaveAck();
  Write1Byte2I2C(Address%256);
  I2CSlaveAck();
  I2CStart();
  Write1Byte2I2C(I2CReadCMD);
  I2CSlaveAck();

  for(i=0;i<(ByteNumber-1);i++)
  {
    * (DataPoint+i)=Read1Byte2I2c();
    I2CHostAck();
   }

   * (DataPoint+ByteNumber-1)=Read1Byte2I2c();

   I2CNoAck();
   I2CStop();
}

/*-----------------------------------------------
向FM24C256中写入单个或多个个字节
-----------------------------------------------*/
void FM24C256Write (uint16 Address , uint16 ByteNumber , uint8 * DataPoint)
{
  uint16 i=0;

  I2CStart();
  Write1Byte2I2C(I2CWriteCMD);
  I2CSlaveAck();
  Write1Byte2I2C(Address/256);
  I2CSlaveAck();
  Write1Byte2I2C(Address%256);
  I2CSlaveAck();

  for(i=0;i<ByteNumber;i++)
  {
    Write1Byte2I2C( * (DataPoint+i) );
    I2CSlaveAck();
  }

  I2CStop();
}

//ICC-AVR application builder : 2010-4-20 9:19:00
// Target : M32
// Crystal: 4.0000Mhz

#include <iom32v.h>
#include <macros.h>
#include <AVRdef.h>
#include "PUBLIC.H"
#include "MAIN.H"

extern void     I2CPORTInit (void);
extern uint8    FM24C256Read1Byte (uint16 Address);
extern void     FM24C256Read  (uint16 Address , uint16 ByteNumber , uint8 * DataPoint);
extern void     FM24C256Write (uint16 Address , uint16 ByteNumber , uint8 * DataPoint);

#define TestAddress 0x0010

uint8 TestTemp1=0;
uint8 TestTemp2=0;
uint8 TestArray1[10]={0,0,0,0,0,0,0,0,0,0};

void port_init(void)
{
PORTA = 0x00;
DDRA  = 0x00;
PORTB = 0x00;
DDRB  = 0x00;
PORTC = 0x00;  
DDRC  = 0x00;
PORTD = 0x00;
DDRD  = 0x00;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();

MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}

//
void main(void)
{
  init_devices();

  //SETBIT(I2CPORTD,SDA);
  //SETBIT(I2CPORT,SDA);

  //CLEARBIT(I2CPORTD,SDA);
   
  //if( CHECKBIT(I2CPORTIN,SDA) )
     //TestTemp1=0;

  I2CPORTInit();

  TestTemp2=FM24C256Read1Byte(TestAddress);

  TestTemp1=0;

  TestTemp1=0x0f;

  FM24C256Write(TestAddress,1,&TestTemp1);

  TestTemp1=0;

  TestTemp2=FM24C256Read1Byte(TestAddress);

  TestTemp1=0;

  TestTemp1=0;
}


------------------------------------------------------------------
以上是我的程序,现在从任何地址读出一个字节都是0xff,写入0x0f后读出还是0xff,一开始我认为是读对了,因为一般储存器没写过应该是0xff的,但是仔细观察有无应答信号,在读FM24C256单个字节的函数(FM24C256Read1Byte)那里设了断点,发现就只有发送第一个命令字节是有正确应答的(低电平),后边都是高电平。所以好像读也不对。SomeNops试过5个NOP也不行,我用的4MHZ,那么一条NOP就是1/4微妙,看了FM24C256数据手册,最快能支持1MHZ。有用过铁电的朋友请发表下看法。谢谢。

我用的ICCAVR 7.22+AVRStudio最新版+JTAG ICE

主函数我用的向导生成然后加入自己的代码,因为看见向导那里可以设置晶振频率。

相关帖子

沙发
自然的天逸| | 2010-4-22 11:44 | 只看该作者
你换普通的EEROM存储器测试一下 试过程序是可以通用的

使用特权

评论回复
板凳
xiaohuai| | 2010-4-22 21:42 | 只看该作者
铁电真铁??什么意思

使用特权

评论回复
地板
午夜粪车| | 2010-4-22 21:49 | 只看该作者
是啊,看不懂

使用特权

评论回复
5
thankw|  楼主 | 2010-4-23 09:23 | 只看该作者
:$谢谢2楼的意见,已经解决了。

使用特权

评论回复
6
QQ931521083| | 2011-11-18 14:38 | 只看该作者
他的意思铁电真硬,铁一样 。写不进去数据,哈哈哈。

使用特权

评论回复
7
NE5532| | 2011-11-18 20:00 | 只看该作者
哈哈,楼主写的程序不出问题,我都不信。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

15

帖子

0

粉丝