GPIO软件模拟IIC时序
2017-08-15 09:10
253 查看
一、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;
}
}
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(35) | 评论(0) | 转发(0) |
0
上一篇:MPU6050寄存器记录
下一篇:嵌入式学习网站推荐
相关热门文章
SHTML是什么_SSI有什么用...
查看linux中某个端口(port)...
卡尔曼滤波的原理说明...
shell中字符串操作
关于java中的“错误:找不到或...
给主人留下些什么吧!~~
评论热议
相关文章推荐
- 基于51单片机实现模拟IIC总线时序
- IIC 时序分析,stm32软件模拟驱动编写
- 基于stm32单片机的模拟IIC时序(附源码)
- GPIO软件模拟IIC时序--转载
- 单片机模拟IIC时序读写24C02
- 基于51单片机实现模拟IIC总线时序
- 基于51单片机实现模拟IIC总线时序
- 学习笔记——51通过IO口模拟IIC实现AT24C02的读写
- 用s5pc100的GPIO模拟IIC
- STM32 模拟IIC主设备 非IIC静默模式
- IIC的读写时序问题
- 深入理解I2C总线时序的模拟
- GPIO模拟IIC接口信号质量分析
- IIC时序图
- gpio软件模拟IIC与硬件IIC驱动有什么区别
- 51单片机普通IO口模拟IIC总线的程序实现
- 基于FPGA EEPROM读写实现及IIC总线协议和时序分析
- GPIO模拟IIC代码模板
- 51单片机 软件模拟IIC
- 【转载】2440的GPIO模拟IIC程序