STM32 您所在的位置:网站首页 stm32i2c从机 STM32

STM32

2024-01-25 12:03| 来源: 网络整理| 查看: 265

目录

 一丶I2C简介

二丶读写过程

(一)发送过程

(二)接收数据

 三丶库函数

四丶代码部分及解析(使用了MPU6050观察实验现象)

(一)I2C及MPU6050初始化部分

(二)主函数部分

      一丶I2C简介

(1)由两条总线控制:一条双向串行数据线(SDA) ,一条串行时钟线 (SCL)。SDA用来发送数据,SCL用于数据收发同步。 (2)I2C总线上可挂在多个 I2C通讯的设备 (3)每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。 (4)总线通过上拉电阻接到电源。当 I2C 设备空闲时,输出高阻态,而当所有设备都空闲,都输出高阻态,上拉电阻将总线拉成高电平。 (5)多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。 (6)支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)支持DMA (7)同步,半双工 二丶读写过程 (1)发送过程

(2)接收数据

 三丶库函数

(1)void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);

          初始化I2C 

(2)void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);

         使能I2C

(3)void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);          void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);

         配合DMA使用

(4)void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);          void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

         起始条件和终止条件

(5)void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); 

收到一个字节后是否给从机应答  

 (6)void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);

          设置主机地址(STM32当从机使用时配置)

(7)void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);          uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

         发送数据和接收数据

(8)void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

         发送从机地址(当然I2C_SendData也可以发送)

(9)I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);

          检查应答位

四丶代码部分及解析(使用了MPU6050观察实验现象) (一)I2C及MPU6050初始化部分 #include "stm32f10x.h" // Device header #include "MPU6050_Reg.h" #define MPU6050_ADDRESS 0xD0 void MPU6050_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); //开启GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启I2C时钟 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); //初始化GPIO I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C模式 I2C_InitStructure.I2C_ClockSpeed = 50000; //传输速度,最大不能超过400KHZ I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //时钟占空比 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //主机是否设置应答 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //主机地址位数 7位或10位 I2C_InitStructure.I2C_OwnAddress1 = 0x00; //主机地址(当STM32位从机时) I2C_Init(I2C2, &I2C_InitStructure); I2C_Cmd(I2C2, ENABLE); MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01); MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00); MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09); MPU6050_WriteReg(MPU6050_CONFIG, 0x06); MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18); MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18); } 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); I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); I2C_SendData(I2C2, RegAddress); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); //此上与发送数据相同 I2C_GenerateSTART(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); //检测EV6(接收模式) I2C_AcknowledgeConfig(I2C2, DISABLE); //主机给从机应答位A I2C_GenerateSTOP(I2C2, ENABLE); //接收数据时需要提前发送终止位 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED); //检测EV7 Data = I2C_ReceiveData(I2C2); I2C_AcknowledgeConfig(I2C2, ENABLE); return Data; } uint8_t MPU6050_GetID(void) { return MPU6050_ReadReg(MPU6050_WHO_AM_I); } 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


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有