#include "am2303.h" #include "dwt.h" //复位AM2303 void am2303_rst(void) { AM2303_IO_OUT; // SET OUTPUT AM2303_DO_LOW; //拉低DQ ms_delay(20); //拉低至少18ms AM2303_DO_HIGH; // DQ=1 us_delay(30); //主机拉高20~40us } //等待AM2303的回应 //返回1:未检测到AM2303的存在 //返回0:存在 INT8U am2303_check(void) { INT8U retry = 0; AM2303_IO_IN; // SET INPUT while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 1) && retry < 100) // AM2303会拉低40~80us { retry++; us_delay(1); }; if (retry >= 100) return 1; else retry = 0; while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 0) && retry < 100) // AM2303拉低后会再次拉高40~80us { retry++; us_delay(1); }; if (retry >= 100) return 1; return 0; } //从AM2303读取一个位 //返回值:1/0 INT8U am2303_read_bit(void) { INT8U retry = 0; while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 1) && retry < 100) //等待变为低电平 { retry++; us_delay(1); } retry = 0; while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 0) && retry < 100) //等待变高电平 { retry++; us_delay(1); } us_delay(40); //等待40us if (GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 1) return 1; else return 0; } //从AM2303读取一个字节 //返回值:读到的数据 INT8U am2303_read_byte(void) { INT8U i, dat; dat = 0; for (i = 0; i < 8; i++) { dat <<= 1; dat |= am2303_read_bit(); } return dat; } //从AM2303读取一次数据 // temp:温度值(范围:0~50°) // humi:湿度值(范围:20%~90%) //返回值:0,正常;1,读取失败 // INT8U am2303_read_data(INT8U *temp, INT8U *humi) // { // INT8U buf[5]; // INT8U i; // am2303_rst(); // if (am2303_check() == 0) // { // for (i = 0; i < 5; i++) //读取40位数据 // { // buf[i] = am2303_read_byte(); // } // if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) // { // *humi = buf[0]; // *temp = buf[2]; // } // } // else // return 1; // return 0; // } /* ********************************************************************************************************* * 函 数 名: DHT11_ReadData * 功能说明: 复位DHT11。 拉低DQ为低,持续最少480us,然后等待 * 形 参: 无 * 返 回 值: 0 失败; 1 表示成功 ********************************************************************************************************* */ INT8U am2303_read_data(INT8U *temp, INT8U *humi) { INT8U buf[5]; INT8U i; INT8U k; /* 时序: 1. MCU拉低QD持续时间大于 18ms, 然后释放QD = 1 */ /* 1. 主机发送起始信号, DQ拉低时间 > 18ms */ AM2303_DO_LOW; /* DQ = 0 */ ms_delay(20); AM2303_DO_HIGH; /* DQ = 1 */ us_delay(15); /* 等待15us */ /* 2. 等待DQ电平变低 ( 超时100us) */ for (k = 0; k < 10; k++) { if (DQ_IS_LOW()) { break; } us_delay(10); } if (k >= 10) { goto quit; /* 超时无应答,失败 */ } /* 3.等待DQ电平变高 (超时100us) */ for (k = 0; k < 10; k++) { if (!DQ_IS_LOW()) { break; } us_delay(10); } if (k >= 10) { goto quit; /* 超时无应答,失败 */ } /* 4.等待DQ电平变低 (超时100us) */ for (k = 0; k < 10; k++) { if (DQ_IS_LOW()) { break; } us_delay(10); } if (k >= 10) { goto quit; /* 超时无应答,失败 */ } /* 读40bit 数据 */ for (i = 0; i < 5; i++) { buf[i] = DHT11_ReadByte(); } us_delay(100); if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) { *humi = buf[0]; *temp = buf[2]; return 1; } quit: return 0; } //初始化AM2303的IO口 DQ 同时检测AM2303的存在 //返回1:不存在 //返回0:存在 #if 0 INT8U am2303_init(void) { am2303_rst(); //复位AM2303 return am2303_check(); //等待AM2303的回应 } #else INT8U am2303_init(void) { AM2303_DO_LOW; } #endif /* ********************************************************************************************************* * 函 数 名: DHT11_ReadByte * 功能说明: 向DHT11读取1字节数据 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ uint8_t DHT11_ReadByte(void) { /* 写数据时序, 见DHT11 page 16 */ uint8_t i, k; uint8_t read = 0; for (i = 0; i < 8; i++) { read <<= 1; /* 等待DQ电平变高 (超时100us) */ for (k = 0; k < 10; k++) { if (!DQ_IS_LOW()) { break; } us_delay(10); } if (k >= 10) { goto quit; /* 超时无应答,失败 */ } /* 等待DQ电平变低,统计DQ高电平时长 (超时100us) */ for (k = 0; k < 10; k++) { if (DQ_IS_LOW()) { break; } us_delay(10); } if (k > 3) /* 高脉冲持续时间大于40us ,认为是1,否则是0 */ { read++; } } return read; quit: return 0xFF; }