21ic问答首页 - 关于GD32f103读取AT24C02总是读不准的疑问
关于GD32f103读取AT24C02总是读不准的疑问
zhczlzhang2022-07-26
如题所示,我第一次使用GD32f103代替stm32,在IIC读取24C02这里出问题了,代码是在stm32上面验证过了,没有问题。为了可移植行,就没有使用GD32的固件库IIC,而是硬件模拟IIC。 但是在GD32上面时,就是存储进去是0x01,读出来是0xc0,写入时0x07,读出来是0x08,写入时0x55,读出来是0x56.
调试了半天,延时之类的都试过了,感觉还是时序的问题,但是手上没有示波器,只能靠猜,请大家帮忙。
IIC_Init();
delay_1ms(1000);
AT24C02_SaveROWSta(AT24C02_row1,0x01);
delay_1ms(1000);
// temp = AT24C02_ReadOneByte(AT24C02_row1);
send_485(AT24C02_ReadOneByte(AT24C02_row1),1);
//以上是在main中的代码
void AT24C02_SaveROWSta(uint8_t row,uint8_t sta1)
{
AT24C02_WriteOneByte(0,0x55); //24C02 地址0 写入0x55
AT24C02_WriteOneByte(row,sta1); //24C02 地址 写入保存的行列的状态
}
void AT24C02_WriteOneByte(unsigned char WriteAddr,unsigned char DataToWrite)
{
IIC_Start(); //开始信号
IIC_Send_Byte(AT24C02_WADDR); //发送器件地址+写操作
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(WriteAddr); //发送写入数据的目的地址
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(DataToWrite); //发送要写入的数据
IIC_Wait_Ack(); //等待应答
IIC_Stop(); //停止信号
Delay_Ms(5); //延迟
}
unsigned char AT24C02_ReadOneByte(unsigned char ReadAddr)
{
unsigned char receive; //定义一个变量用于保存接收到的数据
receive = 0; //清除receive,准备接收数据
IIC_Start(); //IIC开始信号
IIC_Send_Byte(AT24C02_WADDR); //发送24c02器件地址+写操作
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(ReadAddr); //发送需要读数据的地址
IIC_Wait_Ack(); //等待应答
IIC_Start(); //IIC开始信号
IIC_Send_Byte(AT24C02_RADDR); //发送24c02器件地址+读操作
IIC_Wait_Ack(); //等待应答
receive=IIC_Read_Byte(0); //读一字节数据,保存在receive变量中
IIC_Stop(); //停止信号
Delay_Ms(5); //延迟
return receive; //返回读取的数据
}
//以上是24c02中的代码
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t; //定义一个变量用于for循环
SDA_OUT(); //SDA线输出模式
IIC_SCL_L; //SCL拉低,开始数据传输
for(t=0;t<8;t++){ //for循环,一位一位的发送,从最高位 位7开始
IIC_SDA_OUT(((txd&0x80)>>7)); //给SDA数据线
txd<<=1; //左移一位,准备下一次发送
Delay_Us(2); //延时
IIC_SCL_H; //SCL拉高
Delay_Us(2); //延时
IIC_SCL_L; //SCL拉低
Delay_Us(2);
}
}
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i; //定义一个变量用于for循环
unsigned char receive; //定义一个变量用于保存接收到的数据
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL_L;
Delay_Us(2);
IIC_SCL_H;
receive<<=1;
if(READ_SDA)receive++;
Delay_Us(1);
}
if (!ack)
{
SDA_OUT(); //SDA线输出模式
IIC_SDA_H; //时钟脉冲的高电平期间保持稳定的高电平
IIC_SCL_H; //SCL拉高
Delay_Us(2); //延时
IIC_SCL_L; //SCL拉低
}
else
{
SDA_OUT(); //SDA线输出模式
IIC_SDA_L; //时钟脉冲的高电平期间保持稳定的低电平
IIC_SCL_H; //SCL拉高
Delay_Us(2); //延时
IIC_SCL_L; //SCL拉低
IIC_SDA_H; //SDA拉高
}
return receive;
}
//代码基本上就是这样,在stm32中测试没有这个现象,GD32f103中就有了,请大家指点一下。
调试了半天,延时之类的都试过了,感觉还是时序的问题,但是手上没有示波器,只能靠猜,请大家帮忙。
IIC_Init();
delay_1ms(1000);
AT24C02_SaveROWSta(AT24C02_row1,0x01);
delay_1ms(1000);
// temp = AT24C02_ReadOneByte(AT24C02_row1);
send_485(AT24C02_ReadOneByte(AT24C02_row1),1);
//以上是在main中的代码
void AT24C02_SaveROWSta(uint8_t row,uint8_t sta1)
{
AT24C02_WriteOneByte(0,0x55); //24C02 地址0 写入0x55
AT24C02_WriteOneByte(row,sta1); //24C02 地址 写入保存的行列的状态
}
void AT24C02_WriteOneByte(unsigned char WriteAddr,unsigned char DataToWrite)
{
IIC_Start(); //开始信号
IIC_Send_Byte(AT24C02_WADDR); //发送器件地址+写操作
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(WriteAddr); //发送写入数据的目的地址
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(DataToWrite); //发送要写入的数据
IIC_Wait_Ack(); //等待应答
IIC_Stop(); //停止信号
Delay_Ms(5); //延迟
}
unsigned char AT24C02_ReadOneByte(unsigned char ReadAddr)
{
unsigned char receive; //定义一个变量用于保存接收到的数据
receive = 0; //清除receive,准备接收数据
IIC_Start(); //IIC开始信号
IIC_Send_Byte(AT24C02_WADDR); //发送24c02器件地址+写操作
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(ReadAddr); //发送需要读数据的地址
IIC_Wait_Ack(); //等待应答
IIC_Start(); //IIC开始信号
IIC_Send_Byte(AT24C02_RADDR); //发送24c02器件地址+读操作
IIC_Wait_Ack(); //等待应答
receive=IIC_Read_Byte(0); //读一字节数据,保存在receive变量中
IIC_Stop(); //停止信号
Delay_Ms(5); //延迟
return receive; //返回读取的数据
}
//以上是24c02中的代码
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t; //定义一个变量用于for循环
SDA_OUT(); //SDA线输出模式
IIC_SCL_L; //SCL拉低,开始数据传输
for(t=0;t<8;t++){ //for循环,一位一位的发送,从最高位 位7开始
IIC_SDA_OUT(((txd&0x80)>>7)); //给SDA数据线
txd<<=1; //左移一位,准备下一次发送
Delay_Us(2); //延时
IIC_SCL_H; //SCL拉高
Delay_Us(2); //延时
IIC_SCL_L; //SCL拉低
Delay_Us(2);
}
}
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i; //定义一个变量用于for循环
unsigned char receive; //定义一个变量用于保存接收到的数据
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL_L;
Delay_Us(2);
IIC_SCL_H;
receive<<=1;
if(READ_SDA)receive++;
Delay_Us(1);
}
if (!ack)
{
SDA_OUT(); //SDA线输出模式
IIC_SDA_H; //时钟脉冲的高电平期间保持稳定的高电平
IIC_SCL_H; //SCL拉高
Delay_Us(2); //延时
IIC_SCL_L; //SCL拉低
}
else
{
SDA_OUT(); //SDA线输出模式
IIC_SDA_L; //时钟脉冲的高电平期间保持稳定的低电平
IIC_SCL_H; //SCL拉高
Delay_Us(2); //延时
IIC_SCL_L; //SCL拉低
IIC_SDA_H; //SDA拉高
}
return receive;
}
//代码基本上就是这样,在stm32中测试没有这个现象,GD32f103中就有了,请大家指点一下。
赞0
评论
2022-07-26
您需要登录后才可以回复 登录 | 注册