✅ 操作成功!

iic协议

发布时间:2023-06-07 作者:admin 来源:文学

iic协议

iic协议

法官的英文-学生自我陈述报告

2023年2月22日发(作者:付琳)

STC8a8k64d4开发DHT20(IIC通讯协议)

STC8a8k64d4开发DHT20(IIC通讯协议)

注:在此⽤的晶振位22.1184Mhz,其他型号单⽚机相关延时函数请修改。

``

1、与DHT20通讯

DHT20.c

#include"DHT20.h"

sbitDHT20_SDA=P2^0;

sbitDHT20_SCL=P2^1;

u16DHT11Data[DHT11_DATA_SIZE];

staticvoidDelay1us()//@22.1184MHz

{

unsignedchari;

_nop_();

i=5;

while(--i);

}

staticvoidSensorDelay_us(u16t)//延时函数

{

u16i;

for(i=0;i

{

Delay1us();

}

}

staticvoidDelay_4us(void)//延时函数

{

unsignedchari;

_nop_();

i=27;

while(--i);

}

staticvoidDelay_5us(void)//延时函数

{

unsignedchari;

i=35;

while(--i);

}

voidDHT20_Delay1ms()//@22.1184MHz

{

unsignedchari,j;

i=29;

j=183;

do

{

while(--j);

}while(--i);

}while(--i);

}

voidDelay_1ms(u16t)//延时函数

{

while(t--)

{

DHT20_Delay1ms();//延时1ms

}

}

voidAHT20_Clock_Init(void)//延时函数

{

//RCC_APB2PeriphClockCmd(CC_APB2Periph_GPIOB,ENABLE);

}

voidSDA_Pin_Output_High(void)//将PB15配置为输出,并设置为⾼电平,PB15作为I2C的SDA

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义

GPIO_=GPIO_Pin_0;//指定要初始化的IO,GPIO_Pin_0~GPIO_Pin_7,或操作SDA

GPIO_=GPIO_OUT_PP;//指定IO的输⼊或输出⽅式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);//初始化

DHT20_SDA=1;

}

voidSDA_Pin_Output_Low(void)//将P15配置为输出并设置为低电平

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义

GPIO_=GPIO_Pin_0;//指定要初始化的IO,GPIO_Pin_0~GPIO_Pin_7,或操作SDA

GPIO_=GPIO_OUT_PP;//指定IO的输⼊或输出⽅式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);//初始化

DHT20_SDA=0;

}

voidSDA_Pin_IN_FLOATING(void)//SDA配置为浮空输⼊

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义

GPIO_=GPIO_Pin_0;//指定要初始化的IO,GPIO_Pin_0~GPIO_Pin_7,或操作SDA

GPIO_=GPIO_HighZ;//指定IO的输⼊或输出⽅式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);//初始化

}

voidSCL_Pin_Output_High(void)//SCL输出⾼电平,P14作为I2C的SCL

{

DHT20_SCL=1;

}

voidSCL_Pin_Output_Low(void)//SCL输出低电平

{

DHT20_SCL=0;

}

voidSCL_INIT(void)

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义

GPIO_=GPIO_Pin_1;//SCL

GPIO_=GPIO_OUT_PP;//指定IO的输⼊或输出⽅式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);//初始化

}

voidInit_I2C_Sensor_Port(void)//初始化I2C接⼝,输出为⾼电平

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义

GPIO_=GPIO_Pin_0;//指定要初始化的IO,GPIO_Pin_0~GPIO_Pin_7,或操作SDA

GPIO_=GPIO_OUT_PP;//指定IO的输⼊或输出⽅式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);//初始化

GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);//初始化

DHT20_SDA=1;

SCL_INIT();

DHT20_SDA=1;

}

staticvoidI2C_Start(void)//I2C主机发送START信号

{

SDA_Pin_Output_High();

SensorDelay_us(8);

SCL_Pin_Output_High();

SensorDelay_us(8);

SDA_Pin_Output_Low();

SensorDelay_us(8);

SCL_Pin_Output_Low();

SensorDelay_us(8);

}

voidAHT20_WR_Byte(u8Byte)//往AHT20写⼀个字节

{

u8Data,N,i;

Data=Byte;

i=0x80;

for(N=0;N<8;N++)

{

SCL_Pin_Output_Low();

Delay_4us();

if(i&Data)

{

SDA_Pin_Output_High();

}

else

{

SDA_Pin_Output_Low();

}

SCL_Pin_Output_High();

Delay_4us();

Data<<=1;

}

SCL_Pin_Output_Low();

SensorDelay_us(8);

SDA_Pin_IN_FLOATING();

SensorDelay_us(8);

}

