源码网站模板洛南网站建设

张小明 2026/1/10 4:23:51
源码网站模板,洛南网站建设,免费素材库大全,软件推广渠道1.I2C通信简介简述#xff1a;I2C只有一根通信线#xff0c;数据在一条线上传输。同步#xff0c;即由时钟线带领数据传输#xff0c;可以在CPU处理其它事件时停止传输数据#xff0c;处理完后再重新开始。2.I2C的硬件电路解释#xff1a;1.SDA的控制权只有在从机发送数据…1.I2C通信简介简述I2C只有一根通信线数据在一条线上传输。同步即由时钟线带领数据传输可以在CPU处理其它事件时停止传输数据处理完后再重新开始。2.I2C的硬件电路解释1.SDA的控制权只有在从机发送数据和从机应答时才会交给从机而SCL的控制权一直都在主机即CPU手中。2.注意图中第二点开漏即一边接地一边接电阻就是强下拉、弱上拉避免电路短路。开漏加弱上拉兼具输入和输出功能3.软件控制I2C通信时序设计1.时序基本单元1.起始和终止2.发送逻辑主机控制SCL在SCL低电平时将数据放在SDA上从机在SCL高电平时读取主机放在SDA上的数据注意高位先行在这个单元中SCL和SDA都由主机控制从机被动读取数据。3.接收注意实线是主机控制的电平虚线是从机控制的电平。特别注意主机在接收之前需要释放SDA释放相当于主机将SDA的控制权交给了从机给从机放数据逻辑SCL低电平时从机放数据在SDA上SCL高电平时主机读取SDA上的数据4.应答确认是否收到或发送成功2.收发时序格式基本格式从机地址7字节读写操作1字节从机应答位寄存器地址读操作没有写入读出数据指定地址读前半部分为写操作指定地址后半部分为读操作。先写起始写入地址再读起始写入数据注意写入一个数据后地址指针会自动加1地址指针指向寄存器。如果主机想连续读取多个字节就要在最后一个字节给应答。给03.基本配置格式手动配置时序//将置电平操作封装成函数方便移植和修改 //Bitaction是一个枚举类型表示这个位是高电平还是低电平 void MyI2C_W_SCL(uint8_t BitValue) { GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue); Delay_us(10); } void MyI2C_W_SDA(uint8_t BitValue) { GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue); Delay_us(10); } uint8_t MyI2C_R_SDA(void) { uint8_t BitValue; BitValueGPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11); Delay_us(10); return BitValue; } //SCL和SDA配置成开漏输出SCL和SDA置高电平 void MyI2C_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_InitStructure;//结构体定义 GPIO_InitStructure.GPIO_ModeGPIO_Mode_Out_OD;//开漏输出 GPIO_InitStructure.GPIO_PinGPIO_Pin_10|GPIO_Pin_11;//IO口 GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz; GPIO_Init(GPIOB,GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);//此函数可以把引脚设置为高电平 } //起始时序 void MyI2C_Start(void) { MyI2C_W_SDA(1); MyI2C_W_SCL(1); MyI2C_W_SDA(0); MyI2C_W_SCL(0); } //终止时序 void MyI2C_Stop(void) { MyI2C_W_SDA(0); MyI2C_W_SCL(1); MyI2C_W_SDA(1); } //主机发送、从机接收数据的时序 void MyI2C_SendByte(uint8_t Byte) { uint8_t i; for(i0;i8;i) { MyI2C_W_SDA(Byte(0x80i)); MyI2C_W_SCL(1); MyI2C_W_SCL(0); } } //从机发送、主机接收数据的时序 uint8_t MyI2C_ReceiveByte(void) { uint8_t Byte0x00,i; MyI2C_W_SDA(1); MyI2C_W_SCL(1); for(i0;i8;i) { MyI2C_W_SCL(1); if(MyI2C_R_SDA()1){Byte|(0x80i);} MyI2C_W_SCL(0); } return Byte; } //发送应答时序 void MyI2C_SendAck(uint8_t AckBit) { MyI2C_W_SDA(AckBit); MyI2C_W_SCL(1); MyI2C_W_SCL(0); } //接收应道时序 uint8_t I2C_ReceiveAck(void) { unsigned char AckBit; MyI2C_W_SDA(1); MyI2C_W_SCL(1); AckBitMyI2C_R_SDA(); MyI2C_W_SCL(0); return AckBit; }4.硬件实现I2C通信STM32内部的I2C外设1.I2C外设简介2.STM32中I2C外设的内部结构图发送当数据由数据寄存器转到数据移位寄存器时状态寄存器的TXE位置1表发送寄存器为空接收当数据由数据移位寄存器转到数据寄存器时状态寄存器的RXNE位置1表示接收寄存器非空比较器、自身地址寄存器、双地址寄存器了解当STM32充当从机时使用错误校验计算了解CRC数据校验算法硬件自动校验3.I2C基本结构图此时GIOP口要配置成复用开漏输出模式4.硬件I2C的操作流程1.主机发送1.STM32默认为从模式需要给控制寄存器CR1中的Star位t写入1会自动清除才能进入主模式产生起始条件2.EV5是一个大标志位判断是否数据起始条件已发送3.EV6事件就是ADDR位为1代表寻址结束4.EV8_1事件就是TxE标志位为1写入数据5.EV8事件就是移位寄存器正在发送数据6.EV8_2事件请求停止7.P事件配置CR1中的Stop位为1产生终止条件2.主机接收1.STM32默认为从模式需要给控制寄存器CR1中的Star位t写入1会自动清除才能进入主模式产生起始条件2.EV5是一个大标志位判断是否数据起始条件已发送3.EV6事件就是ADDR位为1代表寻址结束4.EV6_1事件就是数据正在通过移位寄存器进行输入5.EV7事件就是数据输入完成后RxNE标志位置1表示数据寄存器非空6.EV7_1事件请求停止应答位ACK置07.EV9事件配置CR1中的Stop位为1产生终止条件3.硬件I2C的实战代码1.部分函数功能//生成起始条件 void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); //生成终止条件 void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); //配置CR1的ACK即为从机应答位给1为非应答给0为应答 void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); //将数据写入DR寄存器 void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); //读取DR寄存器的数据 uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); //发送7位地址的专用函数 void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);2.配置思路1.RCC开启时钟把I2C外设和对应的GPIO口的时钟打开2.配置GPIO配置成复用开漏输出模式3.配置I2C外设4.开启I2C使能)3.基本配置格式使用库函数实现时序注意硬件配置I2C是非阻塞式的需要等待标志位否则得到的波形会出现问题。利用MPU6050_WaitEvent函数监控标志位//此代码为通过硬件I2C外设来控制MPU6050的配置代码包含头文件MPU6050_Reg //注意建议配合江协视频和MPU6050的芯片手册观看 #define MPU6050_ADDRESS 0xD0 //超时跳出防止程序卡死 void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) { uint32_t Timeout; Timeout 10000; while (I2C_CheckEvent(I2Cx, I2C_EVENT) ! SUCCESS) { Timeout --; if (Timeout 0) { break; } } } //写入时序自带接收应答 void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data) { I2C_GenerateSTART(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//等待EV5事件 I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//等待EV6事件 I2C_SendData(I2C2, RegAddress); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);//等待EV8事件 I2C_SendData(I2C2, Data); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);//等待EV8_2事件 I2C_GenerateSTOP(I2C2, ENABLE); } //读取时序自带发送应答 uint8_t MPU6050_ReadReg(uint8_t RegAddress) { uint8_t Data; //写入要读取的地址 I2C_GenerateSTART(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//等待EV5事件 I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//等待EV6事件主机发送 I2C_SendData(I2C2, RegAddress); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);//等待EV8事件 //开始正式读取 I2C_GenerateSTART(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//等待EV5事件 I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);//等待EV6事件主机接收 I2C_AcknowledgeConfig(I2C2, DISABLE);//ACK置0 I2C_GenerateSTOP(I2C2, ENABLE);//配置停止位 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED); Data I2C_ReceiveData(I2C2); I2C_AcknowledgeConfig(I2C2, ENABLE);//恢复ACK return Data; } //初始化 void MPU6050_Init(void) { //I2C1和I2C2都是APB1上的外设 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_OD;//复用开漏输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode I2C_Mode_I2C;//I2C模式 I2C_InitStructure.I2C_ClockSpeed 50000;//时钟速度SCL频率 I2C_InitStructure.I2C_DutyCycle I2C_DutyCycle_2;//时钟占空比 I2C_InitStructure.I2C_Ack I2C_Ack_Enable;//应答位配置ACK I2C_InitStructure.I2C_AcknowledgedAddress I2C_AcknowledgedAddress_7bit;//STM32作为从机时用多少位地址 I2C_InitStructure.I2C_OwnAddress1 0x00; I2C_Init(I2C2, I2C_InitStructure); I2C_Cmd(I2C2, ENABLE); }//此代码为头文件MPU6050_Reg就是MPU6050相关的寄存器的地址 #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 #define MPU6050_ACCEL_XOUT_L 0x3C #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 #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 #define MPU6050_PWR_MGMT_2 0x6C #define MPU6050_WHO_AM_I 0x75 #endif
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

