I2C主模式busy位一上电就置1,哪位仁兄遇到过,怎么解决 啊!!
初始化程序
void I2C_MasterInit(void)
{
#if 1
PB_ODR |= 0X30; //define SDA, SCL outputs, HiZ, Open drain, Fast
PB_DDR |= 0X30;
PB_CR2 |= 0X30;
CLK_PCKENR1 = 0Xaf; //使能fMASTER时钟与对应外设的连接(仅I2C和TIM2,and TIM1)还有UART1,uart2,spi
#endif
//PC_ODR |= 0X02; //S-CE
I2C_FREQR = 8; //输入外设时钟频率为
I2C_CR1 = 0x00; //禁止I2C外设
I2C_CCRL = 0x28; //100K速度 详细分析见PDF文档
I2C_CCRH = 0x00;
I2C_TRISER = 0x09;
I2C_CR1 |= 0x01; //开启I2C外设
I2C_CR2 |= 0x0c; //当前接收字节返回应答
I2C_OARL = MASTER_ADDRESS; //自身地址
I2C_OARH = 0x40;
}
发送起始位是这样写的
BOOL I2C_Start(void)
{
//while((I2C_SR3 & I2C_SR3_BUSY) && timeout()); // 等待总线空闲
while((I2C_SR3 & I2C_SR3_BUSY)) // Wait while the bus is busy
{
I2C_CR2 |= I2C_CR2_STOP; // STOP=1, generate stop
while((I2C_CR2 & I2C_CR2_STOP)); // wait until stop is performed
}
I2C_CR2 |= I2C_CR2_START; //产生起始位
while(!(I2C_SR1 & I2C_SR1_SB)); //等待START发送完
return TURE;
}
在线调试时程序会一直死在while(I2C_CR2 & I2C_CR2_STOP); // wait until stop is performed
I2C_SR2 的STOP位一直是1不会自动清零,I2C_SR3 的busy位从一上电就为1
我若屏蔽掉 I2C_CR2 |= I2C_CR2_STOP; // STOP=1, generate stop
while((I2C_CR2 & I2C_CR2_STOP)); // wait until stop is performed
这两句话,程序就会一直停在while((I2C_SR3 & I2C_SR3_BUSY)) 等待busy位空闲
用示波器观察SDA和SCL引脚(外接3.3V2.2K的上拉电阻)不管我给它发start还是stop信号,两个引脚一直是高电平
我看别人的列子遇到这种情况时在发stop信号之前要把ACK关掉,因此我在初始化时吧I2C_CR2 |= 0x08; 或I2C_CR2 |= 0x04;
甚至I2C_CR2 |= 0x00;程序都会死在原来的地方
原来I2C连接了两个外设,我现在都去掉了,还是一样的
今天一下午就被这个问题搞过去了,路过的各位仁兄,大哥,大牛,给点思路啊
} |