u8AHT20_RD_Byte(void)//从AHT20读取⼀个字节

{

u8Byte,i,a;

Byte=0;

SCL_Pin_Output_Low();

SDA_Pin_IN_FLOATING();

SensorDelay_us(8);

for(i=0;i<8;i++)

{

SCL_Pin_Output_High();

Delay_5us();

a=0;

if(DHT20_SDA)a=1;

Byte=(Byte<<1)|a;

SCL_Pin_Output_Low();

Delay_5us();

}

}

SDA_Pin_IN_FLOATING();

SensorDelay_us(8);

returnByte;

}

u8Receive_ACK(void)//看AHT20是否有回复ACK

{

u16CNT;

CNT=0;

SCL_Pin_Output_Low();

SDA_Pin_IN_FLOATING();

SensorDelay_us(8);

SCL_Pin_Output_High();

SensorDelay_us(8);

while((DHT20_SDA)&&CNT<100)

CNT++;

if(CNT==100)

{

return0;

}

SCL_Pin_Output_Low();

SensorDelay_us(8);

return1;

}

voidSend_ACK(void)//主机回复ACK信号

{

SCL_Pin_Output_Low();

SensorDelay_us(8);

SDA_Pin_Output_Low();

SensorDelay_us(8);

SCL_Pin_Output_High();

SensorDelay_us(8);

SCL_Pin_Output_Low();

SensorDelay_us(8);

SDA_Pin_IN_FLOATING();

SensorDelay_us(8);

}

voidSend_NOT_ACK(void)//主机不回复ACK

{

SCL_Pin_Output_Low();

SensorDelay_us(8);

SDA_Pin_Output_High();

SensorDelay_us(8);

SCL_Pin_Output_High();

SensorDelay_us(8);

SCL_Pin_Output_Low();

SensorDelay_us(8);

SDA_Pin_Output_Low();

SensorDelay_us(8);

}

voidStop_I2C(void)//⼀条协议结束

{

SDA_Pin_Output_Low();

SensorDelay_us(8);

SCL_Pin_Output_High();

SensorDelay_us(8);

SDA_Pin_Output_High();

SensorDelay_us(8);

}

u8AHT20_Read_Status(void)//读取AHT20的状态寄存器

u8AHT20_Read_Status(void)//读取AHT20的状态寄存器

{

u8Byte_first;

I2C_Start();

AHT20_WR_Byte(0x71);

Receive_ACK();

Byte_first=AHT20_RD_Byte();

Send_NOT_ACK();

Stop_I2C();

returnByte_first;

}

u8AHT20_Read_Cal_Enable(void)//查询calenable位有没有使能

{

u8val=0;//ret=0,

val=AHT20_Read_Status();

if((val&0x68)==0x08)

return1;

elsereturn0;

}

voidAHT20_SendAC(void)//向AHT20发送AC命令

{

I2C_Start();

AHT20_WR_Byte(0x70);

Receive_ACK();

AHT20_WR_Byte(0xac);//0xAC采集命令

Receive_ACK();

AHT20_WR_Byte(0x33);

Receive_ACK();

AHT20_WR_Byte(0x00);

Receive_ACK();

Stop_I2C();

}

//CRC校验类型:CRC8/MAXIM

//多项式:X8+X5+X4+1

//Poly:001100010x31

//⾼位放到后⾯就变成100011000x8c

//C现实代码:

u8Calc_CRC8(u8*message,u8Num)

