stm32 iic提问:
cSendByte += cSendByte, 相当于cSendByte乘2,也就相当于cSendByte左移一位,我觉得直接用位移运算可能效率更高一些: cSendByte <<= 1。
cSendByte & 0x80,取的就是cSendByte的最高位, I2C串行发送是从最高位开始,发送完后,左移一位,下一位变成了最高位,就可以发送下一位了。
本文参考了网上的博文,并加以归纳总结,帮助新手从入门到放弃 。
提示:以下是本篇文章正文内容
根据参考资料,STM32 IIC问题指的是使用STM32的软件模拟IIC驱动时出现的问题。具体来说,就是在通讯的不同阶段,需要对状态寄存器(SR1和SR2)的不同数据位写入参数,通过读取这些寄存器标志来了解通讯状态。同时,还需要了解IIC设备的定义,以及发送数据的过程。如果出现问题,可以结合参考资料中提供的代码实现,进行排查和修复。
具体解决方案如下:
typedef struct {
const i2c_bus_t *bus; /* IIC设备使用的总线 */
uint8_t addr; /* IIC设备的地址向左偏移一位 */
} i2c_device_t;
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;
delay_ms(1);
}
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
IIC_SCL=0;
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
uint8_t IIC_Read_Byte(uint8_t ack)
{
unsigned char i,receive=0;
SDA_IN();
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}