网站建设三方协议,佛山乐从网站建设,深圳小程序开发公司排名,长沙公共资源交易中心官网1、硬件电路 SCL引到了STM32的PB10号引脚#xff0c;SDA引到了PB11号引脚软件I2C协议#xff1a; 用普通GPIO口#xff0c;手动反转电平实现协议#xff0c;不需要STM32内部的外设资源支持#xff0c;故端口是可以任意指定MPU605在SCL和SDA自带了两个上拉电阻#xff0c;…1、硬件电路 SCL引到了STM32的PB10号引脚SDA引到了PB11号引脚软件I2C协议 用普通GPIO口手动反转电平实现协议不需要STM32内部的外设资源支持故端口是可以任意指定MPU605在SCL和SDA自带了两个上拉电阻故不需要额外接上拉电阻AD0引脚修改从机地址的最低位其内置了下拉电阻故引脚悬空时相当于接地INT:中断信号输出引脚没用到不接 2、I2C部分代码解释
1发送字节 void MyI2C_SendByte(uint8_t Byte)
{//先把数据放到SDA上面然后SCL先置1再置零将SDA上面的数据送出去uint8_t i;for (i 0; i 8; i ){MyI2C_W_SDA(Byte (0x80 i));//先去最高位MyI2C_W_SCL(1);//驱动时钟走一个脉冲MyI2C_W_SCL(0);}
} 除了终止条件SCL以高电平结束所有单元以低电平结束方便各个单元的拼接 趁着SCL是低电平先把数据放在SDA上再MyI2C_W_SCL(1)MyI2C_W_SCL(0);SCL是原本是低电平此时先高电平再低电平使得SDA走一个时钟读取SCL的数据 2读取字节 SCL低电平期间从机将数据位依次放到SDA线上高位先行 uint8_t MyI2C_ReceiveByte(void)
{//SDA先置1这个时候从机把第一个数据放到SDA上然后SCL置1读取从机的数据uint8_t i, Byte 0x00;MyI2C_W_SDA(1);//主机释放SDA从机把数据放到SDA这时主机释放SCLSCL高电平主机就能读取数据高位先行for (i 0; i 8; i ){MyI2C_W_SCL(1);//SCL高电平主机就可能读取数据了//置1之后读取SDA的数据if (MyI2C_R_SDA() 1){Byte | (0x80 i);}//如果不是高电平就默认是写进0MyI2C_W_SCL(0);}return Byte;//把接收的字节放回过去
} 接收一个字节开始时SCL为低电平从机把数据放在SDA为了防止主机干扰从机写入数据主机先释放SDA释放SDA相当于切换为输入模式故在SCL低电平时从机会把数据放到SDA如果从机想发1就释放SDA发0拉低SDA然后主机释放SCL在SCL高电平期间读取SDA即在SCL为低电平的时候SDA写入数据等SCL释放时读SDA数据即为读写分离的方式故在读写数据的时候SCL是在SDA低电平的时候变化在高电平的时候不变 在起始和终止的时候SCL是在SDA高电平的时候变化 (3)接收应答 函数进来时SCL为低电平主机释放SDA防止干扰从机同时从机把应答位放在SDA上SCL高电平主机读取应答位SCL低电平进入下一个时序单元 uint8_t MyI2C_ReceiveAck(void)
{//将SDA置1后这个时候从机把应答位放在SDA上这个时候只需要SCL置1后置零读取数据即可记得是 //在SCL为高电平的时候读取数据然后读取完之后SCL再置零uint8_t AckBit;MyI2C_W_SDA(1);MyI2C_W_SCL(1);AckBit MyI2C_R_SDA();//此处不一定是1MyI2C_W_SCL(0);return AckBit;
} AckBit MyI2C_R_SDA();//此处不一定是1 原因I2C的引脚都是开漏输出弱上拉配置主机输出1并不是强制SDA为高电平而是释放SDA I2C是在进行通信主机释放SDA从机在的情况下有义务将SDA拉低故读到0代表从机给了应答1则从机应答 3、MyI2C.c
#include stm32f10x.h // Device header
#include Delay.h//写SCL的函数
void MyI2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);Delay_us(10);
}//写SDA的函数
void MyI2C_W_SDA(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);Delay_us(10);
}//读SDA的函数
uint8_t MyI2C_R_SDA(void)//读
{uint8_t BitValue;BitValue GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);//读取SDA的线Delay_us(10);return BitValue;
}//MyI2C初始化
void MyI2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_OD;//开漏输出模式仍然可以输入输入时先输出1再直接读取输入数据寄存器GPIO_InitStructure.GPIO_Pin GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB, GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);//都为高电平处于空闲状态
}//兼容起始条件和重复条件
void MyI2C_Start(void)
{MyI2C_W_SDA(1);//先确保释放数据线再释放SCLMyI2C_W_SCL(1);MyI2C_W_SDA(0);//拉低数据线触发通讯MyI2C_W_SCL(0);//拉低时钟线方便数据线上的数据变化
}//终止条件
//确保释放的时候能产生上升沿需要先拉底数据线后面在SCL是高电平的时候再拉高SDA
void MyI2C_Stop(void)
{MyI2C_W_SDA(0);MyI2C_W_SCL(1);MyI2C_W_SDA(1);
}
//除了终止条件SCL以高电平结束所有单元以低电平结束方便各个单元的拼接//发送一个字节的逻辑以stm32为视角
void MyI2C_SendByte(uint8_t Byte)
{uint8_t i;for (i 0; i 8; i ){//除了终止条件SCL以高电平结束所有单元以低电平结束方便各个单元的拼接//趁着SCL是低电平先把数据放在SDA上再让SDA走一个时钟MyI2C_W_SDA(Byte (0x80 i));//先去最高位MyI2C_W_SCL(1);//驱动时钟走一个脉冲MyI2C_W_SCL(0);}
}//接收一个字节开始时SCL为低电平从机把数据放在SDA为了防止主机干扰从机写入数据
//主机先释放SDA释放SDA相当于切换为输入模式故在SCL低电平时从机会把数据放到SDA
//如果从机想发1就释放SDA发0拉低SDA然后主机释放SCL在SCL高电平期间读取SDA
//即在SCL为低电平的时候SDA写入数据等SCL释放时读SDA数据即为读写分离的方式
//故在读写数据的时候SCL是在SDA低电平的时候变化在高电平的时候不变
//在起始和终止的时候SCL是在SDA高电平的时候变化
uint8_t MyI2C_ReceiveByte(void)
{uint8_t i, Byte 0x00;MyI2C_W_SDA(1);//主机释放SDA从机把数据放到SDA这时主机释放SCLSCL高电平主机就能读取数据高位先行for (i 0; i 8; i ){MyI2C_W_SCL(1);//SCL高电平主机就可能读取数据了if (MyI2C_R_SDA() 1){Byte | (0x80 i);}//如果不是高电平就默认是写进0MyI2C_W_SCL(0);}return Byte;//把接收的字节放回过去
}//发送应答
//函数进来时SCL为低电平
void MyI2C_SendAck(uint8_t AckBit)
{MyI2C_W_SDA(AckBit);MyI2C_W_SCL(1);MyI2C_W_SCL(0);//进入下一个时序单元
}//接收应答
//函数进来时SCL为低电平主机释放SDA防止干扰从机同时从机把应答位放在SDA上
//SCL高电平主机读取应答位SCL低电平进入下一个时序单元
uint8_t MyI2C_ReceiveAck(void)
{uint8_t AckBit;MyI2C_W_SDA(1);MyI2C_W_SCL(1);AckBit MyI2C_R_SDA();//此处不一定是1//原因I2C的引脚都是开漏输出弱上拉配置主机输出1并不是强制SDA为高电平而是释放SDA//I2C是在进行通信主机释放SDA从机在的情况下有义务将SDA拉低故读到0代表从机给了应答1则从机应答MyI2C_W_SCL(0);return AckBit;
}
4、MPU6050.c 在这个代码当中写到了MPU读写寄存器等函数
#include stm32f10x.h // Device header
#include MyI2C.h
#include MPU6050_Reg.h#define MPU6050_ADDRESS 0xD0//基于I2C通信的模块实现指定地址读、指定地址写再实现写寄存器对芯片进行配置读寄存器得到传感器数据//指定地址写
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS);MyI2C_ReceiveAck();//没有对应答位进行判断MyI2C_SendByte(RegAddress);MyI2C_ReceiveAck();//没有对应答位进行判断MyI2C_SendByte(Data);MyI2C_ReceiveAck();//没有对应答位进行判断MyI2C_Stop();
}//指定地址读
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS);MyI2C_ReceiveAck();MyI2C_SendByte(RegAddress);MyI2C_ReceiveAck();MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS | 0x01);//读MyI2C_ReceiveAck();//若想要给多个数据则用for循环接收然后MyI2C_SendAck(0)最后再写1Data MyI2C_ReceiveByte();MyI2C_SendAck(1);//1不给从机应答0给从机应答想读多个字节给应答如果在这里给了应答那么从机就会源源不断发送数据MyI2C_Stop();return Data;//地址
}//目前的配置解除睡眠、选择陀螺仪时钟6个轴均不待机采样分频为10
//滤波参数给最大陀螺仪个加速度计都选择最大量程
void MPU6050_Init(void)
{MyI2C_Init();MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);//电源管理寄存器1翻手册一位一位赋值不复位解除睡眠不需要循环温度传感器失能001选择x轴的螺旋仪时钟MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);//电源管理寄存器200:不需要循环模式唤醒频率后6位每个轴的待机位全部给0不需要待机MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);//10分频//采样率分频这8位决定了数据的快慢值越小越快根据实际的需求来MPU6050_WriteReg(MPU6050_CONFIG, 0x06);//配置寄存器前两位没用第3位到5位000不需要外部同步最后三位110最平滑的数字低通滤波器MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);//陀螺仪配置寄存器前面三位自测使能不自测4、5位满量程选择11选择最大量程后面三位无关位MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);//加速度计配置寄存器自测给000满量程给最大量程11用不到高通滤波器00
}uint8_t MPU6050_GetID(void)
{return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}/*
获取数据
加速度传感器的输出数据x轴y轴和z轴的加速度
陀螺仪传感器的输出数据x轴y轴和z轴的角速度
改变MPU6050传感器的姿态6个数据就会对应变化
*/
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{uint8_t DataH, DataL;DataH MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);DataL MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);*AccX (DataH 8) | DataL;DataH MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);DataL MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);*AccY (DataH 8) | DataL;DataH MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);DataL MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);*AccZ (DataH 8) | DataL;DataH MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);DataL MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);*GyroX (DataH 8) | DataL;DataH MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);DataL MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);*GyroY (DataH 8) | DataL;DataH MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);DataL MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);*GyroZ (DataH 8) | DataL;
}
5、MPU6050_Reg.c
#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H#define MPU6050_SMPLRT_DIV 0x19//采样率分频
#define MPU6050_CONFIG 0x1A//配置寄存器
#define MPU6050_GYRO_CONFIG 0x1B//陀螺仪配置寄存器
#define MPU6050_ACCEL_CONFIG 0x1C//加速度计配置寄存器#define MPU6050_ACCEL_XOUT_H 0x3B//加速度寄存器X轴的高8位
#define MPU6050_ACCEL_XOUT_L 0x3C//加速度寄存器X轴的低8位
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43//陀螺仪的x轴
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48#define MPU6050_PWR_MGMT_1 0x6B//电源管理寄存器1地址是0x6B
#define MPU6050_PWR_MGMT_2 0x6C//电源管理寄存器2地址是0x6B
#define MPU6050_WHO_AM_I 0x75#endif
6、main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include MPU6050.huint8_t ID;
int16_t AX, AY, AZ, GX, GY, GZ;
//写好I2C底层的GPIO初始化和6各时序基本单元
//起始、终止、发送一个字节、接受一个字节、发送应答和接收应答int main(void)
{OLED_Init();MPU6050_Init();OLED_ShowString(1, 1, ID:);ID MPU6050_GetID();OLED_ShowHexNum(1, 4, ID, 2);while (1){MPU6050_GetData(AX, AY, AZ, GX, GY, GZ);OLED_ShowSignedNum(2, 1, AX, 5);OLED_ShowSignedNum(3, 1, AY, 5);OLED_ShowSignedNum(4, 1, AZ, 5);OLED_ShowSignedNum(2, 8, GX, 5);OLED_ShowSignedNum(3, 8, GY, 5);OLED_ShowSignedNum(4, 8, GZ, 5);}
}
7、从机地址 该设备中只有AD0一个引脚故只有两个名字若有AD0和AD1两个引脚则有4个名字 最后一位为0否则就是把控制权交出去 I2C从机地址1101000AD00——1101 0000 0xD0 1101001AD01——1101 0010 0xD2 8、验证结果 将陀螺仪 放在水平位置上 显示屏读出的六个数据是 00130 -00018 -00017 -00003 01943 -00007 验证数据 配置的是量程最大的18g,故1943/32768x/16g x0.949g,接近1 把设备上倾x轴正值下倾x轴负值
文章转载自: http://www.morning.fwllb.cn.gov.cn.fwllb.cn http://www.morning.rsnn.cn.gov.cn.rsnn.cn http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn http://www.morning.xhqr.cn.gov.cn.xhqr.cn http://www.morning.pmdnx.cn.gov.cn.pmdnx.cn http://www.morning.rlhgx.cn.gov.cn.rlhgx.cn http://www.morning.jfcbz.cn.gov.cn.jfcbz.cn http://www.morning.gqwbl.cn.gov.cn.gqwbl.cn http://www.morning.qkgwx.cn.gov.cn.qkgwx.cn http://www.morning.xnpj.cn.gov.cn.xnpj.cn http://www.morning.synlt.cn.gov.cn.synlt.cn http://www.morning.cpctr.cn.gov.cn.cpctr.cn http://www.morning.wnkqt.cn.gov.cn.wnkqt.cn http://www.morning.dongyinet.cn.gov.cn.dongyinet.cn http://www.morning.txhls.cn.gov.cn.txhls.cn http://www.morning.hkshy.cn.gov.cn.hkshy.cn http://www.morning.wfyzs.cn.gov.cn.wfyzs.cn http://www.morning.skpdg.cn.gov.cn.skpdg.cn http://www.morning.ttaes.cn.gov.cn.ttaes.cn http://www.morning.xfcjs.cn.gov.cn.xfcjs.cn http://www.morning.kghhl.cn.gov.cn.kghhl.cn http://www.morning.c7627.cn.gov.cn.c7627.cn http://www.morning.jpmcb.cn.gov.cn.jpmcb.cn http://www.morning.qjlkp.cn.gov.cn.qjlkp.cn http://www.morning.nqypf.cn.gov.cn.nqypf.cn http://www.morning.kxgn.cn.gov.cn.kxgn.cn http://www.morning.ggrzk.cn.gov.cn.ggrzk.cn http://www.morning.jkzjs.cn.gov.cn.jkzjs.cn http://www.morning.zwndt.cn.gov.cn.zwndt.cn http://www.morning.tddrh.cn.gov.cn.tddrh.cn http://www.morning.btpzn.cn.gov.cn.btpzn.cn http://www.morning.qnxzx.cn.gov.cn.qnxzx.cn http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn http://www.morning.zhmgcreativeeducation.cn.gov.cn.zhmgcreativeeducation.cn http://www.morning.bgxgq.cn.gov.cn.bgxgq.cn http://www.morning.i-bins.com.gov.cn.i-bins.com http://www.morning.nbhft.cn.gov.cn.nbhft.cn http://www.morning.fdmfn.cn.gov.cn.fdmfn.cn http://www.morning.mmjyk.cn.gov.cn.mmjyk.cn http://www.morning.mqfhy.cn.gov.cn.mqfhy.cn http://www.morning.cjqcx.cn.gov.cn.cjqcx.cn http://www.morning.webife.com.gov.cn.webife.com http://www.morning.klzt.cn.gov.cn.klzt.cn http://www.morning.qytpt.cn.gov.cn.qytpt.cn http://www.morning.wgkz.cn.gov.cn.wgkz.cn http://www.morning.mdplm.cn.gov.cn.mdplm.cn http://www.morning.lrybz.cn.gov.cn.lrybz.cn http://www.morning.lpgw.cn.gov.cn.lpgw.cn http://www.morning.jqpq.cn.gov.cn.jqpq.cn http://www.morning.mxmzl.cn.gov.cn.mxmzl.cn http://www.morning.sgmgz.cn.gov.cn.sgmgz.cn http://www.morning.xzrbd.cn.gov.cn.xzrbd.cn http://www.morning.bnxfj.cn.gov.cn.bnxfj.cn http://www.morning.rbhqz.cn.gov.cn.rbhqz.cn http://www.morning.skbkq.cn.gov.cn.skbkq.cn http://www.morning.mpngp.cn.gov.cn.mpngp.cn http://www.morning.clnmf.cn.gov.cn.clnmf.cn http://www.morning.nspzy.cn.gov.cn.nspzy.cn http://www.morning.hbxnb.cn.gov.cn.hbxnb.cn http://www.morning.caswellintl.com.gov.cn.caswellintl.com http://www.morning.xqgtd.cn.gov.cn.xqgtd.cn http://www.morning.mxhys.cn.gov.cn.mxhys.cn http://www.morning.xlmpj.cn.gov.cn.xlmpj.cn http://www.morning.sdkaiyu.com.gov.cn.sdkaiyu.com http://www.morning.yfzld.cn.gov.cn.yfzld.cn http://www.morning.kyjyt.cn.gov.cn.kyjyt.cn http://www.morning.rntyn.cn.gov.cn.rntyn.cn http://www.morning.tkchg.cn.gov.cn.tkchg.cn http://www.morning.rbjth.cn.gov.cn.rbjth.cn http://www.morning.gqfbl.cn.gov.cn.gqfbl.cn http://www.morning.nhrkc.cn.gov.cn.nhrkc.cn http://www.morning.dndk.cn.gov.cn.dndk.cn http://www.morning.fwnqq.cn.gov.cn.fwnqq.cn http://www.morning.llqch.cn.gov.cn.llqch.cn http://www.morning.ypzr.cn.gov.cn.ypzr.cn http://www.morning.xwnnp.cn.gov.cn.xwnnp.cn http://www.morning.txysr.cn.gov.cn.txysr.cn http://www.morning.mstbbs.com.gov.cn.mstbbs.com http://www.morning.lpqgq.cn.gov.cn.lpqgq.cn http://www.morning.mrlls.cn.gov.cn.mrlls.cn