赞
踩
"软件I2C"和"硬件I2C"都是指用于实现I2C(Inter-Integrated Circuit,双线串行总线)通信协议的不同方法。
需要注意的是,软件I2C和硬件I2C在使用上有一些差异,特别是在初始化、配置和操作方面。具体的方法和接口可能因不同的平台和微控制器而有所不同,因此在实际应用中需要根据具体的硬件和软件环境选择合适的I2C实现方式。
软件I2C是通过使用软件来模拟实现I2C协议的通信。在软件I2C中,通信线(SDA和SCL)通常连接到微控制器的普通GPIO引脚。通过编程控制这些引脚的状态变化,可以模拟I2C的数据传输和时钟信号。软件I2C通常需要使用延时函数来控制数据的传输速率和时序,因为整个过程是由软件来处理的。
软件I2C的优点是可以在没有硬件I2C接口的设备上实现I2C通信。它不依赖于特定的硬件,因此可以在各种平台和微控制器上使用。然而,由于软件I2C是通过软件模拟的,其速度可能相对较慢,并且对CPU的处理能力要求较高。
硬件I2C是通过专门的硬件接口来实现I2C协议的通信。现代的微控制器和一些集成电路芯片通常都具有硬件I2C接口。这些接口内置了I2C通信所需的电路和逻辑,能够直接处理I2C协议的数据传输和时序。
硬件I2C的优点是速度较快,因为通信过程由硬件自动处理,无需CPU的干预。它也能提供更稳定和准确的时序,从而实现更可靠的数据传输。由于硬件I2C接口是专门设计的,因此在性能和可靠性方面通常优于软件I2C。
对温湿度模块呼气产生了变化,如上图所示。
代码片段如下:
#include "delay.h" #include "usart.h" #include "bsp_i2c.h" int main(void) { delay_init(); uart_init(115200); IIC_Init(); while(1) { printf("开始测量: "); read_AHT20_once(); delay_ms(1500); } }
#include "bsp_i2c.h" #include "delay.h" uint8_t ack_status=0; uint8_t readByte[6]; uint8_t AHT20_status=0; uint32_t H1=0; //Humility uint32_t T1=0; //Temperature uint8_t AHT20_OutData[4]; uint8_t AHT20sendOutData[10] = {0xFA, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}; void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //Ȫ?ȪȬȺ?3? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); IIC_SCL=1; IIC_SDA=1; } //2ȲȦȲIIC?eȺ?D?o? void IIC_Start(void) { SDA_OUT(); //sda??Ⱥ?3? IIC_SDA=1; IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL=0;//?e?I2Cȹ??ª??€?d©?Ȫ?Ȱ?ȮȺ?Ⱥy?Y } //2ȲȦȲIICȪª?1D?o? void IIC_Stop(void) { SDA_OUT();//sda??Ⱥ?3? IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; IIC_SDA=1;//d©?ȪI2Cȹ???ȢȺ?D?o? delay_us(4); } //njȨ¤yȮ|¤eD?o?nj?Ȥ¤ //dnj???njªo1ª??ȮȺ?Ȯ|¤eȺ¬£ȹ // 0ª??ȮȺ?Ȯ|¤e3Ȧ1| u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); //SDAȦȨ???aȺ?Ȩ? IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//Ⱥ€?ȮȺ?3?0 return 0; } //2ȲȦȲACKȮ|¤e void IIC_Ack(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //2?2ȲȦȲACKȮ|¤e void IIC_NAck(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //IICd©?ȪȰ?????Ȳ //dnj??¤Ȯ?ȲȮD?TȮ|¤e //1ª?ȮDȮ|¤e //0ª??TȮ|¤e void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=0;//Ȥ-njȪȺ€?Ȯ?aȺ?Ⱥy?Y¤?Ⱥ? for(t=0;t<8;t++) { IIC_SDA=(txd&0x80)>>7; txd<<=1; delay_us(2); //??TEA5767?aȨy???ȮȺ€??Ⱥ?€?D?nj? IIC_SCL=1; delay_us(2); IIC_SCL=0; delay_us(2); } } //?Ȣ1????Ȳª?ack=1Ⱥ€ª?d©?ȪACKª?ack=0ª?d©?ȪnACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN();//SDAȦȨ???aȺ?Ȩ? for(i=0;i<8;i++ ) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive<<=1; if(READ_SDA)receive++; delay_us(1); } if (!ack) IIC_NAck();//d©?ȪnACK else IIC_Ack(); //d©?ȪACK return receive; } void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr) { IIC_Start(); if(device_addr==0xA0) //eepromnj??d¤ȮȮȲ1??Ȳ IIC_Send_Byte(0xA0 + ((addr/256)<<1));//d©?Ȫ??nj??d else IIC_Send_Byte(device_addr); //d©?‚?tnj??d IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF); //d©?ȪnjȪnj??d IIC_Wait_Ack(); IIC_Send_Byte(data); //d©?Ȫ??Ȳ IIC_Wait_Ack(); IIC_Stop();//2ȲȦȲȰ???Ȫª?1Ȭ??t if(device_addr==0xA0) // delay_ms(10); else delay_us(2); } uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead) //?Ȣ??¤??‚?Ȱ?ȢȺy?Y { uint16_t data; IIC_Start(); if(device_addr==0xA0) IIC_Send_Byte(0xA0 + ((addr/256)<<1)); else IIC_Send_Byte(device_addr); IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF); //d©?ȪnjȪnj??d IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(device_addr+1); //d©?‚?tnj??d IIC_Wait_Ack(); if(ByteNumToRead == 1)//LM75???ȨȺy?Y?a11bit { data=IIC_Read_Byte(0); } else { data=IIC_Read_Byte(1); data=(data<<8)+IIC_Read_Byte(0); } IIC_Stop();//2ȲȦȲȰ???Ȫª?1Ȭ??t return data; } /********** *Ȧ???2?d??aIO?Ȳ?ª?ȦI2C???? * *¤Ȯ?aȰ????aȺ??aAHT20nj?????I2C *oeȺy??ȮDIICoȪI2Cnj???€eª???©Ȱaª?ª?ª?ª?ª? * *2020/2/23?oȮDT??Ȩ??Ȳ * ***********/ void read_AHT20_once(void) { delay_ms(10); reset_AHT20(); delay_ms(10); init_AHT20(); delay_ms(10); startMeasure_AHT20(); delay_ms(80); read_AHT20(); delay_ms(5); } void reset_AHT20(void) { I2C_Start(); I2C_WriteByte(0x70); ack_status = Receive_ACK(); //if(ack_status) printf("1"); //else printf("1-n-"); I2C_WriteByte(0xBA); ack_status = Receive_ACK(); //if(ack_status) printf("2"); //else printf("2-n-"); I2C_Stop(); /* AHT20_OutData[0] = 0; AHT20_OutData[1] = 0; AHT20_OutData[2] = 0; AHT20_OutData[3] = 0; */ } void init_AHT20(void) { I2C_Start(); I2C_WriteByte(0x70); ack_status = Receive_ACK(); //if(ack_status) printf("3"); //else printf("3-n-"); I2C_WriteByte(0xE1); ack_status = Receive_ACK(); //if(ack_status) printf("4"); //else printf("4-n-"); I2C_WriteByte(0x08); ack_status = Receive_ACK(); //if(ack_status) printf("5"); //else printf("5-n-"); I2C_WriteByte(0x00); ack_status = Receive_ACK(); //if(ack_status) printf("6"); //else printf("6-n-"); I2C_Stop(); } void startMeasure_AHT20(void) { //------------ I2C_Start(); I2C_WriteByte(0x70); ack_status = Receive_ACK(); //if(ack_status) printf("7"); //else printf("7-n-"); I2C_WriteByte(0xAC); ack_status = Receive_ACK(); //if(ack_status) printf("8"); //else printf("8-n-"); I2C_WriteByte(0x33); ack_status = Receive_ACK(); //if(ack_status) printf("9"); //else printf("9-n-"); I2C_WriteByte(0x00); ack_status = Receive_ACK(); //if(ack_status) printf("10"); //else printf("10-n-"); I2C_Stop(); } void read_AHT20(void) { uint8_t i; for(i=0; i<6; i++) { readByte[i]=0; } //------------- I2C_Start(); I2C_WriteByte(0x71); ack_status = Receive_ACK(); readByte[0]= I2C_ReadByte(); Send_ACK(); readByte[1]= I2C_ReadByte(); Send_ACK(); readByte[2]= I2C_ReadByte(); Send_ACK(); readByte[3]= I2C_ReadByte(); Send_ACK(); readByte[4]= I2C_ReadByte(); Send_ACK(); readByte[5]= I2C_ReadByte(); SendNot_Ack(); //Send_ACK(); I2C_Stop(); //-------------- if( (readByte[0] & 0x68) == 0x08 ) { H1 = readByte[1]; H1 = (H1<<8) | readByte[2]; H1 = (H1<<8) | readByte[3]; H1 = H1>>4; H1 = (H1*1000)/1024/1024; T1 = readByte[3]; T1 = T1 & 0x0000000F; T1 = (T1<<8) | readByte[4]; T1 = (T1<<8) | readByte[5]; T1 = (T1*2000)/1024/1024 - 500; AHT20_OutData[0] = (H1>>8) & 0x000000FF; AHT20_OutData[1] = H1 & 0x000000FF; AHT20_OutData[2] = (T1>>8) & 0x000000FF; AHT20_OutData[3] = T1 & 0x000000FF; } else { AHT20_OutData[0] = 0xFF; AHT20_OutData[1] = 0xFF; AHT20_OutData[2] = 0xFF; AHT20_OutData[3] = 0xFF; //printf("lyy"); } printf("\r\n"); printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10); printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10); printf("\r\n"); } uint8_t Receive_ACK(void) { uint8_t result=0; uint8_t cnt=0; IIC_SCL = 0; SDA_IN(); delay_us(4); IIC_SCL = 1; delay_us(4); while(READ_SDA && (cnt<100)) { cnt++; } IIC_SCL = 0; delay_us(4); if(cnt<100) { result=1; } return result; } void Send_ACK(void) { SDA_OUT(); IIC_SCL = 0; delay_us(4); IIC_SDA = 0; delay_us(4); IIC_SCL = 1; delay_us(4); IIC_SCL = 0; delay_us(4); SDA_IN(); } void SendNot_Ack(void) { SDA_OUT(); IIC_SCL = 0; delay_us(4); IIC_SDA = 1; delay_us(4); IIC_SCL = 1; delay_us(4); IIC_SCL = 0; delay_us(4); IIC_SDA = 0; delay_us(4); } void I2C_WriteByte(uint8_t input) { uint8_t i; SDA_OUT(); for(i=0; i<8; i++) { IIC_SCL = 0; delay_ms(5); if(input & 0x80) { IIC_SDA = 1; //delaymm(10); } else { IIC_SDA = 0; //delaymm(10); } IIC_SCL = 1; delay_ms(5); input = (input<<1); } IIC_SCL = 0; delay_us(4); SDA_IN(); delay_us(4); } uint8_t I2C_ReadByte(void) { uint8_t resultByte=0; uint8_t i=0, a=0; IIC_SCL = 0; SDA_IN(); delay_ms(4); for(i=0; i<8; i++) { IIC_SCL = 1; delay_ms(3); a=0; if(READ_SDA) { a=1; } else { a=0; } //resultByte = resultByte | a; resultByte = (resultByte << 1) | a; IIC_SCL = 0; delay_ms(3); } SDA_IN(); delay_ms(10); return resultByte; } void set_AHT20sendOutData(void) { /* -------------------------- * 0xFA 0x06 0x0A temperature(2 Bytes) humility(2Bytes) short Address(2 Bytes) * And Check (1 byte) * -------------------------*/ AHT20sendOutData[3] = AHT20_OutData[0]; AHT20sendOutData[4] = AHT20_OutData[1]; AHT20sendOutData[5] = AHT20_OutData[2]; AHT20sendOutData[6] = AHT20_OutData[3]; // AHT20sendOutData[7] = (drf1609.shortAddress >> 8) & 0x00FF; // AHT20sendOutData[8] = drf1609.shortAddress & 0x00FF; // AHT20sendOutData[9] = getXY(AHT20sendOutData,10); } void I2C_Start(void) { SDA_OUT(); IIC_SCL = 1; delay_ms(4); IIC_SDA = 1; delay_ms(4); IIC_SDA = 0; delay_ms(4); IIC_SCL = 0; delay_ms(4); } void I2C_Stop(void) { SDA_OUT(); IIC_SDA = 0; delay_ms(4); IIC_SCL = 1; delay_ms(4); IIC_SDA = 1; delay_ms(4); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。