I2C求助贴,改的官网范例,读出的都是ff
网上买的8a8k64s4a12,和ds3231的模块,上面还有一个24c32,P14接的SDA,P15接SCL,VCC和GND都是在U8W连过来的,我想读写24c32成功了再学3231,可是读出来都是0xff,我知道看别人的原代码很乱,但有人能指点一下吗?#include <STC8.h>
#include <stdio.h>
#include <intrins.h>
unsigned char flag,Dat24c32H,Dat24c32L;
bit busy;
sbit SDA=P1^4;
sbit SCL=P1^5;
void UartInit(void) //9600bps@24.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0xE8; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
EA=1; //打开总中断
}
void delayxms(unsigned int xms) //延时
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=1350;j>0;j--);
}
void I2C_Isr() interrupt 24
{
_push_(P_SW2);
P_SW2|=0x80;
if (I2CMSST&0x40)
{
I2CMSST&=~0x40; //清中断标志
busy = 0;
}
_pop_(P_SW2);
}
void Start()
{
busy=1;
I2CMSCR=0x81; //发送START命令
while(busy);
}
void SendData(char dat)
{
I2CTXD=dat; //写数据到数据缓冲区
busy=1;
I2CMSCR=0x82; //发送SEND命令
while(busy);
}
void RecvACK()
{
busy=1;
I2CMSCR=0x83; //发送读ACK命令
while(busy);
}
char RecvData()
{
busy=1;
I2CMSCR=0x84; //发送RECV命令
while(busy);
return I2CRXD;
}
void SendACK()
{
I2CMSST=0x00; //设置ACK信号
busy = 1;
I2CMSCR=0x85; //发送ACK命令
while(busy);
}
void SendNAK()
{
I2CMSST=0x01; //设置NAK信号
busy=1;
I2CMSCR=0x85; //发送ACK命令
while(busy);
}
void Stop()
{
busy=1;
I2CMSCR=0x86; //发送STOP命令
while(busy);
}
void Delay()
{
int i;
for (i=0; i<3000; i++)
{
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}
}
void main()
{
P_SW2 = 0x80;
UartInit();
I2CCFG = 0xe0; //使能I2C主机模式
I2CMSST = 0x00;
Start(); //发送起始命令
SendData(0xa0); //发送设备地址+写命令
RecvACK();
SendData(0x00); //发送存储地址高字节
RecvACK();
SendData(0x01); //发送存储地址低字节
RecvACK();
SendData(0x12); //写测试数据1
RecvACK();
SendData(0x78); //写测试数据2
RecvACK();
Stop(); //发送停止命令
Delay(); //等待设备写数据
Start(); //发送起始命令
SendData(0xa0); //发送设备地址+写命令
RecvACK();
SendData(0x00); //发送存储地址高字节
RecvACK();
SendData(0x01); //发送存储地址低字节
RecvACK();
Start(); //发送起始命令
SendData(0xa1); //发送设备地址+读命令
RecvACK();
Dat24c32H=RecvData(); //读取数据1
SendACK();
Dat24c32L=RecvData(); //读取数据2
SendNAK();
Stop(); //发送停止命令
P_SW2 = 0x00;
while (1)
{
TI=1;
printf("READ Dat24C32H=%bx Dat24C32L=%bx \n",Dat24c32H,Dat24c32L);
while(!TI);
delayxms(2000);
}
}
你需要确认你测试板上AT24C32的A0、A1、A2这3个脚的连接方法
是接GND还是接VCC,然后对程序中的设备地址进行相应的修改
(范例程序默认这3个脚接地) zhp 发表于 2022-11-26 20:15
你需要确认你测试板上AT24C32的A0、A1、A2这3个脚的连接方法
是接GND还是接VCC,然后对程序中的设备地址进 ...
A0A1A2都是悬空的,我在程序里加上读3231的秒位和分位的语句,3231数据读出来了,难道是我24C32写的不对吗? z9051638 发表于 2022-11-26 22:00
A0A1A2都是悬空的,我在程序里加上读3231的秒位和分位的语句,3231数据读出来了,难道是我24C32写的不对 ...
DS3231能正确读写,说明I2C控制程序没问题
读写AT24C32失败,很大可能是设备地址不匹配
A0、A1、A2悬空,那要看芯片内部是否在这3脚有上拉或者下拉
你可以用万用表测量一下这3个教悬空时的电平
如果是高电平,则需要修改代码中的设备地址
不过一般设计电路时,这3个脚一定是外部接GND或者VCC,
进行地址选择,悬空设计倒是很少见 是的,如你所说,悬空不行,人家设计的本意可能是让自己焊硬件地址,先谢谢指点,我的程序中我还有点不明白的地方,上图,望帮解答一下 zhp 发表于 2022-11-26 22:22
DS3231能正确读写,说明I2C控制程序没问题
读写AT24C32失败,很大可能是设备地址不匹配
A0、A1、A2悬空, ...
是的,如你所说,悬空不行,人家设计的本意可能是让自己焊硬件地址,先谢谢指点,我的程序中我还有点不明白的地方,上图,望帮解答一下
Start();
SendData(0xd0);
RecvACK();
SendData(0x00);
RecvACK();
Start();
SendData(0xd1);
RecvACK();
Dat3231sec00=RecvData();
//SendACK(); 这两个SendACK,加上就执行不到下面的printf语句,去掉就正常了,我看范例每个接收后面都加一个啊,这里为什么不行?24c32的这也加了,却没卡住,加在这好像就卡在这里了
Start();
SendData(0xd0);
RecvACK();
SendData(0x01);
RecvACK();
Start();
SendData(0xd1);
RecvACK();
Dat3231min01=RecvData();
//SendACK(); 这两个SendACK,加上就执行不到下面的printf语句,去掉就正常了,我看范例每个接收后面都加一个啊,这里为什么不行?
Start();
SendData(0xd0);
RecvACK();
SendData(0x02);
RecvACK();
Start();
SendData(0xd1);
RecvACK();
Dat3231hour02=RecvData();
SendNAK();
Stop();
// P_SW2 = 0x00;
TI=1;
printf("READ Dat24C32H=%bxDat24C32L=%bxTIME %bx:%bx:%bx\n",Dat24c32H,Dat24c32L,Dat3231hour02,Dat3231min01,Dat3231sec00);
while(!TI);
delayxms(1000);
}
z9051638 发表于 2022-11-27 12:12
是的,如你所说,悬空不行,人家设计的本意可能是让自己焊硬件地址,先谢谢指点,我的程序中我还有点不明 ...
I2C协议中,正常的数据读写都一定是9个数据位
读取数据后,必须回一个ACK或者NAK,所以你的这段代码应该是没问题的
我不太了解DS3231,你可以尝试读取最后一笔数据后回NAK看看(正确的I2C协议就是这样的)
我用的是STC8H8K64U自带的IIC功能,也有你的这种情况未解决,我用逻辑分析仪测试了一下。DS时钟和液晶屏都正常工作,就是这个24C32写入读取不出来。。。。我的2张图中就是写入和读取的图形,看着没啥问题,就是写入读取都是FF,我的A0A1A2都接到了上拉电阻。地址是0XAE 我的刚才处理好了,我用的是8H8K64U自带的IIC功能和官方的库修改的,我的模块和你的一样,代码如下:
写入:
void Write_IIC_24c32_command(u16 u16_addr,u8 u8_data)
{
Start();
SendData(0XAE|WRITE_CMD);
RecvACK();
SendData(((u16_addr>>8)&0xff)); //write command
RecvACK();
SendData((u16_addr&0xff));
RecvACK();
SendData(u8_data);
RecvACK();
SendNAK();
Stop();
}
读取:
u8 Read_IIC_24c32_data(u16 u16_addr)
{
u8 reg_data=0;
Start();
SendData(0XAE);
RecvACK();
SendData(u16_addr>>8); //write command
RecvACK();
SendData(u16_addr);
RecvACK();
Start();
SendData(0XAF);
RecvACK();
reg_data = RecvData();
SendNAK();
Stop();
return reg_data;
}
attach://87614.jpg https://www.stcaimcu.com/forum.php?mod=viewthread&tid=12065&extra=&page=11已在这个帖子帮问,到时关注下此贴102楼
页:
[1]
2