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;
}
『本文转载自网络,皇冠最新app版本的版权归原作者所有,如有侵权请联系删除』