#include "app_config.h" #include "system/includes.h" #include "os/os_api.h" #include "asm/clock.h" #define TEMP_SAMPLE_TIMER (500) //温度采样时间ms,建议大于100ms以上 #define TEMP_MAX (125) //传感器上限显示温度 #define TEMP_MIN (-55) //传感器下限显示温度 #define TEMP_FILTER_CNT (20) //启动时过滤数据次数(启动时有数据不正常,则需要打开过滤,过滤次数看情况而定) #define TEMP_RANK_NUM (9) //中值滤波使用温度数据个数,冒泡排序过滤大小值,最后取中间值 #define SENSOR_CHECK_CNT (5) //传感器检测失败次数定为传感器掉线 #define USER_FUNC_INT_SRAM 1 //中断处理函数是否放在内部sram #if USER_FUNC_INT_SRAM #define FUNC_IN SEC_USED(.volatile_ram_code) #else #define FUNC_IN #endif #define AWINLINE __attribute__((always_inline)) //单总线硬件IO配置 #define wire_1_bit BIT(7) //IO口,只能寄存器操作 #define DQ_INIT {JL_PORTA->DIR &= ~wire_1_bit;JL_PORTA->PU &= ~wire_1_bit;JL_PORTA->PD &= ~wire_1_bit;}//务必关闭内部上下拉 #define DQ_OUT {JL_PORTA->DIR &= ~wire_1_bit;} #define DQ_IN {JL_PORTA->DIR |= wire_1_bit;} #define DQ_R ((JL_PORTA->IN & wire_1_bit) ? 1 : 0) #define DQ_W_H JL_PORTA->OUT |= wire_1_bit #define DQ_W_L JL_PORTA->OUT &=~ wire_1_bit //#define db_io BIT(0) //IO口,只能寄存器操作 //#define DB_INIT {JL_PORTH->DIR &= ~db_io;JL_PORTH->HD |= db_io;} //#define DB_H JL_PORTH->OUT |= db_io //#define DB_L JL_PORTH->OUT &=~ db_io //#define DB_AND JL_PORTH->OUT ^= db_io enum { TMP_ERR = 0, TMP_NONE, TMP_INIT_START, TMP_INIT_ACK, TMP_INIT_ERR, TMP_INIT_OK, TMP_WTITE_BYTE_START, TMP_WTITE_BYTE_ERR, TMP_WTITE_BYTE_OK, TMP_READ_BYTE_START, TMP_READ_BYTE_ERR, TMP_READ_BYTE_OK, }; enum read_temp_step { STEP_SEND_INIT = 0, STEP_SEND_0XCC1, STEP_SEND_0X44, STEP_SEND_REINIT, STEP_SEND_0XCC2, STEP_SEND_0XBE, STEP_READ_BYT_L, STEP_READ_BYT_H, STEP_READ_DATA_OK, STEP_READ_REDO, }; enum read_temp_am2301_step { STEP_AM_SEND_INIT = 0, STEP_AM_SEND_READ, STEP_AM_SEND_REINIT, STEP_AM_READ_DATA_OK, STEP_AM_READ_REDO, }; enum sensor_type { SENSOR_ERR = -1, SENSOR_NONE = 0, SENSOR_DS1B820, SENSOR_AM2301, }; struct temp_strut { volatile u8 mode_type; volatile u8 mode_cnt; volatile u8 byte_num; volatile u8 temp_h; volatile u8 temp_l; volatile enum read_temp_step read_step; volatile u8 write_data; volatile u8 read_data; volatile u8 wr_bit; u16 temp; u16 filter_cnt; u8 ftemp_rank_id; float ftemp;//温度 float fhumidity;//湿度 volatile float ftemp_rank[TEMP_RANK_NUM]; volatile u8 recv_data[5];//D温湿度传感器 u8 is_ds18b20;//DS1B820温度计 u8 timer_close; char sensor_type; u8 sensor_check; u32 ready_readed_tocnt;//没有被读数据超时计数 } temp_info = {0}; static JL_TIMER_TypeDef *TMR = JL_TIMER4;//选择定时器4 static u8 timer_irq = IRQ_TIMER4_IDX;//选择定时器4 static const u8 timer_index[16] = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15}; static const u32 timer_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; static u32 timer_clk = 0; static FUNC_IN ___interrupt void ds18b20_timer_isr(void); static FUNC_IN ___interrupt void am2301_timer_isr(void); static AWINLINE float temp_rank(float *buff, u8 lenth)//up rank { u8 i, j; float temp; for (i = 0; i < lenth - 1; i++) { for (j = 0; j < lenth - 1 - i; j++) { if (buff[j] > buff[j + 1]) { temp = buff[j + 1]; buff[j + 1] = buff[j]; buff[j] = temp; } } } temp = (lenth % 2) ? buff[lenth / 2] : (buff[lenth / 2] + buff[lenth / 2 - 1]) / 2; return temp;//奇个数返回中间数值,偶个数返回中间2个值平均值 } static AWINLINE void timer_cfg(u32 freq, u32 us) { u32 clock = timer_clk; u8 psc = 0; u8 tmp = 0; u32 prd = 0; u32 ts = us / (1000 * 1000);//计算秒 u32 tu = us % (1000 * 1000);//计算秒剩余us u8 i; float tp = 0; if (freq >= clock) { freq = clock; } else if (freq <= 1) { freq = 1; if (ts) { tp = (float)tu / (1000 * 1000); } } /*求prd值*/ prd = clock / freq; if (prd > 65535) { for (psc = 0; psc < 16; psc++) { prd = (u32)(clock / (timer_table[psc]) / freq); if (prd <= 65535) { break; } else if (psc == 15) { prd = 65535; break; } } } prd = ts ? (prd * ts + tp * prd) : prd; psc = timer_index[psc]; TMR->CON = 0; TMR->CNT = 0; TMR->CON |= BIT(14); TMR->PRD = prd; TMR->CON |= psc << 4; //lsb_clk分频 TMR->CON |= BIT(0); } static AWINLINE void timer_init(u32 us) { u32 freq = 1000000 / us; timer_cfg(freq, us); } /***************************************************************************** DS18B20初始化 *****************************************************************************/ static AWINLINE void temp_mode_reinit(void) { temp_info.byte_num = 0; temp_info.mode_cnt = 0; temp_info.wr_bit = 0; temp_info.timer_close = 0; temp_info.mode_type = TMP_NONE; } static AWINLINE void ds18b20_timer_exit(void) { if (!(TMR->CON & BIT(15))) { TMR->CON &= ~BIT(0); } else { temp_info.timer_close = TRUE; } } static AWINLINE void ds18b20_timer_init(void) { timer_clk = clk_get("timer"); temp_info.sensor_check = 0; temp_info.sensor_type = SENSOR_NONE; temp_info.mode_type = TMP_NONE; temp_info.read_step = STEP_SEND_INIT; temp_mode_reinit(); request_irq(timer_irq, 3, ds18b20_timer_isr, 0); timer_init(50 * 1000); //初始化50ms检测一次设备 } static AWINLINE void ds18b20_io_init(void) { DQ_OUT; DQ_W_H; // printf("ds18b20_io_init\n"); } static AWINLINE void temp_redo_next_time(u32 us) { DQ_OUT; DQ_W_H; timer_init(us);//下次检测温度时间 } static AWINLINE void temp0_reset(void)//高电平空闲信号 { DQ_OUT; timer_init(10 * 1000); //10ms空闲信号 DQ_W_H; } static AWINLINE void temp1_reset_start(void)//启动复位信号 { timer_init(600);//拉低600us复位信号 DQ_W_L; } static AWINLINE void temp2_release_bus(void) { timer_init(65);//释放总线,等待60us (15 - 60us) DQ_IN; } static AWINLINE u8 temp3_reset_get_ack(void)//复位信号从机的ACK是否正常 { u8 ack = !DQ_R; timer_init(480);//等待,最低480us if (!ack) { //检测ACK完成 temp_redo_next_time(50 * 1000); //检测失败,等下一次检测,50ms } return ack; } static AWINLINE void temp4_reset_end(void) { DQ_OUT; DQ_W_H; timer_init(10);//10us后读写字节 } static FUNC_IN u8 ds18b20_init(void) { u8 ret; if (temp_info.mode_type == TMP_INIT_OK) { return TMP_INIT_OK; } temp_info.mode_type = (temp_info.mode_type == TMP_INIT_ACK) ? temp_info.mode_type : TMP_INIT_START; switch (temp_info.mode_cnt) { case 0: temp0_reset(); break; case 1: temp1_reset_start(); break; case 2: temp2_release_bus(); break; case 3: ret = temp3_reset_get_ack(); temp_info.mode_type = ret ? TMP_INIT_ACK : TMP_INIT_ERR; if (!ret) { temp_info.mode_cnt = 0; if (++temp_info.sensor_check > SENSOR_CHECK_CNT) { temp_info.sensor_type = SENSOR_ERR; temp_info.sensor_check = 0; } } break; case 4: temp4_reset_end(); temp_info.mode_type = TMP_INIT_OK; temp_info.mode_cnt = 0; temp_info.sensor_check = 0; temp_info.sensor_type = SENSOR_DS1B820; return temp_info.mode_type; default: break; } temp_info.mode_cnt++; return temp_info.mode_type; } /***************************************************************************** DS18B20读写字节 *****************************************************************************/ static AWINLINE void temp_write_start_bit(void) { DQ_OUT; timer_init(10);//最高15us要拉低 DQ_W_L; } static AWINLINE void temp_write_end_bit(u8 bit) { timer_init(60);//延时60us,60 - 120us if (bit) { DQ_W_H; } else { DQ_W_L; } } static AWINLINE void temp_write_bit_complet(void) { timer_init(10);//5us后继续读写写一个bit,> 1us DQ_W_H; } static AWINLINE void temp_read_start_bit(void) { DQ_OUT; timer_init(1);//要拉低最低1us DQ_W_L; } static AWINLINE void temp_read_release_bus(void) { DQ_IN; timer_init(10);//15us之内采样 } static AWINLINE u8 temp_read_end_bit(void) { u8 bit; bit = DQ_R; timer_init(60);//延时60us,60 - 120us return bit; } static AWINLINE void temp_read_bit_complet(void) { timer_init(10);//10us后继续读写写一个bit,> 1us DQ_OUT; DQ_W_H; } static FUNC_IN u8 ds18b20_write_byte(u8 byte) { if (temp_info.mode_type == TMP_WTITE_BYTE_OK) { return TMP_WTITE_BYTE_OK; } if (!temp_info.mode_cnt && !temp_info.wr_bit) { temp_info.write_data = byte; } temp_info.mode_type = TMP_WTITE_BYTE_START; switch (temp_info.wr_bit) { case 0: temp_write_start_bit(); break; case 1: temp_write_end_bit(temp_info.write_data & 0x1); break; case 2: temp_write_bit_complet(); temp_info.write_data >>= 1; default: break; } temp_info.wr_bit++; if (temp_info.wr_bit > 2) { //最大步骤是0-2 temp_info.mode_cnt++; temp_info.wr_bit = 0; } if (temp_info.mode_cnt >= 8) { temp_info.mode_type = TMP_WTITE_BYTE_OK; temp_info.mode_cnt = 0; temp_info.wr_bit = 0; temp_info.write_data = 0; } return temp_info.mode_type; } static FUNC_IN u8 ds18b20_read_byte(void) { u8 ret; if (temp_info.mode_type == TMP_READ_BYTE_OK) { return TMP_READ_BYTE_OK; } if (!temp_info.mode_cnt && !temp_info.wr_bit) { temp_info.read_data = 0; } temp_info.mode_type = TMP_READ_BYTE_START; switch (temp_info.wr_bit) { case 0: temp_read_start_bit(); temp_info.read_data >>= 1; break; case 1: temp_read_release_bus(); break; case 2: ret = temp_read_end_bit(); temp_info.read_data |= ret ? 0x80 : 0x0; break; case 3: temp_read_bit_complet(); default: break; } temp_info.wr_bit++; if (temp_info.wr_bit > 3) { //最大步骤是0-3 temp_info.mode_cnt++; temp_info.wr_bit = 0; } if (temp_info.mode_cnt >= 8) { temp_info.mode_type = TMP_READ_BYTE_OK; temp_info.mode_cnt = 0; temp_info.wr_bit = 0; temp_info.write_data = 0; } return temp_info.mode_type; } u8 ds18b20_temp_read(float *temp_buf)//线程读取温度数据,temp_buf :温度数据存储地址 { if (temp_info.read_step == STEP_READ_DATA_OK) { //ds18b20温度读取正常 *temp_buf = temp_info.ftemp; temp_info.read_step = STEP_READ_REDO;//重新读取温度标记 return 1; } return 0; } /***************************************************************************** DS18B20中断处理函数 *****************************************************************************/ static FUNC_IN ___interrupt void ds18b20_timer_isr(void) { if (TMR->CON & BIT(15)) { //读取温度步骤 switch (temp_info.read_step) { case STEP_SEND_INIT: ds18b20_init(); //1.初始化 break; case STEP_SEND_0XCC1: ds18b20_write_byte(0xCC); //2,忽略ROM指令 break; case STEP_SEND_0X44: ds18b20_write_byte(0x44); //3.温度转换指令 break; case STEP_SEND_REINIT: ds18b20_init(); //4.初始化 break; case STEP_SEND_0XCC2: ds18b20_write_byte(0xCC); //5.忽略ROM指令 break; case STEP_SEND_0XBE: ds18b20_write_byte(0xBE); //6.读寄存器指令 break; case STEP_READ_BYT_L: ds18b20_read_byte(); //7.读取低字节 break; case STEP_READ_BYT_H: ds18b20_read_byte(); //8.读取高字节 break; case STEP_READ_REDO: temp_info.read_step = STEP_SEND_INIT; if (temp_info.filter_cnt < TEMP_FILTER_CNT || (temp_info.ftemp_rank_id && temp_info.ftemp_rank_id < TEMP_RANK_NUM)) { //启动时过滤,存储在排序BUFF快速读取 timer_init(2 * 1000); //2ms快速过滤 } else { timer_init(TEMP_SAMPLE_TIMER * 1000); //下次检测温度时间 } break; default: break; } //读写一个字节结果分析 switch (temp_info.mode_type) { case TMP_INIT_OK: if (temp_info.read_step == STEP_SEND_INIT) { temp_info.read_step = STEP_SEND_0XCC1; } else { temp_info.read_step = STEP_SEND_0XCC2; } temp_mode_reinit(); break; case TMP_WTITE_BYTE_OK: if (temp_info.read_step == STEP_SEND_0XCC1) { temp_info.read_step = STEP_SEND_0X44; } else if (temp_info.read_step == STEP_SEND_0X44) { temp_info.read_step = STEP_SEND_REINIT; } else if (temp_info.read_step == STEP_SEND_0XCC2) { temp_info.read_step = STEP_SEND_0XBE; } else if (temp_info.read_step == STEP_SEND_0XBE) { temp_info.read_step = STEP_READ_BYT_L; } temp_mode_reinit(); break; case TMP_READ_BYTE_OK: if (temp_info.read_step == STEP_READ_BYT_L) { temp_info.read_step = STEP_READ_BYT_H; temp_info.temp_l = temp_info.read_data; } else { temp_info.temp_h = temp_info.read_data; temp_info.temp = (temp_info.temp_h << 8) | temp_info.temp_l; temp_info.ftemp = (float)temp_info.temp / 16;//* 0.0625;//温度转换 if ((temp_info.filter_cnt >= TEMP_FILTER_CNT || !TEMP_FILTER_CNT) && //过滤完成或者无过滤 (temp_info.ftemp > TEMP_MIN && temp_info.ftemp < TEMP_MAX)) { //ds18b20温度正常范围 temp_info.ftemp_rank[temp_info.ftemp_rank_id++] = temp_info.ftemp; if (temp_info.ftemp_rank_id >= TEMP_RANK_NUM) { temp_info.read_step = STEP_READ_DATA_OK;//读取完成 temp_info.ftemp = temp_rank(temp_info.ftemp_rank, TEMP_RANK_NUM);//中值滤波 temp_info.ftemp_rank_id = 0; } else { temp_info.read_step = STEP_READ_REDO;//重新检测 } temp_redo_next_time(2 * 1000); } else { if (TEMP_FILTER_CNT) { temp_info.filter_cnt++; } temp_info.read_step = STEP_READ_REDO;//重新检测 temp_redo_next_time(10 * 1000); //10ms后检测线程是否读取温度结果 } } temp_mode_reinit(); break; case TMP_ERR: case TMP_INIT_ERR: case TMP_WTITE_BYTE_ERR: case TMP_READ_BYTE_ERR: temp_info.read_step = STEP_SEND_INIT; temp_info.filter_cnt = 0; temp_info.ftemp_rank_id = 0; temp_mode_reinit(); temp_redo_next_time(50 * 1000); //下次检测温度 break; default : break; } if (temp_info.timer_close) { temp_info.timer_close = 0; TMR->CON &= ~BIT(0); } TMR->CON |= BIT(14); } } /*************************************************************************************************************************************************************/ /***************************************************************************** AM2301初始化 *****************************************************************************/ #define AM2301_DATA_L_TIMER 58 //数据0/1低电平时间58 - 62 us,取最小值,示波器抓出来的,文档不对应 #define AM2301_DATA1_H_TIMER 72 //数据1高电平时间72 - 76 us,取最小值,示波器抓出来的,文档不对应 static AWINLINE void am2301_timer_init(void) { timer_clk = clk_get("timer"); temp_info.sensor_check = 0; temp_info.sensor_type = SENSOR_NONE; temp_info.mode_type = TMP_NONE; temp_info.read_step = STEP_AM_SEND_INIT; temp_mode_reinit(); request_irq(timer_irq, 3, am2301_timer_isr, 0); timer_init(50 * 1000); //初始化100ms检测一次设备 } static AWINLINE void am2301_timer_exit(void) { if (!(TMR->CON & BIT(15))) { TMR->CON &= ~BIT(0); } else { temp_info.timer_close = TRUE; } } static AWINLINE void am2301_io_init(void) { DQ_OUT; DQ_W_H; // printf("am2301_io_init\n"); } static AWINLINE void am2301_temp_redo_next_time(u32 us) { DQ_OUT; DQ_W_H; timer_init(us);//下次检测温度时间 } static AWINLINE void am2301_temp0_reset(void)//高电平空闲信号 { timer_init(10 * 1000); //10ms空闲信号 DQ_OUT; DQ_W_H; } static AWINLINE void am2301_temp1_reset_start(void)//启动复位信号 { timer_init(1000);//拉低>800us复位信号 DQ_W_L; } static AWINLINE void am2301_temp2_release_bus(void)//启动复位信号 { timer_init(30);//释放总线,等待30us DQ_IN; } static AWINLINE void am2301_temp3_delay(void) { timer_init(40);//40us后读取从机的低电平 } static AWINLINE u8 am2301_temp4_read_lack(void) { u8 ack = !DQ_R; if (ack) { timer_init(80);//80us后读取从机的高电平 } else { timer_init(50 * 1000); //ACK失败,100ms后测尝试 } return ack; } static AWINLINE u8 am2301_temp5_read_hack(void) { u8 ack = DQ_R; if (ack) { timer_init(40 + AM2301_DATA_L_TIMER / 2); //65us后读取第一位数据信号的低电平时间 } else { timer_init(50 * 1000); //ACK失败,100ms后测尝试 } return ack; } static AWINLINE void am2301_temp6_first_bit_l(void) { #if USER_FUNC_INT_SRAM timer_init(AM2301_DATA_L_TIMER / 2 + 26 + AM2301_DATA_L_TIMER / 2); //76us后读取第一位数据 #else timer_init(AM2301_DATA_L_TIMER / 2 + 26 + AM2301_DATA_L_TIMER / 2 - 30); //函数放在flash需要减去30us #endif } static FUNC_IN u8 am2301_init(void) { u8 ret; if (temp_info.mode_type == TMP_INIT_OK) { return TMP_INIT_OK; } temp_info.mode_type = (temp_info.mode_type == TMP_INIT_ACK) ? temp_info.mode_type : TMP_INIT_START; switch (temp_info.mode_cnt) { case 0: am2301_temp0_reset(); break; case 1: am2301_temp1_reset_start(); break; case 2: am2301_temp2_release_bus(); break; case 3: am2301_temp3_delay(); break; case 4: ret = am2301_temp4_read_lack(); temp_info.mode_type = ret ? TMP_INIT_ACK : TMP_INIT_ERR; if (!ret) { temp_info.mode_cnt = 0; if (++temp_info.sensor_check > SENSOR_CHECK_CNT) { temp_info.sensor_type = SENSOR_ERR; temp_info.sensor_check = 0; } return temp_info.mode_type; } break; case 5: ret = am2301_temp5_read_hack(); temp_info.mode_type = ret ? TMP_INIT_ACK : TMP_INIT_ERR; if (!ret) { temp_info.mode_cnt = 0; if (++temp_info.sensor_check > SENSOR_CHECK_CNT) { temp_info.sensor_type = SENSOR_ERR; temp_info.sensor_check = 0; } return temp_info.mode_type; } break; case 6: am2301_temp6_first_bit_l(); temp_info.mode_type = TMP_INIT_OK; temp_info.mode_cnt = 0; temp_info.sensor_check = 0; temp_info.sensor_type = SENSOR_AM2301; return temp_info.mode_type; break; default: break; } temp_info.mode_cnt++; return temp_info.mode_type; } static AWINLINE u8 am2301_temp_read_bit(void) { u8 bit; bit = DQ_R; if (bit) { timer_init(((AM2301_DATA1_H_TIMER - 26 - (AM2301_DATA_L_TIMER / 2)) + AM2301_DATA_L_TIMER / 2) + (AM2301_DATA_L_TIMER / 2 + 26 + AM2301_DATA_L_TIMER / 2) + ((temp_info.wr_bit) ? 1 : 0) + temp_info.wr_bit / 2); //((temp_info.wr_bit) ? 1 : 0) + temp_info.wr_bit / 2 属于补偿 } else { timer_init(AM2301_DATA_L_TIMER / 2 + 26 + AM2301_DATA_L_TIMER / 2 + ((temp_info.wr_bit % 3 == 0) ? 1 : 0)); //((temp_info.wr_bit % 3 == 0) ? 1 : 0) 属于补偿 } return bit; } static FUNC_IN u8 am2301_read_bytes(void) { if (temp_info.mode_type == TMP_READ_BYTE_OK) { return TMP_READ_BYTE_OK; } if (!temp_info.byte_num && !temp_info.wr_bit) { temp_info.read_data = 0; } temp_info.mode_type = TMP_READ_BYTE_START; temp_info.read_data <<= 1; temp_info.read_data |= am2301_temp_read_bit() ? 0x1 : 0x0; temp_info.wr_bit++; if (temp_info.wr_bit >= 8) { temp_info.recv_data[temp_info.byte_num] = temp_info.read_data; temp_info.read_data = 0; temp_info.wr_bit = 0; temp_info.byte_num++; if (temp_info.byte_num >= 5) { temp_info.byte_num = 0; temp_info.mode_type = TMP_READ_BYTE_OK; timer_init(50 * 1000); } } return temp_info.mode_type; } u8 am2301_read(float *temp, float *humidity)//线程读取温度数据,temp_buf :温度数据存储地址 { if (temp_info.read_step == STEP_AM_READ_DATA_OK) { //ds18b20温度读取正常 *temp = temp_info.ftemp; *humidity = temp_info.fhumidity; temp_info.read_step = STEP_AM_READ_REDO;//重新读取温度标记 return 1; } return 0; } /***************************************************************************** AM2301中断处理函数 *****************************************************************************/ static FUNC_IN ___interrupt void am2301_timer_isr(void) { if (TMR->CON & BIT(15)) { //读取温湿度步骤 switch (temp_info.read_step) { case STEP_AM_SEND_INIT: am2301_init();//1 . 初始化 break; case STEP_AM_SEND_READ: am2301_read_bytes();//2 . 读40字节 break; case STEP_AM_READ_REDO: temp_info.read_step = STEP_AM_SEND_INIT; temp_mode_reinit(); temp_redo_next_time(3 * 1000 * 1000); //3S再次读取 break; case STEP_AM_READ_DATA_OK: ; u8 to_s = 10;//10s没有读取则重新读取 if (temp_info.ready_readed_tocnt > (((to_s * 1000) / 100) * 2)) { //10s重新读取 temp_info.ready_readed_tocnt = 0; temp_info.read_step = STEP_AM_SEND_INIT; temp_mode_reinit(); } else if (!temp_info.ready_readed_tocnt) { temp_redo_next_time(100 * 1000); //100ms检测是否读取温度 } temp_info.ready_readed_tocnt++; break; default: break; } switch (temp_info.mode_type) { case TMP_INIT_OK: if (temp_info.read_step == STEP_AM_SEND_INIT) { temp_info.read_step = STEP_AM_SEND_READ; } break; case TMP_READ_BYTE_OK: ; short hum = 0, tmp = 0, check_sum = 0, sum = 0; hum = ((temp_info.recv_data[0] << 8) | temp_info.recv_data[1]) & 0xFFFF; tmp = ((temp_info.recv_data[2] << 8) | temp_info.recv_data[3]) & 0xFFFF; temp_info.ftemp = (float)tmp / 10;//温度 temp_info.fhumidity = (float)hum / 10;//湿度 sum = temp_info.recv_data[0] + temp_info.recv_data[1] + temp_info.recv_data[2] + temp_info.recv_data[3]; check_sum = temp_info.recv_data[4]; check_sum |= (sum > 255) ? (sum & 0xFF00) : 0;//数据校验,超255,高8位用sum的,传感器BUG if (check_sum == sum) { temp_info.read_step = STEP_AM_READ_DATA_OK; } else { temp_info.read_step = STEP_AM_READ_REDO;//重新读取温度标记 printf("AM3201 data check sum err\n"); } temp_info.mode_type = TMP_NONE; temp_info.ready_readed_tocnt = 0; temp_info.recv_data[0] = temp_info.recv_data[1] = temp_info.recv_data[2] = temp_info.recv_data[3] = temp_info.recv_data[4] = 0; temp_redo_next_time(100 * 1000); //100ms检测是否读取温度 break; case TMP_ERR: case TMP_INIT_ERR: case TMP_WTITE_BYTE_ERR: case TMP_READ_BYTE_ERR: temp_info.read_step = STEP_AM_SEND_INIT; temp_info.filter_cnt = 0; temp_info.ftemp_rank_id = 0; temp_mode_reinit(); temp_redo_next_time(50 * 1000); //100ms检测是否读取温度 break; default : break; } if (temp_info.timer_close) { temp_info.timer_close = 0; TMR->CON &= ~BIT(0); } TMR->CON |= BIT(14); } } static void temp_app_task(void *priv) { u32 ret; float temp; float humidity; temp_info.is_ds18b20 = TRUE; os_time_dly(100); while (1) { if (temp_info.is_ds18b20) { if (temp_info.sensor_type == SENSOR_ERR) { os_time_dly(10); } ds18b20_io_init(); ds18b20_timer_init(); while (temp_info.sensor_type == SENSOR_NONE) { os_time_dly(2); } if (temp_info.sensor_type == SENSOR_ERR) { printf("DS18B20 check err\n\n"); ds18b20_timer_exit(); } } if (temp_info.sensor_type == SENSOR_DS1B820) { while (1) { ret = ds18b20_temp_read(&temp);//获取温度结果 if (ret) { //ds18b20温度读取正常 /* 做显示等...... */ printf("---> DS18B20 : temp = %f \n", temp); } if (temp_info.sensor_type == SENSOR_ERR) { ds18b20_timer_exit(); temp_info.is_ds18b20 = 0; break; } os_time_dly(10); //延时100ms以上释放CPU } } else { if (temp_info.sensor_type == SENSOR_ERR) { os_time_dly(10); } am2301_io_init(); am2301_timer_init(); while (temp_info.sensor_type == SENSOR_NONE) { os_time_dly(2); } if (temp_info.sensor_type == SENSOR_ERR) { printf("AM3201 check err \n\n"); am2301_timer_exit(); } while (1) { ret = am2301_read(&temp, &humidity);//获取温度结果 if (ret) { //ds18b20温度读取正常 /* 做显示等...... */ printf("---> AM3201 : temp = %f ,humidity = %f\n", temp, humidity); } if (temp_info.sensor_type == SENSOR_ERR) { am2301_timer_exit(); temp_info.is_ds18b20 = TRUE; break; } os_time_dly(00); //延时100ms以上释放CPU } } } } static int temp_init(void *priv) { return os_task_create(temp_app_task, NULL, 16, 512, 0, "temp_app_task"); // return thread_fork("temp_app_task", 16, 512, 0, 0, temp_app_task, (void *)NULL); } late_initcall(temp_init);