在微控制器中SPI,I2C是常用的挂接外设的总线,我们对他们的如果没有仔细研究的话我们对他们的认识基本就是串行,线少(I2C两根SCL SDA,SPI 单向3根双向4根 SCK MOSI MISO CS/LD ),多外设(SPI 可以并联也可以级联,I2C基本是随便接,地址不冲突即可),但是实际上这两种总线原理上还有有很大区别的,在微控制器上的操作及与程序控制流程也是完全不一样的。
SPI的原理 是主控使用SCLK 线,在SCLK信号的边沿 将数据寄存器的数据通过 MOSI一位一位的移出到 设备中 ,同时设备的寄存器也将数据在SCLK边沿的驱动下将数据通过MISO线一位一位的移出到主控中,所以SPI总线中读写是同时进行的,没有单独的读也没有单独的写,在微控制器端无论想读还是想写就是将数据填到DR存寄器中,MCU即自动开始传输,等待RXNE BUSY TXE等信号置位便完成一个读或写操作。SPI状态也只有忙和不忙两种状态。
I2C总线与SPI完全不同,因为比SPI少了一根数据线和一根同步/片选线,I2C的内核涉及到状态机的问题,这也就导致了I2C的操作不像SPI那么简单。
串行通信必须有同步过程,SPI通过一根CS/LD数据线解决,I2C通过 生产START信号解决
器件的选通,SPI使用不同的CS线控制选通即可,I2C采用START+写入选通地址解决数据的传输与方向,SPI的MOSI MISO是固定线,无方向概念,I2C在根据选通地址的最低位决定是读还是写数据的确认与中止,SPI无确认,想中止拉高CS线即可,I2C需接收方使用ACK确认数据总线仲裁,SPI为固定主从不需要仲裁,I2C检查总线电平因为这些不同I2C在总线控制上比SPI要复杂的多在STM32上I2C常遇到的问题与解决办法,主要针对STM32做为主机方式
问题1: BUSY位被置位,即始使RESET后初始化总线后即被置位 不能发也不能收
出现原因:外设的不完整通信将SDA线的电平拉底,I2C内核认为总线被占用,除非总线被释放,否则拒绝操作总线(等着AT24系列自动释放总线?连RESET管脚都没有,呵呵吧)
解决办法:使用IO方式强行接管总线,以电平方式发出STOP信号 迫使设置释放总线,具体操作如下初始化前将将SCL SDL置成GPIO OUT_PP模式,拉底SCL,延时,拉低SDA,延时,抬高SCL,延时,抬高SDA 此时SCL SDA全为高电平,重新设定GPIO为ALT-OD模式再继续执行初始化I2C总线操作即可
问题2:在读取时多读一次数据
出现原因:未能正确控制NACK,与STOP位正确生成
解决办法:按手册要求,在倒数第2字节读取前便设置NACK位与STOP位,
LL_I2C_AcknowledgeNextData(I2Cx,LL_I2C_NACK);
LL_I2C_GenerateStopCondition(I2Cx);
问题3:如何检测AT24系列的E2ROM是否响应写操作
按手册要求在向AT24写数据过程中,写操作后面的STOP会使AT24进入内部写状态,判断是否写完成的依据是检测设备会不会在响应新的写操作,流程是START->ADDR->ACK?RESTART:STOP,可以按以下方法进行检测
写START->写 ADDR->直到检测到ADDR或AF被置位
如果AF被置位,清除AF重新执行START
如果ADDR被置位 表示操作完成,发送STOP退出查询
注意不要用STM32中的头文件中定义的位进行比较
头文件定义如下
#define I2C_FLAG_AF 0x00010400U
#define I2C_FLAG_ADDR 0x00010002U
多出的那个高位1会使 如下的失效
flag = (I2C1->SR1) | (I2C1->SR2 <<16);
if(flag & I2C_FLAG_AF) ......
最终的AT24 Pool函数如下
UINT8 I2C_Poll(UINT8 id,UINT8 devaddr)
{
I2C_WaitBus(id);
while(1)
{
I2C_Start(id);
LL_I2C_TransmitData8(I2Cx,devaddr & 0xfe);
GPIOB->BRR = GPIO_PIN_0;
while(1){
if(LL_I2C_IsActiveFlag_ADDR(I2Cx)) break;
if(LL_I2C_IsActiveFlag_AF(I2Cx)) break;
}
if(LL_I2C_IsActiveFlag_AF(I2Cx))
{
LL_I2C_ClearFlag_AF(I2Cx);
continue;
}
break;
}
LL_I2C_ClearFlag_ADDR(I2Cx);
I2C_Stop(id);
}
上一篇:STM32常用通信——USART,IIC,SPI,CAN
下一篇:STM32小白入门(第12天)---I2C协议
推荐阅读最新更新时间:2024-11-12 20:25