網站建設步驟大全石家莊seo推廣
文章目錄
- 前言
- MPU6050
- 參數
- 電路
- MPU6050框圖
- IIC外設
- 框圖
- IIC的基本結構
- 軟件IIC實現MPU6050
- 硬件IIC實現MPU6050
前言
在51單片機專欄中,用過I2C通信來進行實現AT24C02的數據存儲;
里面介紹的是利用程序的編程來實現I2C的時序,進而實現AT24C02與單片機之間的關系連接;
本章將介紹使用I2C的硬件外設來實現I2C通信,和介紹MPU6050,利用I2C通信實現STM32對MPU6050的控制.
I2C通信軟件實現程序鏈接入口
MPU6050
MPU6050是一種集成三軸陀螺儀和三軸加速度計的六軸運動處理組件。
可以用來感知物體的旋轉和加速度運動,并提供相應的測量數據。
MPU6050采用微機電系統(tǒng)(MEMS)技術,通過測量微小的力和振動來檢測物體的運動。其內置的三軸陀螺儀可以測量繞X、Y、Z軸的角速度,而三軸加速度計可以測量物體在X、Y、Z軸上的加速度。通過結合兩者的數據,可以獲得更準確的運動信息。
MPU6050還具有一個可擴展的數字運動處理器(DMP),可以實現更復雜的運動處理功能。DMP可以通過主要的I2C或SPI端口輸出完整的九軸運動融合數據,當連接到三軸磁強計時,可以獲得更全面的運動信息。
MPU6050廣泛應用于飛行器、機器人、游戲控制器等領域,可以提供準確的姿態(tài)感知和運動跟蹤功能。它的集成設計減少了封裝空間和組合陀螺儀與加速度計時間軸不匹配的問題,使其在各種應用中具有較高的可靠性和性能。
參數
角速度全格感測范圍:±250、±500、±1000、±2000°/sec(dps)
可追蹤快速和慢速動作
加速度全格感測范圍:±2g、±4g、±8g、±16g
產品傳輸可透過最高至400kHz的IIC
16位ADC采集傳感器的模擬信號,量化范圍:-32768~32767
I2C從機地址:
1101000(AD0=0) 0x68
1101001(AD0=1)0x69
這里的地址是沒有融入讀寫地址位的,如果融入讀寫地址位,那么將通過左移的方式,變成11010000,0xD0;11010001,0xD1。
電路
最右邊的是MPU6050的芯片,左下角是8針的排針,左上角是一個低壓差線性穩(wěn)壓器。
芯片包括時鐘、IIC通信引腳、供電、幀同步等,本章有很多是用不到的。
左下角VCC和GND是引腳供電;SCL和SDA是IIC通信的引腳,在芯片處,SCL和SDA已經內置了兩個4.7k的上拉電阻,在接線時,可以直接連接到GPIO口。
XCL和XDA是主機的IIC引腳,目的是為了拓展芯片功能,可拓展磁力計等功能。
AD0是從機地址的最低位,接低電平時,7位從機地址為1101000,接高電平時,7位從機地址就是1101001.這里默認連接上了弱下拉到低電平,引腳懸空時,即為低電平。倘若想變?yōu)楦唠娖?#xff0c;可以直接連接VCC,強上拉為高電平。
INT是中斷輸出引腳,可配置芯片內部一些事件,來觸發(fā)中斷引腳的輸出。
左上角LD0是供電的邏輯,MPU6050芯片的VCC供電為2.375~3.46V,屬于3.3V的供電設備,為了擴大供電范圍,設計者在電路中加入3.3V的穩(wěn)壓器,輸入端電壓VCC_5V可以在3.3V到5V之間,經過穩(wěn)壓器后即可輸出3.3V的電壓,一旦3.3V端有電壓,指示燈就會亮起。
MPU6050框圖
該圖即為芯片的內部結構。
左上角是時鐘系統(tǒng),有時鐘輸入腳和時鐘輸出腳。
灰色部分就是芯片的傳感器,分別是XYZ軸的加速度計,XYZ軸的陀螺儀。且還內置一個溫度傳感器,本質上傳感器就是可變電阻,所以通過ADC模數轉換,就可以產生數據放在數據寄存器中。我們只需要讀取寄存器中的數據即可得到測量值。
最左邊是用來驗證芯片的好壞的,當啟動自測后,芯片內部會模擬一個外力施加在傳感器上,該數據一般給的比平時大一些??梢杂檬鼓茏詼y,讀取數據,再使能自測,讀取數據,最后數據差稱為數據響應,只要數據響應在規(guī)定范圍內,則表明芯片沒問題。
ChargePump為電荷泵,這是一種升壓電路,會連接一個電容。
電荷泵與電容并聯(lián)時,可為電容充電,串聯(lián)時,那么電荷泵和電容一起為芯片供電,提供比原來大的電壓。
右邊是通信接口和一些寄存器。
中斷狀態(tài)寄存器,可以控制內部的某些事件到中斷引腳的輸出;
FIFO是先入先出寄存器,可以對數據流進行緩沖;
配置寄存器,可以對內部電路進行配置。
傳感器寄存器,也就是數據寄存器,存儲各傳感器的數據。
工廠校準,內部的傳感器都進行了校準;
數字運動處理器(DMP),這是芯片內部自帶的一個姿態(tài)解算的硬件算法。
然后就是IIC通信的接口,鏈接著STM32,下面還有一些是主機的IIC通信接口。通過(SIBM)寄存器選擇。
IIC外設
STM32內部集成了硬件I2C收發(fā)電路,可以由硬件自動執(zhí)行時鐘生成、起始終止條件生成、應答位收發(fā)、數據收發(fā)等功能,減輕CPU的負擔
支持多主機模型
支持7位/10位地址模式
支持不同的通訊速度,標準速度(高達100 kHz),快速(高達400 kHz)
支持DMA
兼容SMBus協(xié)議
STM32F103C8T6 硬件I2C資源:I2C1、I2C2
框圖
SDA接收數據和發(fā)送數據;
對于要發(fā)送的數據,會從數據寄存器轉移到數據移位寄存器中,數據移位寄存器再通過引腳串行發(fā)送數據位;
對于要接收的數據,也會先放到數據移位寄存器中,數據寄存器再從移位寄存器中取數據,這樣做的目的是為了更好的緩存數據,防止有些數據會丟失。
數據寄存器可以通過寫入控制寄存器對應位進行操作。
比較器和地址寄存器是從機模式使用的,STM32的IIC是基于可變多主機模型設計的,當STM32不通信時,可作為從機,可被別人召喚,這時就需要一個地址。
PEC是一個數據校驗模塊,當發(fā)送一個多數據幀時,硬件可以自動執(zhí)行CRC校驗計算,CRC是一種校驗算法,會根據前面這些數據,進行各種數據運算,會得到一個字節(jié)的校驗位,加在數據幀后面;STM32也可以自動對數據幀進行判斷,如果數據在傳輸過程中出錯,CRC算法通不過,硬件就會置校驗錯誤標志位。
SCL連接著時鐘控制。
SMBALEART是用于SMBus模式的,不使用該模式接口不能使用。
IIC的基本結構
數據控制器,控制對數據的發(fā)送和接收;
時鐘控制器,控制對時鐘的流動;
再接上GPIO口,最后把開關控制啟用,就能實現IIC通信。
軟件IIC實現MPU6050
OLED代碼鏈接入口
連接方式:
利用OLED屏幕顯示MPU6050陀螺儀和加速度各軸數據;
IIC.h
#ifndef __I2C_H__
#define __I2C_H__void I2C_INIT();
void I2C_Start();
void I2C_Stop();
void I2C_SendByte(uint8_t Byte);
uint8_t I2C_ReceiveByte();
void I2C_SendAck(uint8_t AckBit);
uint8_t I2C_ReceiveAck();#endif
IIC.c
#include "stm32f10x.h" // Device header
#include "Delay.h"void I2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue);Delay_us(10); //延遲是讓函數有時間反應
}void I2C_W_SDA(uint8_t BitValue)
{GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);Delay_us(10); //延遲是讓函數有時間反應
}uint8_t I2C_R_SDA()
{uint8_t BitValue;BitValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);Delay_us(10);return BitValue;
}void I2C_INIT()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //開漏弱上拉輸出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 I2C_Start()
{I2C_W_SDA(1);I2C_W_SCL(1);I2C_W_SDA(0);I2C_W_SCL(0);
}void I2C_Stop()
{I2C_W_SDA(0);I2C_W_SCL(1);I2C_W_SDA(1);
}void I2C_SendByte(uint8_t Byte)
{uint8_t i;for(i=0;i<8;i++){I2C_W_SDA(Byte&(0x80>>i));//高電平鎖存,從機讀取I2C_W_SCL(1);I2C_W_SCL(0);}
}uint8_t I2C_ReceiveByte()
{uint8_t i,Byte=0x00;I2C_W_SDA(1); //主機釋放SDAfor(i=0;i<8;i++){I2C_W_SCL(1); //SCL高電平期間主機讀取從機發(fā)送的數據if(I2C_R_SDA()==1){Byte|=(0x80>>i);}I2C_W_SCL(0);}return Byte;
}void I2C_SendAck(uint8_t AckBit)
{I2C_W_SDA(AckBit);//高電平鎖存,從機讀取I2C_W_SCL(1);I2C_W_SCL(0);
}uint8_t I2C_ReceiveAck()
{uint8_t AckBit;I2C_W_SDA(1); //主機釋放SDAI2C_W_SCL(1); //SCL高電平期間主機讀取從機發(fā)送的數據AckBit=I2C_R_SDA(); I2C_W_SCL(0);return AckBit;
}
這部分實現的是IIC的六個主要部分的代碼,與51單片機上的時序基本一致;在STM32上,是利用GPIO口來實現高低電平的輸入輸出。
輸出模式用開漏輸出,當輸出低電平時,電路會強下拉,變?yōu)榈碗娖?#xff1b;
當輸出為高電平時,為弱上拉,一旦有下拉電平輸入,就會變成低電平。
該模式不止可以實現輸出,也可以實現對IIC的接收,當輸入為1時,在SCL高電平時STM32會讀取;當輸入為0時,在SCL高電平STM32會讀取.
MPU6050_tag.h
#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
MPU6050.h
#ifndef __MPU6050_H__
#define __MPU6050_H__void MPU6050_Init();
uint8_t MPU6050_GetID();
void MPU6050_GetData(int16_t* AccX,int16_t* AccY,int16_t* AccZ,int16_t* GyroX,int16_t* GyroY,int16_t* GyroZ);#endif
MPU6050.c
#include "stm32f10x.h" // Device header
#include "I2C.h"
#include "MPU6050_rag.h"#define MPU6050_ADDRESS 0xD0void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data)
{I2C_Start();I2C_SendByte(MPU6050_ADDRESS);I2C_ReceiveAck();I2C_SendByte(RegAddress);I2C_ReceiveAck();I2C_SendByte(Data);I2C_ReceiveAck();I2C_Stop();}uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;I2C_Start();I2C_SendByte(MPU6050_ADDRESS);I2C_ReceiveAck();I2C_SendByte(RegAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(MPU6050_ADDRESS|0x01);I2C_ReceiveAck();Data=I2C_ReceiveByte();I2C_SendAck(1); //主機不應答,主機收回主動權,讓從機停止發(fā)送數據字節(jié)I2C_Stop();return Data;}void MPU6050_Init()
{I2C_INIT();MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0x01); //解除睡眠,選擇陀螺儀時鐘MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0x00); //6個軸均不待機MPU6050_WriteReg(MPU6050_SMPLRT_DIV,0x09); //采樣分頻為10MPU6050_WriteReg(MPU6050_CONFIG, 0x06); //濾波參數給最大MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18); //最大陀螺儀量程MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18); //最大加速度量程}uint8_t MPU6050_GetID()
{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<<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;}
第一個代碼塊是對MPU6050一些寄存器地址的宏定義,主要有采樣分頻寄存器、陀螺儀配置寄存器、加速度配置寄存器、加速度數據寄存器、陀螺儀數據寄存器、狀態(tài)寄存器1/2、地址寄存器。
對于MPU6050的讀寫,采用了IIC通信時序實現
寫時序:
讀時序:
數據存儲器為16位存儲;
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"uint8_t ID;
int16_t AX,AY,AZ,GX,GY,GZ;int main()
{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);}
}
硬件IIC實現MPU6050
連接方式與軟件的保持一致。由于是硬件外設,需要注意引腳有沒有支持該IIC功能。
對于硬件外設,我們只需要對軟件實現部分的IIC通信進行修改。
MPU6050.c
#include "stm32f10x.h" // Device header
#include "MPU6050_rag.h"#define MPU6050_ADDRESS 0xD0void 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); //SMPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT); //EV5I2C_Send7bitAddress(I2C2,MPU6050_ADDRESS,I2C_Direction_Transmitter);MPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); //EV6I2C_SendData(I2C2,RegAddress);MPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING); //EV8I2C_SendData(I2C2,Data);MPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED); //EV8_2I2C_GenerateSTOP(I2C2,ENABLE);
}uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;I2C_GenerateSTART(I2C2,ENABLE); //SMPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT); //EV5I2C_Send7bitAddress(I2C2,MPU6050_ADDRESS,I2C_Direction_Transmitter); MPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); //EV6I2C_SendData(I2C2,RegAddress); MPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTART(I2C2,ENABLE); //SMPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT); //EV5I2C_Send7bitAddress(I2C2,MPU6050_ADDRESS,I2C_Direction_Receiver);MPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); //EV6//EV7_1I2C_AcknowledgeConfig(I2C2,DISABLE);//應答位禁用 I2C_GenerateSTOP(I2C2,ENABLE); //PMPU6050_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED); //EV7Data=I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2,ENABLE); //應答位啟用return Data;}void MPU6050_Init()
{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_Ack=I2C_Ack_Enable; //啟用應答位I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit; //確認地址模式I2C_InitStructure.I2C_ClockSpeed=50000; //時鐘頻率I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2; //占空比I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; //模式選擇I2C_InitStructure.I2C_OwnAddress1=0x00;I2C_Init(I2C2,&I2C_InitStructure);I2C_Cmd(I2C2,ENABLE);MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0x01); //解除睡眠,選擇陀螺儀時鐘MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0x00); //6個軸均不待機MPU6050_WriteReg(MPU6050_SMPLRT_DIV,0x09); //采樣分頻為10MPU6050_WriteReg(MPU6050_CONFIG, 0x06); //濾波參數給最大MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18); //最大陀螺儀量程MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18); //最大加速度量程}uint8_t MPU6050_GetID()
{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<<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;}
這里的初始化,GPIO引腳需要用到復用模式,因為IIC外設是片上外設;
接收數據和發(fā)送數據要根據STM32的要求,
根據響應事件來確定事件的產生效果,所以會在每條條件后執(zhí)行響應事件。
對于所給的庫函數,有些事件(EVX)沒有提供,一些可以省略,一些需要對程序進行一定的整改。
如上面的EV8_1,確保數據寄存器和移位寄存器為空,在我們一開始調用時,就為空,所以可以對它進行忽略。
接收數據的EV7_1,描述到,設置應答位為無應答,和Stop請求;對于連續(xù)接收的數據,需要在最后一個數據之前進行EV7_1響應,在進行EV7_1響應時,因為最后一個數據會先放到移位寄存器中,最后第二個會在數據寄存器中。需要提前STOP請求,表示,接收結束。
而在程序中,我們只是對一個數據進行接收,并沒有連續(xù)接收數據,但道理一樣,需要提前STOP請求。而在庫函數中剛好沒有對應的函數,需要自己禁用ACK和STOP請求。
上軟下硬:
這時軟件和硬件的波形對比,會發(fā)現,在應答位硬件會更快應答,只要到到SCL下降沿和SDA上升沿,就會產生應答。這就是硬件的優(yōu)勢;
在軟件中,由于是同步時序,對于時間沒有嚴格要求,只要在對應時間完成對應的電平操作即可,所以IIC通信才可以實現軟件編程。而軟件編程相對來說,也比較容易理解。