打印

c8051f340控制EEPROM

[复制链接]
3588|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
赵俊|  楼主 | 2010-1-5 11:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问一下,用的是新华龙的C8051F340控制CAT24WC64。写入一个固定的数到固定的地址,但发现读出的都是0xff,郁闷至极。这程序以前用过的。烦请哪位高手给看看,晕的很呀。控制的SDA外接一个1K的上拉电阴到3.3V,SCL没接。单片机设置为SCL为普通IO口,SDA为漏极开漏。
如下:
#include"main.h"
#include"eeprom.h"
#define N    10
/************************************************************
;说明:读写24C256/512标准程序段
;适用于地址为两个字节的IIC存储器
************************************************************/
void nop_delay(uint8 i)
{
while(i--)
{
  _nop_();
}
}
/************************************************************
函数名称:void start_bit(void)        
入口参数:无   
返回参数:无;            
函数说明:通信开始位
************************************************************/
void start_bit(void)
{
  nop_delay(N);
  SCL=1;
  nop_delay(N);
  SDA=1;
  nop_delay(N);
  SDA=0;
  nop_delay(N);
  SCL=0;
  nop_delay(N);
}
/************************************************************
函数名称:void stop_bit(void)        
入口参数:无   
返回参数:无;            
函数说明:通信停止位            
************************************************************/
void stop_bit(void)
{
  nop_delay(N);
  SCL=1;
  nop_delay(N);
  SDA=0;
  nop_delay(N);
  SDA=1;
  nop_delay(N);
}
/************************************************************
函数名称:void ack(void)         
入口参数:无   
返回参数:无;            
函数说明:应答函数
************************************************************/
void ack(void)
{  uint8 data i;
// P1MDOUT   = 0x7c;
  nop_delay(N);
  SDA=1;
  nop_delay(N);
  SCL=0;
  nop_delay(N);
  SCL=1;
  nop_delay(N);
  while(SDA);
  nop_delay(N);
  //while((SDA)&&(i<255))
  //  i++;   //This may make the CPU crash. 04-3-18 17:16
  SCL=0;
  nop_delay(N);
  //P1MDOUT   = 0x7e;
}
/************************************************************
函数名称:void no_ack(void)      
入口参数:无   
返回参数:无;            
函数说明:无需应答位,在读程序中用到
************************************************************/
void no_ack(void)
{
  nop_delay(N);
  SDA=1;
  nop_delay(N);
  SCL=1;
  nop_delay(N);
  //while(SDA){;}  //This may make the CPU crash. 04-3-18 17:16
  SCL=0;
  nop_delay(N);
}
/************************************************************
函数名称:void write_8bit(uint8 ch)      
入口参数:所要写入的字节  
返回参数:无;            
函数说明:写一个字节(8位)数据
************************************************************/
void write_8bit(uint8 ch)
{
  uint8 data i=8;
  nop_delay(N);
  SCL=0;
  nop_delay(N);
  while(i--)
  {
   
    SDA=(bit)(ch&0x80);
    nop_delay(N);
    ch<<=1;
    nop_delay(N);
    SCL=1;
    nop_delay(N);
    SCL=0;
  }
}
/************************************************************
函数名称:uchar read24c16(uint address)      
入口参数:所要读取的16位地址  
返回参数:读取的字节;            
函数说明:读24c512指定地址数据(字节读)
************************************************************/
uint8 ReadFm24c256(uint16 address)
{
  
  //EA=0;//避免与串口通讯等中断冲突
  uint8 data rdata;
  uint8 data i=8;
  rdata=0;
  start_bit();
  write_8bit(0xA0);
  ack();
  write_8bit(address/256);
  ack();//伪写
  write_8bit(address%256);
  ack();
  start_bit();
  write_8bit(0xA1);
  ack();
  while(i--)
  {
    rdata<<=1;
    SCL=0;
    nop_delay(N);
    SCL=1;
    if(SDA) rdata|=0x01;
  }
  no_ack();
  stop_bit();
  //EA=1;
  return rdata;
}
/************************************************************
函数名称:void write24c16(uint address,uint8 ddata)      
入口参数:所要写入的16位地址,所要写入的字节  
返回参数:无            
函数说明:写数据到24c16的指定地址(字节写)
************************************************************/
void WriteFm24c256(uint16 address,uint8 ddata)
{
  //EA=0;  //避免与串口通讯等中断冲突
  nop_delay(N);
  start_bit();
  nop_delay(N);
  write_8bit(0xA0);
  ack();
  nop_delay(N);
  write_8bit(address/256);
  ack();
  write_8bit(address%256);
  ack();
  write_8bit(ddata);
  ack();
  stop_bit();
   //EA=1;
}

