GPIO软件模拟IIC时序
一、MPU6050中的IIC时序
1.1 START和STOP

SDA和SCL在高电平时,SDA拉低表示START。SCL拉低,表示可以传输数据。
SDA和SCL在低电平时,SDA拉高表示STOP。 SCL拉高,表示传输数据结束。
- /******************************************
- *函数原型: void IIC_Start(void)
- *功能: 产生IIC起始信号
- ******************************************/
- void IIC_Start(void)
- {
- SDA_OUT();
- IIC_SDA=1;
- IIC_SCL=1;
- delay_us(4);
- IIC_SDA=0; //START:when CLK is high,SDA change from hig to low
- delay_us(4);
- IIC_SCL=0; //Ready Transmit or Receive
- }
- /******************************************
- *函数原型: void IIC_Start(void)
- *功能: 产生IIC结束信号
- ******************************************/
- void IIC_Stop(void)
- {
- SDA_OUT();
- IIC_SDA=0;
- IIC_SCL=0;
- delay_us(4);
- IIC_SDA=1; //STOP:when CLK is low,SDA change from low to high
- IIC_SCL=1; //发送I2C总线结束信号
- delay_us(4);
- }
一些的宏定义:
- #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
- #define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
- #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
- #define GPIOB_ODR_Addr (GPIOB_BASE+12)
- #define GPIOB_IDR_Addr (GPIOB_BASE+8)
- #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
- #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
- //驱动接口,GPIO模拟IIC
- //PB7->I2C_SDA
- //PB6->I2C_SCL
- #define SDA_IN() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x80000000;} //上拉输入
- #define SDA_OUT() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x30000000;} //通用推挽输出,不用硬件IIC
- //IO操作函数
- #define IIC_SCL PBout(6)
- #define IIC_SDA PBout(7)
- #define READ_SDA PBin(7)
1.2 ACK和NACK时序图

在START信号后,读取8位的数据,STM32需要对MPU6050发出响应以同步。
第九个SCL时,SCL从低电平变成高电平后,SDA如果是低电平则是ACK,如果是高电平则是NACK。
- /******************************************
- *函数原型: void IIC_Wait_Ack(void)
- *功能: 等待应答信号到来
- *输出; 1,接收应答失败
- 0,接收应答成功
- ******************************************/
- u8 IIC_Wait_Ack(void)
- {
- u8 ucErrTime = 0;
- SDA_IN();
- IIC_SDA=1;
- delay_us(1);
- IIC_SCL=1;
- delay_us(1);
- while(IIC_SDA) //最多等待50us
- {
- ucErrTime++;
- if(ucErrTime>50)
- {
- IIC_Stop();
- return 1;
- }
- delay_us(1);
- }
- IIC_SCL=0; //时钟输出0
- return 0;
- }
- /******************************************
- *函数原型: void IIC_Ack(void)
- *功能: 产生ACK应答信号SDA=0
- ******************************************/
- void IIC_Ack(void)
- {
- IIC_SCL=0;
- SDA_OUT();
- IIC_SDA=0;
- delay_us(1);
- IIC_SCL=1;
- delay_us(1);
- IIC_SCL=0;
- }
- /******************************************
- *函数原型: void IIC_Ack(void)
- *功能: 产生ACK应答信号SDA=0
- ******************************************/
- void IIC_NAck(void)
- {
- IIC_SCL=0;
- SDA_OUT();
- IIC_SDA=1;
- delay_us(1);
- IIC_SCL=1;
- delay_us(1);
- IIC_SCL=0;
- }
1.3 MPU6050写入时序



