单片机 > 单片机程序设计 > 详情

stm32普通IO口模拟iic时序

发布时间:2024-07-08 发布时间:
|

1,用stm32的普通IO口模拟iic时序,可以用较少的IO口实现iic功能,在实际使用中有很大优势。

2,stm32的IO可以设置为推挽,开漏输出模式,在开漏输出下,如果带上拉电阻,则可以双向传输数据,

如输出1(PCout()=1),从它的输入引脚可以读出状态(PCin()),

这样在不需要配置输入,输出模式,就可以实现iic数据线的写和读。

程序实现过程:

#define AT_IIC_SCL          PCout(12)    

#define AT_IIC_SDA          PCout(11)    

#define AT_IIC_SDA_READ     PCin(11)

void I2cIoInit()

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );  

   

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_SetBits(GPIOC,GPIO_Pin_12|GPIO_Pin_11);

}

void I2cStart()

{

    AT_IIC_SDA=1;

    AT_IIC_SCL=1;

    delay_us(4);

    AT_IIC_SDA=0;      

    delay_us(4);

    AT_IIC_SCL=0;      

}

void I2cStop()

{

    AT_IIC_SCL=0;

    AT_IIC_SDA=0;      

    delay_us(4);

    AT_IIC_SCL=1;

    AT_IIC_SDA=1;      

    delay_us(4);

}

uint8_t I2cWaitAck()

{

    uint8_t errTimes=0;

    AT_IIC_SDA=1;

    delay_us(1);

    AT_IIC_SCL=1;

    delay_us(1);

    while(AT_IIC_SDA_READ)

    {

        errTimes++;

        if(errTimes>250)

        {

            I2cStop();

            return 1;

        }

    }

    AT_IIC_SCL=0;      

    return 0;

}

void I2cAck()

{

    AT_IIC_SCL=0;

    AT_IIC_SDA=0;

    delay_us(2);

    AT_IIC_SCL=1;

    delay_us(2);

    AT_IIC_SCL=0;

}

void I2cNoAck()

{

    AT_IIC_SCL=0;

    AT_IIC_SDA=1;

    delay_us(2);

    AT_IIC_SCL=1;

    delay_us(2);

    AT_IIC_SCL=0;

}

void I2cSendByte(uint8_t txdata)

{

    uint8_t t;

    AT_IIC_SCL=0;          

    for(t=0;t<8;t++)

    {

        if((txdata&0x80)>>7)

        {

            AT_IIC_SDA=1;

        }

        else

        {

            AT_IIC_SDA=0;

        }

        txdata<<=1;

        delay_us(2);        

        AT_IIC_SCL=1;

        delay_us(2);

        AT_IIC_SCL=0;

        delay_us(2);

    }

}

uint8_t I2cReadByte(uint8_t ack)

{

    unsigned char i,receive=0;

    for(i=0;i<8;i++ )

    {

        AT_IIC_SCL=0;

        delay_us(2);

        AT_IIC_SCL=1;

        receive<<=1;

        if(AT_IIC_SDA_READ)

        {

            receive++;

        }

        delay_us(1);

    }

    if (!ack)

    {

        I2cNoAck();    

    }

    else

    {

        I2cAck();      

    }

    return receive;

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR单片机Atmega16的ADC采集数码管显示仿真程序