建设 春风 摩托车官方网站手机网站登录模板

不管你是零基础小白、在职备考党,还是学渣想逆袭,这份保姆级 PMP 备考指南都能帮你理清思路,不用走弯路,轻松冲刺一次上岸!​一、备考前期:先搞定 3 件事,打好基础​1. 明确考试核心信息​考试形…

张小明 2025/12/31 17:09:36 网站建设

凡科建站是不是免费的合肥专业网站制作团队

Linly-Talker在潜水探险中的装备使用说明引言 在远洋科考船的甲板上,风浪未息,潜水员正紧张地检查装备。此时,指挥中心的大屏亮起——一位面容沉稳的“虚拟安全官”开始播报今日下潜的关键参数:最大深度32米、停留时间18分钟、气体…

张小明 2026/1/3 6:42:59 网站建设

佛山网页网站设计多少钱石岩做网站

第一步:熔化小烛树蜡(基体)将称量好的小烛树蜡放入加热容器(如不锈钢杯)。在100C的恒温热板或油浴上加热,直至蜡完全熔化成透明、低粘度的液体。目的:为钨粉提供一个均匀、易流动的分散介质。第…

张小明 2026/1/2 22:12:26 网站建设

北京的做网站公司建设工程公司组织架构图

Linux内核信号队列深度解析:从sigqueue到实时信号处理 【免费下载链接】linux-insides-zh Linux 内核揭秘 项目地址: https://gitcode.com/gh_mirrors/li/linux-insides-zh 在Linux系统编程中,信号处理机制是实现进程间异步通信的核心技术。传统的…

张小明 2026/1/3 4:05:27 网站建设

北京网站优化体验pc网站优化排名软件

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个AI辅助代码调试工具,能够实时分析代码中的潜在错误和性能瓶颈。工具应支持多种编程语言(如Python、JavaScript、Java等),提供…

张小明 2026/1/2 15:44:38 网站建设

秦皇岛建设路小学网站怎样打开网站

12月11日,广东盘古信息科技股份有限公司在东莞总部成功举办生态接待日。本次活动以“携手共赢,生态共建”为主题,汇聚全国各地生态伙伴与企业代表,通过沉浸式交流与深度对接,共探IMS OS新一代工业软件的创新路径&#…

张小明 2026/1/3 0:34:06 网站建设