stm32软件模拟IIC读取PX4FLOW光流传感器数据

这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模拟iic的时序要求可能更高一点所以在原子哥的iic程序上做了修改,代码测验后已经不会死机,做个笔记,保存一下。

  1 #include "myiic.h"
  2 #include "delay.h"
 15
 16 //初始化IIC
 17 void IIC_Init(void)
 18 {
 19   GPIO_InitTypeDef  GPIO_InitStructure;
 20
 21    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
 22
 23   //GPIOB10,B11初始化设置
 24    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
 25    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
 26    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
 27    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
 28    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
 29    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
 30    IIC_SCL=1;
 31    IIC_SDA=1;
 32 }
 33 //产生IIC起始信号
 34 void IIC_Start(void)
 35 {
 36     SDA_OUT();     //sda线输出
 37     IIC_SDA=1;
 38
 39     delay_us(1);
 40
 41     IIC_SCL=1;
 42     delay_us(2);                                                                                //4
 43     IIC_SDA=0;//START:when CLK is high,DATA change form high to low
 44     delay_us(2);                                                                                    //4
 45     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
 46 }
 47 //产生IIC停止信号
 48 void IIC_Stop(void)
 49 {
 50     SDA_OUT();//sda线输出
 51     IIC_SCL=0;
 52
 53     delay_us(1);
 54
 55     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 56     delay_us(2);                                                                                    //4
 57     IIC_SCL=1;
 58
 59     delay_us(1);
 60
 61     IIC_SDA=1;//发送I2C总线结束信号
 62     delay_us(2);                                                                           //4
 63 }
 64 //等待应答信号到来
 65 //返回值:1,接收应答失败
 66 //        0,接收应答成功
 67 u8 IIC_Wait_Ack(void)
 68 {
 69     u8 ucErrTime=0;
 70     SDA_IN();      //SDA设置为输入
 71     IIC_SDA=1;
 72     delay_us(1);                                                                        //1
 73     IIC_SCL=1;
 74     delay_us(1);                                                                        //1
 75     while(READ_SDA)                 //可能可以把数搞大点
 76     {
 77         ucErrTime++;
 78         if(ucErrTime>250)
 79         {
 80             IIC_Stop();
 81             return 1;
 82         }
 83     }
 84     IIC_SCL=0;//时钟输出0
 85     return 0;
 86 }
 87 //产生ACK应答
 88 void IIC_Ack(void)
 89 {
 90     IIC_SCL=0;
 91
 92     delay_us(1);
 93
 94     SDA_OUT();
 95     IIC_SDA=0;
 96     delay_us(2);                                                                    //2
 97     IIC_SCL=1;
 98     delay_us(2);                                                                    //2
 99     IIC_SCL=0;
100 }
101 //不产生ACK应答
102 void IIC_NAck(void)
103 {
104     IIC_SCL=0;
105
106     delay_us(1);
107
108     SDA_OUT();
109     IIC_SDA=1;
110     delay_us(2);                                                                    //2
111     IIC_SCL=1;
112     delay_us(2);                                                                    //2
113     IIC_SCL=0;
114 }
115 //IIC发送一个字节
116 //返回从机有无应答
117 //1,有应答
118 //0,无应答
119 void IIC_Send_Byte(u8 txd)
120 {
121     u8 t;
122     SDA_OUT();
123     IIC_SCL=0;//拉低时钟开始数据传输
124     for(t=0;t<8;t++)
125     {
126         IIC_SDA=(txd&0x80)>>7;
127         txd<<=1;
128         delay_us(2); //对TEA5767这三个延时都是必须的  //2
129         IIC_SCL=1;
130         delay_us(2);                                                                        //2
131         IIC_SCL=0;
132         delay_us(2);                                                                        //2
133     }
134 }
135 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
136 u8 IIC_Read_Byte(unsigned char ack)
137 {
138     unsigned char i,receive=0;
139     SDA_IN();//SDA设置为输入
140     for(i=0;i<8;i++ )
141     {
142         IIC_SCL=0;
143         delay_us(2);                                                             //2
144         IIC_SCL=1;
145         receive<<=1;
146         if(READ_SDA)
147             receive++;
148         delay_us(2);                                                                        //1
149     }
150     if (!ack)
151         IIC_NAck();//发送nACK
152     else
153         IIC_Ack(); //发送ACK
154     return receive;
155 }

空行间隔的为新增延时,和注释不一样的为改了的延时

时间: 2024-08-01 10:43:45

stm32软件模拟IIC读取PX4FLOW光流传感器数据的相关文章

px4flow通过iic读取具体寄存器数据程序

底层通信用了昨天写好的iic,今天结合官方资料成功读出所有指定寄存器的数据附上源码 include.h主要包括了一些stm32 IO控制的宏定义,具体参考正点原子所有例程中都有的sys.h头文件 inc #ifndef __PX4FLOW_H #define __PX4FLOW_H #include "include.h" //器件地址 #define PX4FLOW_ADDR 0x42 //寄存器宏定义,如果是2字节一个数据地址指的低字节位,高字节是低字节地址后一位,组合起来就是完整