相关帖子

沙发
xuyaqi| | 2010-1-5 17:04 | 只看该作者
楼主说以前用过,以前是用c8051f340控制CAT24WC64吗?

使用特权

评论回复
板凳
赵俊|  楼主 | 2010-1-5 18:21 | 只看该作者
没有,是用来控制AT24C01系列。但我看资料上好象时序都是一样的呀。这个东西调了好几天,实在是郁闷至极
。希望哪位高手能给解决一下。非常感谢呀

使用特权

评论回复
地板
myfaith| | 2010-1-5 21:45 | 只看该作者
#include "./head/Head.h"
#include <intrins.h>

#define        OP_READ        0xa1                // 器件地址以及读取操作
#define        OP_WRITE 0xa0                // 器件地址以及写入操作
#define        MAX_ADDR 0x7f                // AT24C02最大地址

#define ACK 0
#define NACK 1

sbit SDA = P1^0;
sbit SCL = P1^1;


void I2C_Start();
void I2C_Stop();
unsigned char I2C_Shift_In(void);
uchar I2C_Shift_Out(unsigned char write_data);
unsigned char Eeprom_Read_Random(unsigned char random_addr,uchar RdData);
uchar Eeprom_Write_Byte( unsigned char addr, unsigned char write_data);
uchar Eeprom_Write_Page(uchar Addr,uchar *pWrData,uchar Len);
void delay_i2c(unsigned char ms);
uchar Eeprom_Read_Sequential(uchar Addr,uchar *RdBuf,uchar Len);

static void SomeNop(void)
{
        uchar n;
        for(n=0;n<30;n++)
                _nop_();
}

