whx.000 发表于 2019-9-5 08:02 谢谢了,问题已经解决了。给sda和sdl加上10k的上拉电阻,在电源和gnd之间加一个104.就好了。 |
24c02_data = Read_Eeprom_OneData(0); 这个是上电读EE吧,试试在读数据的前后各加20ms的延时 |
问题解决了,在网上重新找了个图。给电源个接了一个104电容,给SDA和SCL接了两个10k的上拉电阻。搞定了。 |
eeprom.c //EEPROM-24c02底层驱动文件 #include <msp430f249.h> #include "delay.h" #include "iic.h" #include "eeprom.h" //EEPROM容量 //- 24C02, 256 X 8 (2K bits) //- 24C04, 512 X 8 (4K bits) //- 24C08, 1024 X 8 (8K bits) //- 24C16, 2048 X 8 (16K bits) //- 24C32, 4096 X 8 (32K bits) //- 24C64, 8192 X 8 (64K bits) //在EEPROM-24c02指定地址写入一个数据 //Addr:写入数据的目的地址 0~255 for AT24C02 //Data:要写入的数据 void Write_Eeprom_OneData(u8 Addr,u8 Data) { IIC_Start(); Write_IIC_byte(WriteCom); //写命令 IIC_Ack(); Write_IIC_byte(Addr); IIC_Ack(); Write_IIC_byte(Data); IIC_Ack(); IIC_Stop(); Delay_ms(10);//等待EEPROM写入数据完成 } //在EEPROM-24c02指定地址读出一个数据 //Addr:开始读数的目的地址 0~255 for AT24C02 //Data:读到的数据 u8 Read_Eeprom_OneData(u8 Addr) { u8 Data; IIC_Start(); Write_IIC_byte(WriteCom); //写命令 IIC_Ack(); Write_IIC_byte(Addr); IIC_Ack(); IIC_Start(); Write_IIC_byte(ReadCom); //读命令 IIC_Ack(); Data = Read_IIC_byte(); IIC_NoAck(); IIC_Stop(); return Data; } //检查EEPROM-24c02是否正常 //返回1:检测成功,返回0:检测失败 //EEPROM-24c02的最后一个地址(255)来存储标志字 u8 EEPROM_24C02_Check(void) { u8 temp; IIC_Init();//初始化IIC总线 temp = Read_Eeprom_OneData(255);//先读取数据 if(temp == 8) return 1; else { Write_Eeprom_OneData(255,8);//24C02的255位置第一次写入数据 temp = Read_Eeprom_OneData(255); if(temp == 8) return 1;//读取数据成功 } return 0; } //在EEPROM-24c02里面的指定地址开始写入0~4294967295的数据 //Addr:开始写入的地址;Data:数据 //一个数据占用EEPROM-24c02四个地址 void Write_Eeprom_LenData(u16 Addr,u32 Data) { u8 t; for(t=0; t<4; t++) { Write_Eeprom_OneData(Addr+t,(Data>>(8*t))&0xFF); } } //在EEPROM-24c02里面的指定地址开始读出0~4294967295的数据 //Addr:开始读出的地址 Data:数据 //该函数用于读出32bit的数据 u32 Read_Eeprom_LenData(u16 Addr) { u8 t; u32 Data; for(t=0; t<4; t++) { Data <<= 8; Data += Read_Eeprom_OneData(Addr+4-t-1); } return Data; } //在EEPROM-24c02里面的指定地址开始写入指定个数的字符串 //Addr:开始写入的地址 对24c02为0~255;Buf:数据数组首地址;Num:要写入数据的个数 void Write_Eeprom_NubStr(u16 Addr,u8 *Buf,u16 Num) { while(Num --) { Write_Eeprom_OneData(Addr,*Buf); Addr ++; Buf ++; } } //在EEPROM-24c02里面的指定地址开始读出指定个数的字符串 //Addr:开始读出的地址 对24c02为0~255;Buf:数据数组首地址;Num:要读出数据的个数 void Read_Eeprom_NubStr(u16 Addr,u8 *Buf,u16 Num) { while(Num) { *Buf ++= Read_Eeprom_OneData(Addr ++); Num --; } } |
由于长度不足。 iic.c //模拟IIC总线底层驱动文件 #include <msp430f249.h> #include "delay.h" #include "iic.h" //IIC_SDA方向输出 void IIC_SDAOut(void) { P5DIR |= (1<<1);//设置为输出 } //IIC_SDA方向输入 void IIC_SDAIn(void) { P5DIR &= ~(1<<1);//设置为输入 } //IIC初始化 void IIC_Init(void) { P5SEL &= 0xf9;//设置P5.1,P5.2IO口为普通I/O模式 P5DIR |= 0x06;//设置P5.1,P5.2IO口方向为输出 P5OUT |= 0x06;//初始设置P5.1,P5.2IO为高电平 IIC_SDA_H; IIC_SCL_H; Delay_us(5); } //起始信号函数 void IIC_Start(void) { IIC_SDAOut(); IIC_SDA_H; IIC_SCL_H; Delay_us(5); IIC_SDA_L; Delay_us(5); } //停止信号函数 void IIC_Stop(void) { IIC_SDAOut(); IIC_SDA_L; Delay_us(5); IIC_SCL_H; Delay_us(5); IIC_SDA_H; Delay_us(5); } //应答函数 void IIC_Ack(void) { u8 time = 220; IIC_SDAIn(); IIC_SCL_H; Delay_us(5); while(IIC_SDA_D && time --);//等待从机返回低电平应答信号 IIC_SCL_L; Delay_us(5); } //非应答函数 void IIC_NoAck(void) { IIC_SDAOut(); IIC_SDA_H; Delay_us(5); IIC_SCL_H; Delay_us(5); IIC_SCL_L; Delay_us(5); } //写字节函数 void Write_IIC_byte(u8 Data) { u8 i; IIC_SDAOut(); IIC_SCL_L; for(i=0; i<8; i++) { if(Data & 0x80) { IIC_SDA_H; } else { IIC_SDA_L; } Data <<= 1; Delay_us(5); IIC_SCL_H; Delay_us(5); IIC_SCL_L; Delay_us(5); } IIC_SDA_H; Delay_us(5); } //读字节函数 u8 Read_IIC_byte(void) { u8 i, byte=0; IIC_SDAIn(); IIC_SCL_L; Delay_us(5); for(i=0; i<8; i++) { IIC_SCL_H; Delay_us(5); byte <<= 1; if(IIC_SDA_D) byte ++; Delay_us(5); IIC_SCL_L; Delay_us(5); } return byte; } |