关于I2C的读写问题,我用的是新华龙的C8051F040 5
我用新华龙公司的C8051f040单片机读写外部的fm24c02是为什么写了几个数字到不同的内存地址,但从不同地址读数时总是读到的是最后一个写进去的值呢,这个一般是什么问...
我用新华龙公司的C8051f040单片机读写外部的fm24c02是为什么写了几个数字到不同的内存地址,但从不同地址读数时总是读到的是最后一个写进去的值呢,这个一般是什么问题引起的,高手请帮帮忙吧,小弟不胜感激!!
while(1)
{
SM_Send(0x01, 0x51); // Send 0x51(data) to address 0x01 on CHIP_A
delay_us(1000);
check = SM_Receive(0x01); // 在此处设断点可观察check值的变化
SM_Send(0x04, 0x52); // Send 0x52(data) to address 0x04 on CHIP_A
delay_us(1000);
che1 = SM_Receive(0x04);
delay_us(1000);
che2 = SM_Receive(0x01); //从CHIP_A的address 0x01取值 ,可是取到的是0x52
che3 = SM_Receive(0x04); //从CHIP_A的address 0x04取值 ,取到的也是0x52,所以我存在的问题是取 //到的总是最后一个写进去的值,我怀疑我根本就没写进去,就是数据都是在线上
}
这是我摘来的一段程序!!! 展开
while(1)
{
SM_Send(0x01, 0x51); // Send 0x51(data) to address 0x01 on CHIP_A
delay_us(1000);
check = SM_Receive(0x01); // 在此处设断点可观察check值的变化
SM_Send(0x04, 0x52); // Send 0x52(data) to address 0x04 on CHIP_A
delay_us(1000);
che1 = SM_Receive(0x04);
delay_us(1000);
che2 = SM_Receive(0x01); //从CHIP_A的address 0x01取值 ,可是取到的是0x52
che3 = SM_Receive(0x04); //从CHIP_A的address 0x04取值 ,取到的也是0x52,所以我存在的问题是取 //到的总是最后一个写进去的值,我怀疑我根本就没写进去,就是数据都是在线上
}
这是我摘来的一段程序!!! 展开
3个回答
展开全部
//**********************************//
// SMB0CN的初始化
//*********************************//
void SMB0CN_INIT(void)
{
SMB0CN =0x44 ; //ENABLE SMBUS,应答周期发ASK 01000100
EIE1 |=0x02; //扩展中断允许;允许SMBUS中断
}
//***********************************//
//SCL时钟频率设置的初始化
//***********************************//
void SMBUS0CR_INIT(void)
{
SMB0CR = 0xe0; //////11100000 时钟速率每隔1.446us产生一次低电平
///////每隔1.537us产生高电平
write_512framflg=0;
}
//********************************************//
//WRITE A BLOCK TO EEPROM24C64
//*******************************************//
//***************************************//
//***************************************//
//**********************************//
//READ A BLOCK FORM EEPROM
//**********************************//
//**********************************//
//中断处理子程序
//**********************************//
void SMBUS0_SI(void) interrupt 7
{
unsigned char i;
unsigned int l;
switch(SMB0STA) ////////SMB0STA状态寄存器
{ case 0x08:
SMB0DAT = COMMAND; //起始条件已发出,写控制字节
STA=0;
break;
case 0x10:
SMB0DAT = COMMANDR;
STA =0;
COMMANDR = 0;
break;
case 0x18:
SMB0DAT=ADDR_H ;//ADDR_H; //从地址+w已发出,并收到ACK
break;
case 0x20: //nack
STO=1;
STA=1;
break;
case 0x28:{
//数据字节已发出,收到ACK
switch(BYTE_NUMBER)
{
case 0: //数据已发送完毕
STO=1;
BUSY=0; //释放总线
i2c_mangflg = 0;
break;
case 2:
SMB0DAT =ADDR_L; //说明只发送了ADDR_H
BYTE_NUMBER--;
break;
case 1: //说明ADDR_L已发送
if((COMMANDR&0x01)==1)//读指定单元
{
STA =1;
}
else{
SMB0DAT =sys_con_temp[NUMBER];
NUMBER = NUMBER + 1;
if(NUMBER == info_length){
BYTE_NUMBER--;
NUMBER = 0;
//WDTCN = 0xA5; //使能WDT
}
}
break;
default: //数据已发送完毕
STO=1;
BUSY=0; //释放总线
}
}
break;
case 0x30:
STO =1; //smbus停止标志
STA =1; //smbus起始标志
break;
case 0x40:
AA =1;
break;
case 0x50:
sys_con_temp[x] = SMB0DAT;
x=x+1;
if(x==(info_length-1))
{
AA=0; /////smbus确认标志
}
break;
case 0x58:
sys_con_temp[x] = SMB0DAT;
x=x+1;
if(x==info_length){
BUSY =0;
STO =1;
//WDTCN = 0xA5; //使能WDT
for(i=0;i<40;i++){
l = (unsigned int)(sys_con_temp[i*2+1])<<8;
l = l + (unsigned int)(sys_con_temp[i*2]);
sys_con[i] = l;
}
TH1 = -(SYSCLK/sys_con[2]/16/12);
for(i=0;i<6;i++)
{
yc_mes_real[128+i*2] = sys_con[17+i*2];
yc_mes_real[128+i*2+1]=sys_con[17+i*2+1];
}
i2c_mangflg = 0;
}
break;
default:
STO =1;
BUSY =0;
break;
}
SI =0; //CLEAR SI smbus中断
}
/////////// 读写FRAM ////////////
void Read_512fram(void)
{
SMB0CN_INIT();
BYTE_NUMBER=2;
COMMAND=(0xA0|0x00); //CS ADDR=10100000=A0
COMMANDR=(0xA0|0x01); //CS ADDR=10100001=A1
ADDR_H =0;
ADDR_L =0;
info_length = 80; //
STA =1;
x = 0;
}
void write_512fram(void) //xie 512 ge fram
{
unsigned char i;
unsigned int l;
for(i=0;i<40;i++){
l = sys_con[i];
sys_con_temp[i*2] = (unsigned char)sys_con[i];
sys_con_temp[i*2+1] = (unsigned char)(l>>8);
}
SMB0CN_INIT();
BYTE_NUMBER=2;
COMMAND=(0xA0|0x00); //CS ADDR=10100000=A0
COMMANDR=0xa0;
ADDR_H =0;
ADDR_L =0;
info_length = 80; //
NUMBER = 0;
i2c_mangflg = 1;
STA =1;
}
//--------------------------------------------------------------------
// SMB0CN的初始化
//*********************************//
void SMB0CN_INIT(void)
{
SMB0CN =0x44 ; //ENABLE SMBUS,应答周期发ASK 01000100
EIE1 |=0x02; //扩展中断允许;允许SMBUS中断
}
//***********************************//
//SCL时钟频率设置的初始化
//***********************************//
void SMBUS0CR_INIT(void)
{
SMB0CR = 0xe0; //////11100000 时钟速率每隔1.446us产生一次低电平
///////每隔1.537us产生高电平
write_512framflg=0;
}
//********************************************//
//WRITE A BLOCK TO EEPROM24C64
//*******************************************//
//***************************************//
//***************************************//
//**********************************//
//READ A BLOCK FORM EEPROM
//**********************************//
//**********************************//
//中断处理子程序
//**********************************//
void SMBUS0_SI(void) interrupt 7
{
unsigned char i;
unsigned int l;
switch(SMB0STA) ////////SMB0STA状态寄存器
{ case 0x08:
SMB0DAT = COMMAND; //起始条件已发出,写控制字节
STA=0;
break;
case 0x10:
SMB0DAT = COMMANDR;
STA =0;
COMMANDR = 0;
break;
case 0x18:
SMB0DAT=ADDR_H ;//ADDR_H; //从地址+w已发出,并收到ACK
break;
case 0x20: //nack
STO=1;
STA=1;
break;
case 0x28:{
//数据字节已发出,收到ACK
switch(BYTE_NUMBER)
{
case 0: //数据已发送完毕
STO=1;
BUSY=0; //释放总线
i2c_mangflg = 0;
break;
case 2:
SMB0DAT =ADDR_L; //说明只发送了ADDR_H
BYTE_NUMBER--;
break;
case 1: //说明ADDR_L已发送
if((COMMANDR&0x01)==1)//读指定单元
{
STA =1;
}
else{
SMB0DAT =sys_con_temp[NUMBER];
NUMBER = NUMBER + 1;
if(NUMBER == info_length){
BYTE_NUMBER--;
NUMBER = 0;
//WDTCN = 0xA5; //使能WDT
}
}
break;
default: //数据已发送完毕
STO=1;
BUSY=0; //释放总线
}
}
break;
case 0x30:
STO =1; //smbus停止标志
STA =1; //smbus起始标志
break;
case 0x40:
AA =1;
break;
case 0x50:
sys_con_temp[x] = SMB0DAT;
x=x+1;
if(x==(info_length-1))
{
AA=0; /////smbus确认标志
}
break;
case 0x58:
sys_con_temp[x] = SMB0DAT;
x=x+1;
if(x==info_length){
BUSY =0;
STO =1;
//WDTCN = 0xA5; //使能WDT
for(i=0;i<40;i++){
l = (unsigned int)(sys_con_temp[i*2+1])<<8;
l = l + (unsigned int)(sys_con_temp[i*2]);
sys_con[i] = l;
}
TH1 = -(SYSCLK/sys_con[2]/16/12);
for(i=0;i<6;i++)
{
yc_mes_real[128+i*2] = sys_con[17+i*2];
yc_mes_real[128+i*2+1]=sys_con[17+i*2+1];
}
i2c_mangflg = 0;
}
break;
default:
STO =1;
BUSY =0;
break;
}
SI =0; //CLEAR SI smbus中断
}
/////////// 读写FRAM ////////////
void Read_512fram(void)
{
SMB0CN_INIT();
BYTE_NUMBER=2;
COMMAND=(0xA0|0x00); //CS ADDR=10100000=A0
COMMANDR=(0xA0|0x01); //CS ADDR=10100001=A1
ADDR_H =0;
ADDR_L =0;
info_length = 80; //
STA =1;
x = 0;
}
void write_512fram(void) //xie 512 ge fram
{
unsigned char i;
unsigned int l;
for(i=0;i<40;i++){
l = sys_con[i];
sys_con_temp[i*2] = (unsigned char)sys_con[i];
sys_con_temp[i*2+1] = (unsigned char)(l>>8);
}
SMB0CN_INIT();
BYTE_NUMBER=2;
COMMAND=(0xA0|0x00); //CS ADDR=10100000=A0
COMMANDR=0xa0;
ADDR_H =0;
ADDR_L =0;
info_length = 80; //
NUMBER = 0;
i2c_mangflg = 1;
STA =1;
}
//--------------------------------------------------------------------
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
意法半导体(中国)投资有限公司
2023-06-12 广告
2023-06-12 广告
STM32F103是一款高性能的嵌入式芯片,由意法半导体(STMicroelectronics)公司生产。它是STM32系列芯片之一,具有紧凑、低功耗、高性能等特点,被广泛应用于嵌入式系统中。STM32F103的主要特点包括:1. 集成了A...
点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
展开全部
你要是怀疑没有写进去,你可以用示波器看看fm24c02有没有反馈ACK信号,即8个数据位后把SDA拉低。假如有的再看看读程序是否有问题。
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
很明显你没有写到寄存器中,看看时序是否正确!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询