- #include "stm32f10x.h"
- #include "AHT20-21_DEMO_V1_3.h"
- void Delay_N10us(uint32_t t)//延時(shí)函數(shù)
- {
- uint32_t k;
- while(t--)
- {
- for (k = 0; k < 2; k++);//110
- }
- }
- void SensorDelay_us(uint32_t t)//延時(shí)函數(shù)
- {
-
- for(t = t-2; t>0; t--)
- {
- Delay_N10us(1);
- }
- }
- void Delay_4us(void) //延時(shí)函數(shù)
- {
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- }
- void Delay_5us(void) //延時(shí)函數(shù)
- {
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- }
- void Delay_1ms(uint32_t t) //延時(shí)函數(shù)
- {
- while(t--)
- {
- SensorDelay_us(1000);//////延時(shí)1ms
- }
- }
- void AHT20_Clock_Init(void) //延時(shí)函數(shù)
- {
- RCC_APB2PeriphClockCmd(CC_APB2Periph_GPIOB,ENABLE);
- }
- void SDA_Pin_Output_High(void) //將PB15配置為輸出 , 并設(shè)置為高電平, PB15作為I2C的SDA
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,& GPIO_InitStruct);
- GPIO_SetBits(GPIOB,GPIO_Pin_15);
- }
- void SDA_Pin_Output_Low(void) //將P15配置為輸出 并設(shè)置為低電平//SDA配置為浮空輸出
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,& GPIO_InitStruct);
- GPIO_ResetBits(GPIOB,GPIO_Pin_15);
- }
- void SDA_Pin_IN_FLOATING(void) //SDA配置為浮空輸入
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOB,&GPIO_InitStruct);
- }
- void SCL_Pin_Output_High(void) //SCL輸出高電平,P14作為I2C的SCL
- {
- GPIO_SetBits(GPIOB,GPIO_Pin_14);
- }
- void SCL_Pin_Output_Low(void) //SCL輸出低電平
- {
- GPIO_ResetBits(GPIOB,GPIO_Pin_14);
- }
- void Init_I2C_Sensor_Port(void) //初始化I2C接口,輸出為高電平
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,& GPIO_InitStruct);
- GPIO_SetBits(GPIOB,GPIO_Pin_15);//輸出高電平
-
- GPIO_InitTypeDef GPIO_InitStruct;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,& GPIO_InitStruct);
- GPIO_SetBits(GPIOB,GPIO_Pin_15);//輸出高電平
-
- }
- void I2C_Start(void) //I2C主機(jī)發(fā)送START信號(hào)
- {
- 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);
- }
- void AHT20_WR_Byte(uint8_t Byte) //往AHT20寫一個(gè)字節(jié)
- {
- uint8_t Data,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);
- }
- uint8_t AHT20_RD_Byte(void)//從AHT20讀取一個(gè)字節(jié)
- {
- uint8_t Byte,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(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)) a=1;
- Byte = (Byte<<1)|a;
- SCL_Pin_Output_Low();
- Delay_5us();
- }
- SDA_Pin_IN_FLOATING();
- SensorDelay_us(8);
- return Byte;
- }
- uint8_t Receive_ACK(void) //看AHT20是否有回復(fù)ACK
- {
- uint16_t CNT;
- CNT = 0;
- SCL_Pin_Output_Low();
- SDA_Pin_IN_FLOATING();
- SensorDelay_us(8);
- SCL_Pin_Output_High();
- SensorDelay_us(8);
- while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)) && CNT < 100)
- CNT++;
- if(CNT == 100)
- {
- return 0;
- }
- SCL_Pin_Output_Low();
- SensorDelay_us(8);
- return 1;
- }
- void Send_ACK(void) //主機(jī)回復(fù)ACK信號(hào)
- {
- 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);
- }
- void Send_NOT_ACK(void) //主機(jī)不回復(fù)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);
- }
- void Stop_I2C(void) //一條協(xié)議結(jié)束
- {
- SDA_Pin_Output_Low();
- SensorDelay_us(8);
- SCL_Pin_Output_High();
- SensorDelay_us(8);
- SDA_Pin_Output_High();
- SensorDelay_us(8);
- }
- uint8_t AHT20_Read_Status(void)//讀取AHT20的狀態(tài)寄存器
- {
- uint8_t Byte_first;
- I2C_Start();
- AHT20_WR_Byte(0x71);
- Receive_ACK();
- Byte_first = AHT20_RD_Byte();
- Send_NOT_ACK();
- Stop_I2C();
- return Byte_first;
- }
- uint8_t AHT20_Read_Cal_Enable(void) //查詢cal enable位有沒(méi)有使能
- {
- uint8_t val = 0;//ret = 0,
- val = AHT20_Read_Status();
- if((val & 0x68)==0x08)
- return 1;
- else return 0;
- }
- void AHT20_SendAC(void) //向AHT20發(fā)送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校驗(yàn)類型:CRC8/MAXIM
- //多項(xiàng)式:X8+X5+X4+1
- //Poly:0011 0001 0x31
- //高位放到后面就變成 1000 1100 0x8c
- //C現(xiàn)實(shí)代碼:
- uint8_t Calc_CRC8(uint8_t *message,uint8_t Num)
- {
- uint8_t i;
- uint8_t byte;
- uint8_t crc=0xFF;
- for(byte=0; byte<Num; byte++)
- {
- crc^=(message[byte]);
- for(i=8;i>0;--i)
- {
- if(crc&0x80) crc=(crc<<1)^0x31;
- else crc=(crc<<1);
- }
- }
- return crc;
- }
- void AHT20_Read_CTdata(uint32_t *ct) //沒(méi)有CRC校驗(yàn),直接讀取AHT20的溫度和濕度數(shù)據(jù)
- {
- volatile uint8_t Byte_1th=0;
- volatile uint8_t Byte_2th=0;
- volatile uint8_t Byte_3th=0;
- volatile uint8_t Byte_4th=0;
- volatile uint8_t Byte_5th=0;
- volatile uint8_t Byte_6th=0;
- uint32_t RetuData = 0;
- uint16_t cnt = 0;
- AHT20_SendAC();//向AHT10發(fā)送AC命令
- Delay_1ms(80);//延時(shí)80ms左右
- cnt = 0;
- while(((AHT20_Read_Status()&0x80)==0x80))//直到狀態(tài)bit[7]為0,表示為空閑狀態(tài),若為1,表示忙狀態(tài)
- {
- SensorDelay_us(1508);
- if(cnt++>=100)
- {
- break;
- }
- }
- I2C_Start();
- AHT20_WR_Byte(0x71);
- Receive_ACK();
- Byte_1th = AHT20_RD_Byte();//狀態(tài)字,查詢到狀態(tài)為0x98,表示為忙狀態(tài),bit[7]為1;狀態(tài)為0x1C,或者0x0C,或者0x08表示為空閑狀態(tài),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; //溫度
- }
- void AHT20_Read_CTdata_crc(uint32_t *ct) //CRC校驗(yàn)后,讀取AHT20的溫度和濕度數(shù)據(jù)
- {
- volatile uint8_t Byte_1th=0;
- volatile uint8_t Byte_2th=0;
- volatile uint8_t Byte_3th=0;
- volatile uint8_t Byte_4th=0;
- volatile uint8_t Byte_5th=0;
- volatile uint8_t Byte_6th=0;
- volatile uint8_t Byte_7th=0;
- uint32_t RetuData = 0;
- uint16_t cnt = 0;
- // uint8_t CRCDATA=0;
- uint8_t CTDATA[6]={0};//用于CRC傳遞數(shù)組
-
- AHT20_SendAC();//向AHT10發(fā)送AC命令
- Delay_1ms(80);//延時(shí)80ms左右
- cnt = 0;
- while(((AHT20_Read_Status()&0x80)==0x80))//直到狀態(tài)bit[7]為0,表示為空閑狀態(tài),若為1,表示忙狀態(tài)
- {
- SensorDelay_us(1508);
- if(cnt++>=100)
- {
- break;
- }
- }
-
- I2C_Start();
- AHT20_WR_Byte(0x71);
- Receive_ACK();
- CTDATA[0]=Byte_1th = AHT20_RD_Byte();//狀態(tài)字,查詢到狀態(tài)為0x98,表示為忙狀態(tài),bit[7]為1;狀態(tài)為0x1C,或者0x0C,或者0x08表示為空閑狀態(tài),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數(shù)據(jù)
- Send_NOT_ACK(); //注意: 最后是發(fā)送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;//校驗(yàn)錯(cuò)誤返回值,客戶可以根據(jù)自己需要更改
- }//CRC數(shù)據(jù)
- }
- void AHT20_Init(void) //初始化AHT20
- {
- Init_I2C_Sensor_Port();
- I2C_Start();
- AHT20_WR_Byte(0x70);
- Receive_ACK();
- AHT20_WR_Byte(0xa8);//0xA8進(jìn)入NOR工作模式
- Receive_ACK();
- AHT20_WR_Byte(0x00);
- Receive_ACK();
- AHT20_WR_Byte(0x00);
- Receive_ACK();
- Stop_I2C();
- Delay_1ms(10);//延時(shí)10ms左右
- I2C_Start();
- AHT20_WR_Byte(0x70);
- Receive_ACK();
- AHT20_WR_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1
- Receive_ACK();
- AHT20_WR_Byte(0x08);//相關(guān)寄存器bit[3]置1,為校準(zhǔn)輸出
- Receive_ACK();
- AHT20_WR_Byte(0x00);
- Receive_ACK();
- Stop_I2C();
- Delay_1ms(10);//延時(shí)10ms左右
- }
- void JH_Reset_REG(uint8_t addr)
- {
-
- uint8_t Byte_first,Byte_second,Byte_third,Byte_fourth;
- I2C_Start();
- AHT20_WR_Byte(0x70);//原來(lái)是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);//延時(shí)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);//延時(shí)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;
- }
- void AHT20_Start_Init(void)
- {
- JH_Reset_REG(0x1b);
- JH_Reset_REG(0x1c);
- JH_Reset_REG(0x1e);
- }
- int32_t main(void)
- {
- uint32_t CT_data[2];
- volatile int c1,t1;
- /***********************************************************************************/
- /**///①剛上電,產(chǎn)品芯片內(nèi)部就緒需要時(shí)間,延時(shí)100~500ms,建議500ms
- /***********************************************************************************/
- Delay_1ms(500);
- /***********************************************************************************/
- /**///②上電第一次發(fā)0x71讀取狀態(tài)字,判斷狀態(tài)字是否為0x18,如果不是0x18,進(jìn)行寄存器初始化
- /***********************************************************************************/
- if((AHT20_Read_Status()&0x18)!=0x18)
- {
- AHT20_Start_Init(); //重新初始化寄存器
- Delay_1ms(10);
- }
-
- /***********************************************************************************/
- /**///③根據(jù)客戶自己需求發(fā)測(cè)量命令讀取溫濕度數(shù)據(jù),當(dāng)前while(1)循環(huán)發(fā)測(cè)量命令讀取溫濕度數(shù)據(jù),僅供參考
- /***********************************************************************************/
- while(1)
- {
- AHT20_Read_CTdata(CT_data); //不經(jīng)過(guò)CRC校驗(yàn),直接讀取AHT20的溫度和濕度數(shù)據(jù) 推薦每隔大于1S讀一次
- //AHT20_Read_CTdata_crc(CT_data); //crc校驗(yàn)后,讀取AHT20的溫度和濕度數(shù)據(jù)
-
- c1 = CT_data[0]*100*10/1024/1024; //計(jì)算得到濕度值c1(放大了10倍)
- t1 = CT_data[1]*200*10/1024/1024-500;//計(jì)算得到溫度值t1(放大了10倍)
- ////下一步客戶處理顯示數(shù)據(jù),
- }
- }
復(fù)制代碼- #ifndef _AHT20_DEMO_
- #define _AHT20_DEMO_
- #include "stm32f10x.h"
- void Delay_N10us(uint32_t t);//延時(shí)函數(shù)
- void SensorDelay_us(uint32_t t);//延時(shí)函數(shù)
- void Delay_4us(void); //延時(shí)函數(shù)
- void Delay_5us(void); //延時(shí)函數(shù)
- void Delay_1ms(uint32_t t);
- void AHT20_Clock_Init(void); //延時(shí)函數(shù)
- void SDA_Pin_Output_High(void) ; //將PB15配置為輸出 , 并設(shè)置為高電平, PB15作為I2C的SDA
- void SDA_Pin_Output_Low(void); //將P15配置為輸出 并設(shè)置為低電平
- void SDA_Pin_IN_FLOATING(void); //SDA配置為浮空輸入
- void SCL_Pin_Output_High(void); //SCL輸出高電平,P14作為I2C的SCL
- void SCL_Pin_Output_Low(void); //SCL輸出低電平
- void Init_I2C_Sensor_Port(void); //初始化I2C接口,輸出為高電平
- void I2C_Start(void); //I2C主機(jī)發(fā)送START信號(hào)
- void AHT20_WR_Byte(uint8_t Byte); //往AHT20寫一個(gè)字節(jié)
- uint8_t AHT20_RD_Byte(void);//從AHT20讀取一個(gè)字節(jié)
- uint8_t Receive_ACK(void); //看AHT20是否有回復(fù)ACK
- void Send_ACK(void) ; //主機(jī)回復(fù)ACK信號(hào)
- void Send_NOT_ACK(void); //主機(jī)不回復(fù)ACK
- void Stop_I2C(void); //一條協(xié)議結(jié)束
- uint8_t AHT20_Read_Status(void);//讀取AHT20的狀態(tài)寄存器
- uint8_t AHT20_Read_Cal_Enable(void); //查詢cal enable位有沒(méi)有使能
- void AHT20_SendAC(void); //向AHT20發(fā)送AC命令
- uint8_t Calc_CRC8(uint8_t *message,uint8_t Num);
- void AHT20_Read_CTdata(uint32_t *ct); //沒(méi)有CRC校驗(yàn),直接讀取AHT20的溫度和濕度數(shù)據(jù)
- void AHT20_Read_CTdata_crc(uint32_t *ct); //CRC校驗(yàn)后,讀取AHT20的溫度和濕度數(shù)據(jù)
- void AHT20_Init(void); //初始化AHT20
- void JH_Reset_REG(uint8_t addr);///重置寄存器
- void AHT20_Start_Init(void);///上電初始化進(jìn)入正常測(cè)量狀態(tài)
復(fù)制代碼
|