关于#stm32#的问题,如何解决?

stm32 iic提问:

img


这两句到底是为了什么呢?
正文长度小于30个字符,请进行修改!

cSendByte += cSendByte, 相当于cSendByte乘2,也就相当于cSendByte左移一位,我觉得直接用位移运算可能效率更高一些: cSendByte <<= 1。
cSendByte & 0x80,取的就是cSendByte的最高位, I2C串行发送是从最高位开始,发送完后,左移一位,下一位变成了最高位,就可以发送下一位了。

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7774005
  • 你也可以参考下这篇文章:STM32 IIC从机的使用注意点,解决IIC发送第一个字节的数据错误
  • 除此之外, 这篇博客: STM32 IIC实验讲解,从入门到放弃。中的 前言 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 本文参考了网上的博文,并加以归纳总结,帮助新手从入门到放弃


    提示:以下是本篇文章正文内容

  • 您还可以看一下 Abel小智老师的嵌入式开发系统学习路线 从基础到项目 精品教程 工程师必备课程 物联网课程中的 STM32如何使用定时器?小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    根据参考资料,STM32 IIC问题指的是使用STM32的软件模拟IIC驱动时出现的问题。具体来说,就是在通讯的不同阶段,需要对状态寄存器(SR1和SR2)的不同数据位写入参数,通过读取这些寄存器标志来了解通讯状态。同时,还需要了解IIC设备的定义,以及发送数据的过程。如果出现问题,可以结合参考资料中提供的代码实现,进行排查和修复。

    具体解决方案如下:

    1. 了解IIC设备的定义,以及使用总线的情况。可以使用以下结构体来定义一个IIC设备:
    typedef struct {
        const i2c_bus_t *bus;       /* IIC设备使用的总线 */
        uint8_t addr;               /* IIC设备的地址向左偏移一位 */
    } i2c_device_t;
    
    1. 实现IIC驱动的代码,包括初始化IIC的IO口、发送起始信号、停止信号,发送ACK应答等。可以使用参考资料中提供的代码实现,如下:
    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;
    }
    
    1. 在使用IIC设备时,需要注意slave_addr的值。如果