{

u8i;

u8byte;

u8crc=0xFF;

for(byte=0;byte

{

crc^=(message[byte]);

for(i=8;i>0;--i)

{

if(crc&0x80)crc=(crc<<1)^0x31;

elsecrc=(crc<<1);

}

}

returncrc;

}

voidAHT20_Read_CTdata(u16*ct)//没有CRC校验,直接读取AHT20的温度和湿度数据

{

volatileu8Byte_1th=0;

volatileu8Byte_2th=0;

volatileu8Byte_3th=0;

volatileu8Byte_4th=0;

volatileu8Byte_4th=0;

volatileu8Byte_5th=0;

volatileu8Byte_6th=0;

u16RetuData=0;

u16cnt=0;

AHT20_SendAC();//向AHT10发送AC命令

Delay_1ms(80);//延时80ms左右

cnt=0;

while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表⽰为空闲状态,若为1,表⽰忙状态

{

SensorDelay_us(1508);

if(cnt++>=100)

{

break;

}

}

I2C_Start();

AHT20_WR_Byte(0x71);

Receive_ACK();

Byte_1th=AHT20_RD_Byte();//状态字,查询到状态为0x98,表⽰为忙状态,bit[7]为1;状态为0x1C,或者0x0C,或者0x08表⽰为空闲状态,bit[7]为0

Send_ACK();

Byte_2th=AHT20_RD_Byte();//湿度

Send_ACK();

Byte_3th=AHT20_RD_Byte();//湿度

Send_ACK();

Byte_4th=AHT20_RD_Byte();//湿度/温度

Send_ACK();

Byte_5th=AHT20_RD_Byte();//温度

Send_ACK();

Byte_6th=AHT20_RD_Byte();//温度

Send_NOT_ACK();

Stop_I2C();

RetuData=(RetuData|Byte_2th)<<8;

RetuData=(RetuData|Byte_3th)<<8;

RetuData=(RetuData|Byte_4th);

RetuData=RetuData>>4;

ct[0]=RetuData;//湿度

RetuData=0;

RetuData=(RetuData|Byte_4th)<<8;

RetuData=(RetuData|Byte_5th)<<8;

RetuData=(RetuData|Byte_6th);

RetuData=RetuData&0xfffff;

ct[1]=RetuData;//温度

}

voidAHT20_Read_CTdata_crc(u16*ct)//CRC校验后,读取AHT20的温度和湿度数据

{

volatileu8Byte_1th=0;

volatileu8Byte_2th=0;

volatileu8Byte_3th=0;

volatileu8Byte_4th=0;

volatileu8Byte_5th=0;

volatileu8Byte_6th=0;

volatileu8Byte_7th=0;

u16RetuData=0;

u16cnt=0;

//u8CRCDATA=0;

u8CTDATA[6]={0};//⽤于CRC传递数组

AHT20_SendAC();//向AHT10发送AC命令

Delay_1ms(80);//延时80ms左右

cnt=0;

while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表⽰为空闲状态,若为1,表⽰忙状态

while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表⽰为空闲状态,若为1,表⽰忙状态

{

SensorDelay_us(1508);

if(cnt++>=100)

{

break;

}

}

I2C_Start();

AHT20_WR_Byte(0x71);

Receive_ACK();

CTDATA[0]=Byte_1th=AHT20_RD_Byte();//状态字,查询到状态为0x98,表⽰为忙状态,bit[7]为1;状态为0x1C,或者0x0C,或者0x08表⽰为空闲状态,bit[

7]为0

Send_ACK();

CTDATA[1]=Byte_2th=AHT20_RD_Byte();//湿度

Send_ACK();

CTDATA[2]=Byte_3th=AHT20_RD_Byte();//湿度

Send_ACK();

CTDATA[3]=Byte_4th=AHT20_RD_Byte();//湿度/温度

Send_ACK();

CTDATA[4]=Byte_5th=AHT20_RD_Byte();//温度

Send_ACK();

CTDATA[5]=Byte_6th=AHT20_RD_Byte();//温度

Send_ACK();

Byte_7th=AHT20_RD_Byte();//CRC数据

Send_NOT_ACK();//注意:最后是发送NAK

Stop_I2C();

if(Calc_CRC8(CTDATA,6)==Byte_7th)

{

RetuData=(RetuData|Byte_2th)<<8;

RetuData=(RetuData|Byte_3th)<<8;

RetuData=(RetuData|Byte_4th);

RetuData=RetuData>>4;

ct[0]=RetuData;//湿度

RetuData=0;

RetuData=(RetuData|Byte_4th)<<8;

RetuData=(RetuData|Byte_5th)<<8;

RetuData=(RetuData|Byte_6th);

RetuData=RetuData&0xfffff;

ct[1]=RetuData;//温度

}

else

{

ct[0]=0x00;

ct[1]=0x00;//校验错误返回值,客户可以根据⾃⼰需要更改

}//CRC数据

}

voidAHT20_Init(void)//初始化AHT20

