I2C(IIC)例子程序为何不能工作
我用8H8K64U做I2C主机(11.0592M),8G2K64S4(24M)做从机,准双向口,直接P1.4P1.5连接,共地GND,2个板子各自独立5V供电,C程序完全按照说明书程序,但是貌似无法工作,是什么原因呢,可能的原因罗列:1、主机速度 I2CCFG = 0xe0; //这个速度是不是有问题? speed = Fosc / 2 / (2 * 32 + 4) = Fosc / 136
从机速度应该设置无效,但是看到是 I2CCFG = 0x81; //I2C speed = Fosc / 2 / (2 * 1 + 4) = Fosc /12
2、没有设置上拉电阻,但是例子程序里也是准双向口设置
有没有谁碰到过类似问题
在线等待中……谢谢
本帖最后由 海盗克里斯 于 2024-6-27 19:04 编辑
补充:8G2K64S4如果改成11.0592M烧录,也是一样的,读出来的数据和写入的不一样,主机main代码如下:
sbit SDA = P1^4;
sbit SCL = P1^5;
unsigned char revDat_1, revDat_2;
void Wait(){
while(!(I2CMSST & 0x40));
I2CMSST &= ~0x40;
}
void Start(){
I2CMSCR = 0x01;
Wait();
}
void SendData(char dat){
I2CTXD = dat;
I2CMSCR = 0x02;
Wait();
}
void RecvACK(){
I2CMSCR = 0x03;
Wait();
}
char RecvData(){
I2CMSCR = 0x04;
Wait();
return I2CRXD;
}
void SendACK(){
I2CMSST = 0x00;
I2CMSCR = 0x05;
Wait();
}
void SendNAK(){
I2CMSST = 0x01;
I2CMSCR = 0x05;
Wait();
}
void Stop(){
I2CMSCR = 0x06;
Wait();
}
void Delay3000ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
i = 169;
j = 80;
k = 87;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main(){
bit b = 1;
P0M1= 0x00;
P0M0= 0x00;
P1M1= 0x00;
P1M0= 0x00;
P2M1= 0x00;
P2M0= 0x00;
P3M1= 0x00;
P3M0= 0x00;
P4M1= 0x00;
P4M0= 0x00;
P5M1 = 0x00;
P5M0 = 0x00;
P_SW2 = 0x80;
I2CCFG = 0xe0; //speed = Fosc / 2 / (2 * 32 + 4) = Fosc / 136
I2CMSST = 0x00;
while(1){
Start();
SendData(0x5a); //0x5a: 0: address(0101 101) + 0 for write
RecvACK();
SendData(0x00); //mem address
RecvACK();
SendData(0x12); //test data-1
RecvACK();
SendData(0x78); //test data-2
RecvACK();
Stop();
Start();
SendData(0x5a); //0x5a: 0: address(0101 101) + 0 for write
RecvACK();
SendData(0x00);
RecvACK();
Start();
SendData(0x5b); //0x5b: 1: address(0101 101) + 1 for read
RecvACK();
revDat_1 = RecvData();
SendACK();
revDat_2 = RecvData();
SendNAK();
Stop();
//P_SW2 = 0x00;
if(revDat_1 == 0x12) P20 = 0; else P20 = 1;
if(revDat_2 == 0x78) P21 = 0; else P21 = 1;
Delay3000ms();
P27 = b;
if(b) b = 0;
else b = 1;
}
}
8G2K64S4代码如下,运行以后,主机打狗棒上P20和P21从来没亮过:
sbit SDA = P1^4;
sbit SCL = P1^5;
bit isda;
bit isma;
u8 addr;
u8 xdata buffer;
void i2c_init(){
I2CCFG = 0x81; //I2C speed = Fosc / 2 / (2 * 1 + 4) = Fosc /12 !?
I2CSLADR = 0x5a; // 0x5a: 0: 0 for strict-address mode
I2CSLST = 0x00;
I2CSLCR = 0x78;
isda = 1;
isma = 1;
I2CTXD = buffer;
}
void I2C_Isr() interrupt 24 {
//_push_(P_SW2);
//P_SW2 |= 0x80;
if(I2CSLST & 0x40){
I2CSLST &= ~0x40;
isda = 1;
}
else if(I2CSLST & 0x20){ //meanwhile, SLACKO will be sent to master ?
I2CSLST &= ~0x20;
if(isda){
isda = 0;
}
else if(isma){
isma = 0;
addr = I2CRXD;
I2CTXD = buffer; //since write-mode, will NOT be sent at once, but will be sent next read-cmd?
}
else{
buffer = I2CRXD;
}
}
else if(I2CSLST & 0x10){
I2CSLST &= ~0x10;
if(I2CSLST & 0x02){
I2CTXD = 0xff;
}
else{
I2CTXD = buffer[++addr]; //since read-mode, will be sent next read-cmd ?
}
}
else if(I2CSLST & 0x08){
I2CSLST &= ~0x08;
isda = 1;
isma = 1;
}
//_pop_(P_SW2);
}
void main(){
P_SW2 = 0x80;
i2c_init();
EA = 1;
while(1){
}
}
30块包邮的逻辑分析仪,你值得拥有 是不是线太长了{:5_278:} 用附件的这套I2C主从收发例子试试 乘风飞扬 发表于 2024-6-28 13:24
用附件的这套I2C主从收发例子试试
你这些和我的代码框架都是基本一样的,主从2个是如何用线连接的?你确定是可以用的吗?
或者麻烦你看下我的代码可能有哪些问题? 爱吃西红柿 发表于 2024-6-28 12:19
是不是线太长了
我的线一定小于20cm,我看IIC连线最长200-300MM 乘风飞扬 发表于 2024-6-28 13:24
用附件的这套I2C主从收发例子试试
K,我检查出哪里问题了,是一个超级低级的错误。是看你发的代码过程中突然想到的。无论如何,感谢每一位{:biggrin:} 乘风飞扬 发表于 2024-6-28 13:24
用附件的这套I2C主从收发例子试试
特别感谢{:4_269:}{:4_182:}
页:
[1]
2