<p>
在STM32的I2C上摔了一跤,测试了官方提供的几个例程和库,都有不同缺陷,也无法弥补:</p><br><p>
1、查询方式,在连续读数据的过程中不能中断</p><br><p>
2、DMA方式类似,在同一DMA中I2C的级别必须最高,否则同1.</p><br><p>
3、中断方式也不能有更高优先级中断I2C,否则同1.</p><br><p>
鉴于以上原因,无奈的口线模拟了I2C。(仅仅代表个人看法,欢迎指正)</p><br><p>
附件中的项目文件已经过测试,为感谢OUR这几年的帮助,先开源这个小程序。</p><br><p>链接: https://pan.baidu.com/s/1by6r7jLqoLJuGR8bl6Sk4A 提取码: jfkn 复制这段内容后打开百度 {MOD}手机App,操作更方便哦</p><p><br></p>
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
#define Set_24XXX_SDA(void) {PIN_SDA=1;}
#define Clr_24XXX_SDA(void) {PIN_SDA=0;}
#define Get_24XXX_SDA(void) {PIN_SDA;}
#define Set_24XXX_SCL(void) {PIN_SCL=1;}
#define Clr_24XXX_SCL(void) {PIN_SCL=0;}
/****************************************/
static void nop(void)
{ asm("nop");
asm("nop");
asm("nop");
}
/****************************************/
static void ProgrameDelay(int16u x)
{ while(x--);
}
/****************************************/
static void Start(void)
{ Clr_24XXX_SCL();
Set_24XXX_SDA();
Set_24XXX_SCL();
nop();
Clr_24XXX_SDA();
nop();
Clr_24XXX_SCL();
Set_24XXX_SDA();
}
/****************************************/
void Stop(void)
{ Clr_24XXX_SCL();
Clr_24XXX_SDA();
Set_24XXX_SCL();
nop();
Set_24XXX_SDA();
nop();
Clr_24XXX_SCL();
}
/****************************************/
static int8u GetAck(void)
{ int8u ack;
Clr_24XXX_SCL();
Set_24XXX_SDA();
Set_24XXX_SCL();
nop();
ack= Get_24XXX_SDA();
Clr_24XXX_SCL();
return ack;
}
/****************************************/
static void Ack(void)
{ Clr_24XXX_SDA();
Set_24XXX_SCL();
nop();
Clr_24XXX_SCL();
nop();
Set_24XXX_SDA();
}
/****************************************/
static void Nack(void)
{ Set_24XXX_SDA();
Set_24XXX_SCL();
nop();
Clr_24XXX_SCL();
}
/****************************************/
static void SendByte(int8u sendbyte)
{ int8u i;
for(i=8;i>0;i--)
{ Clr_24XXX_SCL();
if(sendbyte & 0x80)
{ Set_24XXX_SDA();
}
else
{ Clr_24XXX_SDA();
}
sendbyte<<= 1;
Set_24XXX_SCL();
nop();
}
Clr_24XXX_SCL();
}
/****************************************/
static int8u ReceiveByte(void)
{ int8u resualt,i=8;
Clr_24XXX_SCL();
while(i--)
{ Set_24XXX_SCL();
resualt= (resualt<<1)|Get_24XXX_SDA();
Clr_24XXX_SCL();
}
return resualt;
}
/****************************************/
int8u Rw24XXX(int16u address,int8u *buf,int16u number,int8u control)
{ int16u i;
int8u *ptr;
int8u error=1;
int8s time=3;
while(1)
{ if(--time < 0) break;
ptr= buf;
Start();
SendByte(control&0xfe); if(GetAck())continue;
SendByte(address>>8); if(GetAck())continue; //如果地址小于2字节的,如24c02,04,16,32可以屏蔽此句
SendByte(address); if(GetAck())continue;
if(!(control&0x01))
{ i= number;
error= 0;
while(i--)
{ SendByte(*ptr++); if(!GetAck())continue;
error= 1;
break;
}
if(error == 1) continue;
break;
}
else
{ Start();
SendByte(control); if(GetAck())continue;
while(--number)
{ *ptr++= ReceiveByte();
Ack();
}
*ptr= ReceiveByte();
Nack();
error= 0;
break;
}
}
Stop();
if(!(control&0x01))
{ ProgrameDelay(1000);
}
return error;
}
/****************************************/
一周热门 更多>