/*---------------------------------------------------------
---------------------------------------------------------*/       
void I2C_ACK(void)
{
        SDA = 0;
        SomeNop();
        SCL = 1;
        SomeNop();
        SCL = 0;
        _nop_();
        SDA = 1;
}       
void I2C_NACK(void)
{
        SDA = 1;
        SomeNop();
        SCL = 1;
        SomeNop();
        SCL = 0;
        SomeNop();
}
/*---------------------------------------------------------
---------------------------------------------------------*/
void I2C_Start()
// 开始位
{
        SDA = 1;
        SomeNop();
        SCL = 1;
        SomeNop();
        SDA = 0;
        SomeNop();
        SCL = 0;
        SomeNop();
}
/*---------------------------------------------------------

---------------------------------------------------------*/
void I2C_Stop()
{
        SCL = 0;
        SomeNop();
        SDA = 0;
        SomeNop();
        SCL = 1;
        SomeNop();
        SDA = 1;
}
/*---------------------------------------------------------
// 从AT24Cxx移入数据到MCU
---------------------------------------------------------*/       
unsigned char I2C_Shift_In(void)
{
        unsigned char i,read_data;
        SomeNop();
        for(i = 0; i < 8; i++)
        {
                SCL = 1;                  SomeNop();
                read_data <<= 1;
                read_data |= (unsigned char)SDA;
                SCL = 0;                   SomeNop();
        }
        return(read_data);
}
/*---------------------------------------------------------
// 从MCU移出数据到AT24Cxx
---------------------------------------------------------*/
uchar I2C_Shift_Out(unsigned char write_data)
{
        unsigned char i;
        uchar ack_bit;
        SomeNop();
        for(i = 0; i < 8; i++)                // 循环移入8个位
        {
                SDA = (bit)(write_data & 0x80);
                SomeNop();
                SCL = 1;
                SomeNop();
                SCL = 0;
                write_data <<= 1;
                SomeNop();
        }
        SDA = 1;                        //应答已出现在数据线上,释放数据线
        SomeNop();
        SCL = 1;
        SomeNop();                    //应答信号应在此SCL为高电平期间保持稳定
        ack_bit = SDA;
        SCL = 0;
        SomeNop();
        return ack_bit;                        // 返回AT24Cxx应答位
}
/*---------------------------------------------------------
// 在指定地址addr处写入数据write_data
---------------------------------------------------------*/
uchar Eeprom_Write_Byte(unsigned char addr, unsigned char write_data)
{
        I2C_Start();
        if(NACK == I2C_Shift_Out(OP_WRITE))
                return FALSE;
        if(NACK == I2C_Shift_Out(addr))
                return FALSE;
        if(NACK == I2C_Shift_Out(write_data))
                return FALSE;
        I2C_Stop();
        delay_i2c(255);                // 写入周期
        return TRUE;
}
/*---------------------------------------------------------
---------------------------------------------------------*/
uchar Eeprom_Write_Page(uchar Addr,uchar *pWrData,uchar Len)
{
        unsigned char i;
        I2C_Start();
        if(NACK == I2C_Shift_Out(OP_WRITE))
                return FALSE;
        if(NACK == I2C_Shift_Out(Addr))
                return FALSE;
        for(i = 0; i < Len; i++)
        {
                if(NACK == I2C_Shift_Out(*pWrData++))
                        return FALSE;
                delay_i2c(255);                // 写入周期
        }
        I2C_Stop();
        delay_i2c(255);
        return TRUE;
}
/*---------------------------------------------------------
// 在当前地址读取
---------------------------------------------------------*/
unsigned char Eeprom_Read_Current(uchar RdData)
{
        I2C_Start();
        if(NACK == I2C_Shift_Out(OP_READ))
                return FALSE;
        RdData = I2C_Shift_In();
        I2C_NACK();
        I2C_Stop();
        return TRUE;
}
/*---------------------------------------------------------
// 在指定地址读取
---------------------------------------------------------*/
unsigned char Eeprom_Read_Random(unsigned char random_addr,uchar RdData)
{
        I2C_Start();
        if(NACK == I2C_Shift_Out(OP_WRITE))
                return FALSE;
        if(NACK == I2C_Shift_Out(random_addr))
                return FALSE;
        if(FALSE == Eeprom_Read_Current(RdData))
                return FALSE;
        return        TRUE;
}
/*---------------------------------------------------------
---------------------------------------------------------*/
uchar Eeprom_Read_Sequential(uchar Addr,uchar *RdBuf,uchar Len)
{
        I2C_Start();
        if(NACK == I2C_Shift_Out(OP_WRITE))  //a0
                return FALSE;
        if(NACK == I2C_Shift_Out(Addr))       
                return FALSE;
        I2C_Start();
        if(NACK == I2C_Shift_Out(OP_READ))
                return FALSE;          
        while(Len)
        {
                *RdBuf++ = I2C_Shift_In();
                Len--;
                if(Len == 0)
                        I2C_NACK();
                else
                        I2C_ACK();
        }               
/*
        for(n=0;n<Len;n++)                 //哈哈,一字之差害我找了好久!
        {
                *RdBuf++ = I2C_Shift_In();
                if(n==Len)
                        I2C_NACK();
                else
                        I2C_ACK();
        }                 */
        I2C_Stop();       
        return TRUE;
}       
       
/*---------------------------------------------------------
//i=220,延时68us
//i=250,延时76us
//i=164,延时50.4us
---------------------------------------------------------*/
void delay_i2c(unsigned char n)       
// 延时子程序
{
        unsigned char i;
        while(n--)
        {
                for(i = 0; i < 164; i++);
        }
}
C8051F340,48M系统时钟.I2C时钟速度大概35K左右.奉献给楼主拉!

使用特权

评论回复
5
404710520| | 2013-1-9 10:44 | 只看该作者
看一下 现在也在自己写iic

使用特权

评论回复
6
ayb_ice| | 2013-1-9 13:27 | 只看该作者
多加几个NOP吧

使用特权

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

本版积分规则

8

主题

11

帖子

1

粉丝