这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模拟iic的时序要求可能更高一点所以在原子哥的iic程序上做了修改,代码测验后已经不会死机,做个笔记,保存一下。
#include "myiic.h" #include "delay.h" //初始化IIC void IIC_Init(void) { 19 GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟 //GPIOB10,B11初始化设置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 IIC_SCL=; IIC_SDA=; } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA=; delay_us(); IIC_SCL=; delay_us(); IIC_SDA=;//START:when CLK is high,DATA change form high to low delay_us(); IIC_SCL=;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL=; delay_us(); IIC_SDA=;//STOP:when CLK is high DATA change form low to high delay_us(); IIC_SCL=; delay_us(); IIC_SDA=;//发送I2C总线结束信号 delay_us(); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=; SDA_IN(); //SDA设置为输入 IIC_SDA=; delay_us(); IIC_SCL=; delay_us(); while(READ_SDA) //可能可以把数搞大点 { ucErrTime++; ) { IIC_Stop(); ; } } IIC_SCL=;//时钟输出0 ; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL=; delay_us(); SDA_OUT(); IIC_SDA=; delay_us(); IIC_SCL=; delay_us(); IIC_SCL=; } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL=; delay_us(); SDA_OUT(); IIC_SDA=; delay_us(); IIC_SCL=; delay_us(); IIC_SCL=; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=;//拉低时钟开始数据传输 ;t<;t++) { IIC_SDA=(txd&; txd<<=; delay_us(); IIC_SCL=; delay_us(); IIC_SCL=; delay_us(); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned ; SDA_IN();//SDA设置为输入 ;i<;i++ ) { IIC_SCL=; delay_us(); IIC_SCL=; receive<<=; if(READ_SDA) receive++; delay_us(); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; }
空行间隔的为新增延时,和注释不一样的为改了的延时