写时序的步骤:START+(MPU6050地址+W)+等待ACK+寄存器地址+等待ACK+写入的数据+等待ACK+STOP。
读时序的步骤:START+(MPU6050地址+W)+等待ACK+寄存器地址+START+读取数据+ACK响应+STOP。
- /****************************************************
- *函数原型: u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8 *data)
- *功能: 将多个字节写入指定设备 指定寄存器
- *输入: dev 目标设备地址
- * reg 寄存器地址
- * length 要写的字节数
- * *data 将要写的数据的首地址
- *返回: 返回是否成功,1成功
- ****************************************************/
- u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8 *data)
- {
- u8 count = 0;
- IIC_Start();
- IIC_Send_Byte(dev); //发送写命令
- IIC_Wait_Ack();
- IIC_Send_Byte(reg); //发送写入的地址
- IIC_Wait_Ack();
- for(count=0;count<length;count++)
- {
- IIC_Send_Byte(data[count]);
- IIC_Wait_Ack();
- }
- IIC_Stop(); //发送停止信号
- return 1;
- }
- /******************************************
- *函数原型: u8 IIC_Read_Byte(unsigned char ack)
- *功能: 读取一个Byte的字节
- *输入: 读取一个字节,ack=1,发送ACK,ack=0,发送nACK
- *返回: 读取到的Byte
- ******************************************/
- u8 IIC_Read_Byte(unsigned char ack)
- {
- unsigned char i, receive = 0;
- SDA_IN(); //设置为输入
- for(i=0;i<8;i++)
- {
- IIC_SCL=0;
- delay_us(1);
- IIC_SCL=1;
- receive<<=1;
- if(READ_SDA) receive++;
- delay_us(1);
- }
- if(ack)
- IIC_Ack(); //发送ACK
- else
- IIC_NAck(); //发送NACK
- return receive;
- }
留下了一个不太清楚的内容,按位,位长度写数据:
- /****************************************************
- *函数原型: u8 IICwriteBits(u8 dev, u8 reg, u8 bitStart, u8 length, u8 data)
- *功能: 读、修改、写指定设备、指定寄存器一个字节中的多个位
- *输入: dev 目标设备地址
- * reg 寄存器地址
- * bitStart 目标字节的起始位,自左向右?
- * length 位长度
- * data 存放改变目标字节位的值
- *返回: 返回是否成功,1成功
- ****************************************************/
- u8 IICwriteBits(u8 dev, u8 reg, u8 bitStart, u8 length, u8 data)
- {
- u8 b;
- u8 mask;
- if(IICreadByte(dev, reg, &b) != 0)
- {
- mask = (0xFF << (bitStart +1))| 0xFF >> ((8 - bitStart) + length -1);
- data >>= (7 - bitStart);
- b &= mask;
- b |= data;
- return IICwriteByte(dev, reg, b);
- } else {
- return 0;
- }
- }
GPIO软件模拟IIC时序的更多相关文章
- stm32软件模拟IIC读取PX4FLOW光流传感器数据
这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模 ...
- 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)
版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...
- STM32 软件模拟 IIC 代码,标准库、HAL库可用
#ifndef _IIC_H #define _IIC_H #include "stdio.h" #include "stm32f1xx_hal.h" /* 定 ...
- 使用软件模拟spi 时序时注意点
软件模拟 spi 时序有以下几个点需要注意: cs 使能后到第一个 sck 边沿需要延时. 最后一个sck 边沿到下一个 cs 需要延时. sck 的高电平和低电平本身需要维持时间. mosi 需要先 ...
- GPIO软件模拟I2C
/***************************************************************************** * * Filename: * ----- ...
- 51单片机下实现软件模拟IIC通信
1.IIC协议简易概述 IIC全称Inter-Integrated Circuit (集成电路总线),是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备.IIC属于半双 ...
- 软件模拟IIC实现EEPROM
....妈的太难. 反正就是控制引脚的高低电平 实现数据的读取....参考 I2C的协议层和物理层的那个几个图,个个信号产生的电平 自己看源码去把. 头疼
- C51—模拟IIC总线实现EEPROM存取数据
a - 什么是IIC总线 -什么是EEPROM -IIC总线的通信格式 模块化设计注解 整体代码 - 什么是IIC总线 IIC总线是同步通信的一种特殊形式,具有接线口少.控制简单.器件封装形式小.通信 ...
- GPIO模拟IIC接口信号质量分析
信号质量有问题的波形001: 信号质量有问题的波形002: 从上图可以看出,GPIO口模拟的I2C接口,电平都存在半高的情况. 因为I2C的接口是通过GPIO模拟实现的,该时钟信号线SCL内部默认为下 ...
随机推荐
- pycharm 进入Pythonshell脚本调试
- springmvc把对象放到session中
1:首先把创建的对象放到Map中, @RequestMapping("/testSession") public String testSession(Map<Stri ...
- JS谷歌浏览器断点调试
1.找到对应的文件 按F12打开网页调试工具,默认打开的是Elements,显示的是网页标签元素.选择Source,在左侧找到对应的js代码文件(这里是在page标签上找到的) 1.1.如何找到web ...
- QUartus 使用之001_空格_箭头切换----FPGA--001
Quartus里的Tab键,按下后,显示的为什么是箭头,以前显示的是空白,图片如下: 解决方式如下: 修改后效果图如下:
- 听说你懂个J?——前端发展闲聊
刚好周末和朋友聊起"前端从受鄙视到变得重要"这个话题,感慨前端这四年来的发展,遂有本文. 1. 前情提要 毋庸讳言,在我刚工作的时候,前端是还是一个不受重视的岗位.切图狗,写网页的 ...
- html标签<td><tr><th>全称及缩写说明
<td> 是table data cell 的缩写,单元格 <tr> 是table row 的缩写,表格中的一行 <th> 是table header cell 的 ...
- EditText设置/隐藏光标位置、选中文本和获取/清除焦点(转)
转:http://blog.csdn.net/dajian790626/article/details/8464722 有时候需要让光标显示在EditText的指定位置或者选中某些文本.同样,为了方便 ...
- GPIO 的 8 种工作模式
GPIO 的 8 种工作模式 在初始化 GPIO 的时候,根据我们的使用要求,必须把 GPIO 设置为相应的模式.如 LED 例程中的 GPIO 引脚如果配置为模拟输入模式是必然会导致错误的. 我们配 ...
- Nuget-Doc:NuGet 介绍
ylbtech-Nuget-Doc:NuGet 介绍 NuGet 是适用于 .NET 的包管理器. 它使开发人员能够创建.共享和使用有用的 .NET 库. NuGet 客户端工具可生成这些库并将其作为 ...
- Java + selenium 元素定位(4)之By CSS
这篇我要介绍元素定位的倒数第二个方法啦,就是基于CSS的元素定位.关于一些CSS的知识,我这里就不累赘的讲了,以后可能会单独写一篇关于CSS的介绍.当然个人推荐如果之前完全没有CSS只是储备的,可以选 ...