{

Init_I2C_Sensor_Port();

I2C_Start();

AHT20_WR_Byte(0x70);

Receive_ACK();

AHT20_WR_Byte(0xa8);//0xA8进⼊NOR⼯作模式

Receive_ACK();

AHT20_WR_Byte(0x00);

Receive_ACK();

AHT20_WR_Byte(0x00);

Receive_ACK();

Stop_I2C();

Stop_I2C();

Delay_1ms(10);//延时10ms左右

I2C_Start();

AHT20_WR_Byte(0x70);

Receive_ACK();

AHT20_WR_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE,AHT10的初始化命令是0xE1

Receive_ACK();

AHT20_WR_Byte(0x08);//相关寄存器bit[3]置1,为校准输出

Receive_ACK();

AHT20_WR_Byte(0x00);

Receive_ACK();

Stop_I2C();

Delay_1ms(10);//延时10ms左右

}

voidJH_Reset_REG(u8addr)

{

u8Byte_first,Byte_second,Byte_third;

I2C_Start();

AHT20_WR_Byte(0x70);//原来是0x70

Receive_ACK();

AHT20_WR_Byte(addr);

Receive_ACK();

AHT20_WR_Byte(0x00);

Receive_ACK();

AHT20_WR_Byte(0x00);

Receive_ACK();

Stop_I2C();

Delay_1ms(5);//延时5ms左右

I2C_Start();

AHT20_WR_Byte(0x71);//

Receive_ACK();

Byte_first=AHT20_RD_Byte();

Send_ACK();

Byte_second=AHT20_RD_Byte();

Send_ACK();

Byte_third=AHT20_RD_Byte();

Send_NOT_ACK();

Stop_I2C();

Delay_1ms(10);//延时10ms左右

I2C_Start();

AHT20_WR_Byte(0x70);///

Receive_ACK();

AHT20_WR_Byte(0xB0|addr);寄存器命令

Receive_ACK();

AHT20_WR_Byte(Byte_second);

Receive_ACK();

AHT20_WR_Byte(Byte_third);

Receive_ACK();

Stop_I2C();

Byte_second=0x00;

Byte_third=0x00;

}

voidAHT20_Start_Init(void)

{

JH_Reset_REG(0x1b);

JH_Reset_REG(0x1c);

JH_Reset_REG(0x1e);

}

//----------------------------------------------------------------------------------------------

voidDHT20_TASK(void)//这个函数写进循环

{

AHT20_Read_CTdata(DHT11Data);

}

DHT20.h

#ifndef_DHT20_H_

#define_DHT20_H_

#include"APP_ALL_DEVICE.h"

#include"STC8A_GPIO.h"

#defineDHT11_DATA_SIZE30

voidDHT20_TASK(void);

voidDelay_N10us(u16t);//延时函数

voidSensorDelay_us(u16t);//延时函数

voidDelay_4us(void);//延时函数

voidDelay_5us(void);//延时函数

voidDelay_1ms(u16t);

voidAHT20_Clock_Init(void);//延时函数

voidSDA_Pin_Output_High(void);//将PB15配置为输出,并设置为⾼电平,PB15作为I2C的SDA

voidSDA_Pin_Output_Low(void);//将P15配置为输出并设置为低电平

voidSDA_Pin_IN_FLOATING(void);//SDA配置为浮空输⼊

voidSCL_Pin_Output_High(void);//SCL输出⾼电平,P14作为I2C的SCL

voidSCL_Pin_Output_Low(void);//SCL输出低电平

voidInit_I2C_Sensor_Port(void);//初始化I2C接⼝,输出为⾼电平

voidI2C_Start(void);//I2C主机发送START信号

voidAHT20_WR_Byte(u8Byte);//往AHT20写⼀个字节

u8AHT20_RD_Byte(void);//从AHT20读取⼀个字节

u8Receive_ACK(void);//看AHT20是否有回复ACK

voidSend_ACK(void);//主机回复ACK信号

voidSend_NOT_ACK(void);//主机不回复ACK

voidStop_I2C(void);//⼀条协议结束

u8AHT20_Read_Status(void);//读取AHT20的状态寄存器

u8AHT20_Read_Cal_Enable(void);//查询calenable位有没有使能

voidAHT20_SendAC(void);//向AHT20发送AC命令

u8Calc_CRC8(u8*message,u8Num);

voidAHT20_Read_CTdata(u16*ct);//没有CRC校验,直接读取AHT20的温度和湿度数据

voidAHT20_Read_CTdata_crc(u16*ct);//CRC校验后,读取AHT20的温度和湿度数据

voidAHT20_Init(void);//初始化AHT20

voidJH_Reset_REG(u8addr);///重置寄存器

voidAHT20_Start_Init(void);///上电初始化进⼊正常测量状态

#endif

------本⽂代码参考了DHT20官⽅资料

👁️ 阅读量:0