STM32 软件复位并模拟USB拔插

最近做了个USB跟上位机的通信,需要软件对MCU进行复位,复位后如果USB没有拔插,PC就不会重新枚举USB为了解决这个问题,我做了软件复位跟,软件模拟USB拔插. 这里我用的是HAL库的软件复位,复位前先把中断关掉,再复位,代码如下: __set_FAULTMASK(1); //关中断 NVIC_SystemReset(); //复位 至于怎么实现模拟USB拔插,则只需要在USB初始化前把PA12进行一个拉低--延时--拉高的操作即可,一般PC机可以通过检查USB的D+引脚来判断USB是否有变

002.光流传感器(ADNS0380版)使用说明

先放广告,以下是光流传感器购买地址(全网最低价并且唯一提供代码支持的): https://item.taobao.com/item.htm?spm=a230r.1.14.63.j2eDn3&id=541014211123&ns=1&abbucket=12#detail 如果模块直接使用在APM飞控上请看下文标题一内容,如果使用传感器作为二次开发请看下文标题二内容. 一.APM2.5与传感器模块连接图 二.提供的代码请按以下连线使用,传感器与stm32连接: GND    ---- 

STM32F10x_SPI(硬件接口 + 软件模拟)读写Flash(25Q16)

Ⅰ.写在前面 SPI(Serial Perripheral Interface)串行外设通信接口,主要实现设备(主从)之间的通信.硬件上由CS.SCK.MISO.MOSI四根通信线连接而成.关于SPI更多介绍不再详细描述,本文主要以STM32F103为主机.W25Q16为从机进行SPI通信实验. 本文将提供STM32硬件SPI.软件模拟SPI两实例工程代码供大家参考.掌握两种方式的区别. STM32硬件SPI:控制简单.运行效率高.使用方便等. 软件模拟SPI:移植性强,只需要简单修改接口,就能

lpc1788IO口模拟IIC

#ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #include "debugserial.h" //sda 027 scl 028 //IO方向设置 #define IIC1_SDA_IN()  P0dir(27) = 0 #define IIC1_SDA_OUT() P0dir(27) = 1 //IO操作函数 #define IIC1_

用s5pc100的GPIO模拟IIC

转载:http://blog.chinaunix.net/uid-26833883-id-3823530.html 一.硬件连线 先来看看LM75硬件的上的连线: 其中I2C_SDA0是数据线,I2C_SCL0是时钟线,它们分别接到s5pc100的GPD3和GPD4,如下图所示 在模拟IIC的时候,用GPD3引脚发送数据或读取数据,用GPD4引脚提供时钟信号即可. 二.数据结构 由于s5pc100的GPD这一组的引脚很多,不好单独对其中的某一个引脚操作,为了能单独对其中的某一个管脚单独操作,这里

模拟IIC协议时序

IIC是飞利浦公司开发的两线式串行总线,主要应用在单片机和外围电子器件之间的数据通讯. IIC总线优点是节约总线数,稳定,快速,是目前芯片制造上非常流行的一种总线,大多数单片机已经片内集成了IIC总线接口,无需用户自己模拟,只需配置相关寄存器即可使用,但是,为了更好地理解IIC总线协议,可以自行按照IIC时序图进行模拟,加深理解. IIC总线有两条串行线,其一是时钟线SCK,其二是数据线SDA. 在寻常的应用之中,单片机常常作为主机,外围器件作为从机使用. 每一个从机器件都拥有唯一的一个地址,这

应用PIC16F1938中IIC读取LM75A温度

一.概述 LM75A是一个高精度温度传感器,精度高达0.125℃,可以采集的温度范围是-55℃~125℃.PIC16F1938可以通过IIC通信方式对LM75A里面的温度寄存器直接读取,并可设置相关的配置寄存器.每个LM75A的地址信号前四位是一样的(由不同生产厂家决定1001),有三位可选的逻辑地址管脚(A0,A1,A2),因此IIC总线上可以支持同时挂载8个LM75A芯片.LM75A有不同的工作模式,正常模式下是监控环境温度,通过IIC总线读取:OS输出模式有两种可选的工作模式:OS比较模式

第二天:SLAM智能小车DIY乐趣-小车控制stm32软件基础

SLAM智能小车DIY乐趣-小车控制stm32软件基础 ####写在前面#### 前面介绍了小车控制stm32硬件基础,本文就来介绍配套的小车控制stm32软件基础.关于stm32开发相关的基础知识这里就不多说了,有需要的小伙伴可以查阅相关资料进行学习,这里重点从小车控制项目入手,直接进行跟实际需求相关的开发.本文主要内容: 1) 电机控制 2) 编码器数据读取 3) 串口数据收发 4) 电机速度PID控制 5) 周期性控制 6) 小车控制软件整体框图 ####正文#### 1.电机控制 电机控