完成了引脚的连接,那么我们就来修改AHT11的代码,这里直接上代码
- #include "DRV_AHT10.h"
- float TempData=0,WetData=0;
- void Delay_N10us(uint32_t t)//延时函数
- {
- uint32_t k;
- while(t--)
- {
- for (k = 0; k < 719; k++)//110
- ;
- }
- }
- void SensorDelay_us(uint32_t t)//延时函数
- {
- t = t-2;
- for(; t>0; t--)
- {
- Delay_N10us(1);
- }
- }
- void Delay_3us(void) //延时函数
- {
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- }
- void Delay_1us(void) //延时函数
- {
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- Delay_N10us(1);
- }
- //--SCL_PA00---SDA-PA01---
- void SDA_Pin_Output_High(void) //将P15配置为输出 , 并设置为高电平, P15作为I2C的SDA
- {
- GPIO_Pins_Set(GPIOB,GPIO_PIN_8);
- }
- void SDA_Pin_Output_Low(void) //将P15配置为输出 并设置为低电平
- {
- GPIO_Pins_Reset(GPIOB,GPIO_PIN_8);
- }
- void SDA_Pin_IN_FLOATING(void) //SDA配置为悬浮输入
- {
-
-
- GPIO_InitType GPIO_InitStructure;
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
- //PA1-PA7-PA9
- GPIO_InitStructure.Pin = GPIO_PIN_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT;
- GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
- GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
-
-
-
- }
- void SDA_Pin_OUT_PP(void) //SDA配置为悬浮输入
- {
- GPIO_InitType GPIO_InitStructure;
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
- //PA1-PA7-PA9
- GPIO_InitStructure.Pin = GPIO_PIN_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
- GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
- GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
- }
- void SCL_Pin_Output_High(void) //SCL输出高电平,P14作为I2C的SCL
- {
- GPIO_Pins_Set(GPIOB,GPIO_PIN_9);
- }
- void SCL_Pin_Output_Low(void) //SCL输出低电平
- {
- GPIO_Pins_Reset(GPIOB,GPIO_PIN_9);
- }
- void Init_I2C_Sensor_Port(void) //初始化I2C接口
- {
-
- GPIO_InitType GPIO_InitStructure;
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
- //--SDA_PB8
- GPIO_InitStructure.Pin = GPIO_PIN_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
- GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
- GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
-
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
- //SCL_PB9
- GPIO_InitStructure.Pin = GPIO_PIN_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
- GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
- GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
-
-
- }
- void I2C_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);
- }
- void ZSSC_I2C_WR_Byte(uint8_t Byte) //往AHT10写一个字节
- {
- uint8_t Data,N,i;
- SDA_Pin_OUT_PP();
- Data=Byte;
- i = 0x80;
- for(N=0;N<8;N++)
- {
- SCL_Pin_Output_Low();
-
- Delay_3us();
-
- if(i&Data)
- {
- SDA_Pin_Output_High();
- }
- else
- {
- SDA_Pin_Output_Low();
- }
-
- SCL_Pin_Output_High();
- Delay_3us();
-
- Data <<= 1;
-
- }
- SCL_Pin_Output_Low();
- SensorDelay_us(8);
- SDA_Pin_IN_FLOATING();
- SensorDelay_us(8);
- }
- uint8_t ZSSC_I2C_RD_Byte(void)//从AHT10读取一个字节
- {
- 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_1us();
- a=0;
- if(GPIO_Input_Pin_Data_Get(GPIOB,GPIO_PIN_8)==PIN_SET)//--读取引脚状态
- {
- a=1;
- }
- Byte = (Byte<<1)|a;
- SCL_Pin_Output_Low();
- Delay_1us();
- }
- SDA_Pin_IN_FLOATING();
- SensorDelay_us(8);
- return Byte;
- }
- uint8_t Receive_ACK(void) //看AHT10是否有回复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_Input_Pin_Data_Get(GPIOB,GPIO_PIN_8)==PIN_SET) && CNT < 100)
- {
- CNT++;
- }
- if(CNT == 100)
- {
- return 0;
- }
- SCL_Pin_Output_Low();
- SensorDelay_us(8);
- return 1;
- }
- void Send_ACK(void) //主机回复ACK信号
- {
-
- SDA_Pin_OUT_PP();
- 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) //主机不回复ACK
- {
- SDA_Pin_OUT_PP();
- 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) //一条协议结束
- {
- SDA_Pin_OUT_PP();
- SDA_Pin_Output_Low();
- SensorDelay_us(8);
- SCL_Pin_Output_High();
- SensorDelay_us(8);
- SDA_Pin_Output_High();
- SensorDelay_us(8);
- }
- uint8_t JH_Read_Status(void)//读取AHT10的状态寄存器
- {
- uint8_t Byte_first;
- I2C_Start();
- ZSSC_I2C_WR_Byte(0x71);
- Receive_ACK();
- Byte_first = ZSSC_I2C_RD_Byte();
-
- Send_NOT_ACK();
- Stop_I2C();
- return Byte_first;
- }
- uint8_t JH_Read_Cal_Enable(void) //查询cal enable位有没有使能?
- {
- uint8_t val = 0;//ret = 0,
-
- val = JH_Read_Status();
- if((val & 0x68)==0x08) //判断NOR模式和校准输出是否有效
- return 1;
- else return 0;
- }
- void JH_SendAC(void) //向AHT10发送AC命令
- {
- I2C_Start();
- ZSSC_I2C_WR_Byte(0x70);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0xac);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0x33);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0x00);
- Receive_ACK();
- Stop_I2C();
- }
- void JH_Send_BA(void)//向AHT10发送BA命令
- {
- I2C_Start();
- ZSSC_I2C_WR_Byte(0x70);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0xba);
- Receive_ACK();
- Stop_I2C();
- }
- void JH_Read_CTdata(uint32_t *ct) //读取AHT10的温度和湿度数据
- {
- 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;
- JH_SendAC();//向AHT10发送AC命令
- SysTick_Delay_Ms(75);//等待75ms
- cnt = 0;
- while(((JH_Read_Status()&0x80)==0x80))//等待忙状态结束
- {
- SensorDelay_us(1508);
- if(cnt++>=100)
- {
- break;
- }
- }
- I2C_Start();
- ZSSC_I2C_WR_Byte(0x71);//0x70+1 0x70为设备地址 1为方向位
- Receive_ACK();
- Byte_1th = ZSSC_I2C_RD_Byte();//状态字
- Send_ACK();
- Byte_2th = ZSSC_I2C_RD_Byte();//湿度字节
- Send_ACK();
- Byte_3th = ZSSC_I2C_RD_Byte();//湿度字节
- Send_ACK();
- Byte_4th = ZSSC_I2C_RD_Byte();//高4位为湿度 低4位为温度
- Send_ACK();
- Byte_5th = ZSSC_I2C_RD_Byte();//温度字节
- Send_ACK();
- Byte_6th = ZSSC_I2C_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;
- }
- unsigned char JH_Init(void) //初始化AHT10
- {
- unsigned int count=0;
- Init_I2C_Sensor_Port();
- SensorDelay_us(11038);
- I2C_Start();
- ZSSC_I2C_WR_Byte(0x70);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0xe1);//写系统配置寄存器
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0x08);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0x00);
- Receive_ACK();
- Stop_I2C();
- SysTick_Delay_Ms(500);//延时0.5S
- while(JH_Read_Cal_Enable()==0)//需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT10,直至Bit[3]=1
- {
-
- JH_Send_BA(); //复位
- SysTick_Delay_Ms(100);
- SensorDelay_us(11038);
- I2C_Start();
- ZSSC_I2C_WR_Byte(0x70);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0xe1);//写系统配置寄存器
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0x08);
- Receive_ACK();
- ZSSC_I2C_WR_Byte(0x00);
- Receive_ACK();
- Stop_I2C();
- count++;
- if(count>=10)
- return 0;
- SysTick_Delay_Ms(500);
- }
- return 1;
- }
- void Get_Data(void)
- {
- uint32_t CT_data[2];
- volatile int c1,t1;
-
- if(0)
- {
- }
- else
- {
-
- while(JH_Read_Cal_Enable()==0)//等到校准输出使能位为1,才读取。
- {
- JH_Init();//如果为0再使能一次
- SysTick_Delay_Ms(50);
- }
- JH_Read_CTdata(CT_data); //读取温度和湿度 , 可间隔1.5S读一次
- c1 = CT_data[0]*1000/1024/1024; //计算得到湿度值(放大了10倍,如果c1=523,表示现在湿度为52.3%)
- t1 = CT_data[1] *200*10/1024/1024-500;//计算得到温度值(放大了10倍,如果t1=245,表示现在温度为24.5℃)
- TempData=t1*0.1;//因为设置了两位小数--
- WetData=c1*0.1;//--放大了两倍----
- }
- }
- #include "n32g401.h"
- #include "bsp_delay.h"
- #include "DRV_UART.h"
- #include "DRV_TIM.h"
- #include "DRV_AHT10.h"
- int main(void)
- {
- LED_Init();
- UART_Init();
- TIM_Init();
- JH_Init(); //初始化AHT10;
- while(1)
- {
- Get_Data();
- printf("TempData is %2f3 %\r\n",TempData);
- printf("WetData is %2f3 %\r\n",WetData);
- SysTick_Delay_Ms(500);
-
- }
- }
测试结果还是比较准确的,我拍了视频,后面上传上来,主要是在办公室,不太好说话,所以大家感受一下结果就行了,感兴趣的话可以自己复制代码去测试。
视频链接:
https://www.bilibili.com/video/BV1AusjeuEL7/?buvid=XU268A1260BC1080F6C5DE9BB8885853A284E&is_story_h5=false&mid=ZPNijV8XOdBxHvi4hyDZnQ%3D%3D&plat_id=240&share_from=ugc&share_medium=android&share_plat=android&share_session_id=34ec3807-b268-440c-a310-66412bf9f865&share_source=WEIXIN&share_tag=s_i&spmid=dt.space-dt.0.0×tamp=1724649027&unique_k=HwCthPZ&up_id=474849000