[$group] 元件库-传感器.$pname$ [$last_ver_update_time] 2021-04-03 [$min_need_ver] 2.1 [$p_list] [$short_show_UIname] [$code_area_type] codes,exe_per_1ms,init_code [$blocks_type] line [$name] [$引脚占用列表,用于提示冲突] [($_xgm$data),type=pin]|.DHT11温湿度传感器已占用data引脚 [$寄存器占用列表,用于提示冲突,但=>后的值没变则不提示冲突] [($_xgm$timer),type=num]|DHT11积木里已占用此定时器号:[($_xgm$timer),type=num] [$中断函数号占用列表,用于提示冲突] [$interrupt_1] [$thread_do] [$run] [$cs] [$function_ref_define_in_headfile] @@file=DHT11.h #define dataPin_$rnd_varname_pre$ [($_xgm$data),type=pin] extern float rec_data_$rnd_varname_pre$[]; extern u16 ccc_max_count; extern u16 ccc_max_count2; void call_back_from_5us_timer_$rnd_varname_pre$(); [$init_code_for_define_area_once] @@file=DHT11.c [$init_code_for_define_area] @@file=DHT11.c #include "io.h" #include "protothread.h" #include "app_process.h" #include "sys/timer.h" #include "Extline_Lib.h" #include "Lib_base.h" //考虑PROCESS2_WAIT_UNTIL宏 #define dataPin_$rnd_varname_pre$ [($_xgm$data),type=pin] u16 ccc_max_count=0; u16 ccc_max_count2=0; float rec_data_$rnd_varname_pre$[2]; void D_OUT_$rnd_varname_pre$() { #get_P口_to_PxM1_PxM0_set_code(group_xml,rand1,block_name,ref_complier,extinfo,"[($_xgm$data),type=pin]","1","DHT11温湿度传感器data信号")% } void D_IN_$rnd_varname_pre$() { #get_P口_to_PxM1_PxM0_set_code(group_xml,rand1,block_name,ref_complier,extinfo,"[($_xgm$data),type=pin]","0","DHT11温湿度传感器data信号")% //old= "0" } extern unsigned long ptTicks2; void delay_10us_$rnd_varname_pre$(u16 time1) { u32 ccc=0; //18 40 80 do { ccc++; } while (ccc<=time1* 3 *#get_1us_delay_num_stm32f10x(group_xml,rand1,block_name,ref_complier,extinfo)% ); /* u32 ssss=ptTicks2; ccc_max_count2=0; do { } while (ptTicks2<=(u32)(ssss+ time1/10) && ccc_max_count2<=4 );//timer_jinque_5us_ccc_$rnd_varname_pre$ 每10us加一 */ } struct timer timer_at_$rnd_varname_pre$; //主机发送开始信号 char DHT11_Start_$rnd_varname_pre$(struct pt *process_pt) { PT_BEGIN(process_pt); D_OUT_$rnd_varname_pre$(); //输出模式 //先拉高 IO_Write(dataPin_$rnd_varname_pre$ ,1) ; delay_10us_$rnd_varname_pre$(12); IO_Write(dataPin_$rnd_varname_pre$ ,0) ; timer_set2(&timer_at_$rnd_varname_pre$, 100*20 );//old=20ms timer_restart2(&timer_at_$rnd_varname_pre$); PROCESS2_WAIT_UNTIL(process_pt , timer_expired2(&timer_at_$rnd_varname_pre$)!=0); IO_Write(dataPin_$rnd_varname_pre$ ,1) ; //拉高电平20~40us delay_10us_$rnd_varname_pre$(30);//old=30us,DHT11官网查询到了V1.3版本的数据手册:需要拉高10-20us D_IN_$rnd_varname_pre$(); //输入模式 PT_END(process_pt); } #define max_waitccc 20 //获取一个字节 char DHT11_Rec_Byte_$rnd_varname_pre$(void) { unsigned char i = 0; unsigned char data; TT_disable_100us_Task_scan_for_other(1);//如果已经执行到这行,说明已经不在任何中断里了??(线程体执行时间大于260us时),所以void SysTick_Handler(void) 里 if(TT_disable_100us_Task_scan_for_other_Flag==0){不成立 data=0; u32 count_high_v_times=0; for(i=0;i<8;i++) //1个数据就是1个字节byte,1个字节byte有8位bit { ccc_max_count=0; while( IO_Read(dataPin_$rnd_varname_pre$) == 0&&ccc_max_count<=max_waitccc){;} //----------------------------- count_high_v_times=0; ccc_max_count=0; while( IO_Read(dataPin_$rnd_varname_pre$) == 1&&ccc_max_count<=max_waitccc){ delay_10us_$rnd_varname_pre$(10); count_high_v_times++; } data <<= 1; //左移 //if( count_high_v_times>=18*#get_1us_delay_num_stm32f10x(group_xml,rand1,block_name,ref_complier,extinfo)% ) //如果过了30us还是高电平的话就是数据1 if(count_high_v_times>=3) { data |= 1; //数据+1 } //ccc_max_count=0; //while( IO_Read(dataPin_$rnd_varname_pre$) == 1&&ccc_max_count<=max_waitccc ){;} //加大到840ms后比400ms稳定, 高电平变低电平,等待高电平结束 } TT_disable_100us_Task_scan_for_other(0); return data; } //获取数据 struct pt pt_DHT11_Start_$rnd_varname_pre$; u8 Drv_Dht11_ConnectCheck_$rnd_varname_pre$ () { u8 tempVar = 0; // 定义临时变量 TT_disable_100us_Task_scan_for_other(1); while ((IO_Read(dataPin_$rnd_varname_pre$) == 1) && tempVar < 10) // DHT11会拉低40~80us { tempVar++; delay_10us_$rnd_varname_pre$(10); }; if(tempVar >= 10) { TT_disable_100us_Task_scan_for_other(0); return 1; } else { tempVar = 0; } while ((IO_Read(dataPin_$rnd_varname_pre$)==0 ) && tempVar < 10) // DHT11拉低后会再次拉高40~80us { tempVar++; delay_10us_$rnd_varname_pre$(10); }; if(tempVar >= 10) { TT_disable_100us_Task_scan_for_other(0); return 1; } tempVar=0; while ((IO_Read(dataPin_$rnd_varname_pre$)==1 ) && tempVar < 10) // 等待拉高完毕 { tempVar++; delay_10us_$rnd_varname_pre$(10); }; if(tempVar >= 10) { TT_disable_100us_Task_scan_for_other(0); return 1; } TT_disable_100us_Task_scan_for_other(0); return 0; } char DHT11_REC_Data_$rnd_varname_pre$(struct pt *process_pt) { PT_BEGIN(process_pt); static unsigned char R_H,R_L,T_H,T_L=0; static unsigned char RH,RL,TH,TL,CHECK=0; call_PT_2_func_without_pm(DHT11_Start_$rnd_varname_pre$,&pt_DHT11_Start_$rnd_varname_pre$); if( Drv_Dht11_ConnectCheck_$rnd_varname_pre$() == 0 ) //判断DHT11是否响应 //if(IO_Read(dataPin_$rnd_varname_pre$)==0) { R_H = DHT11_Rec_Byte_$rnd_varname_pre$(); R_L = DHT11_Rec_Byte_$rnd_varname_pre$(); T_H = DHT11_Rec_Byte_$rnd_varname_pre$(); T_L = DHT11_Rec_Byte_$rnd_varname_pre$(); CHECK = DHT11_Rec_Byte_$rnd_varname_pre$(); //接收5个数据 if((u8)(R_H + R_L + T_H + T_L) == CHECK) //和检验位对比,判断校验接收到的数据是否正确 { RH = R_H; RL = R_L; TH = T_H; TL = T_L; if(RL>=10){ rec_data_$rnd_varname_pre$[0] = (float)RH+(float)RL/100.00; }else{ rec_data_$rnd_varname_pre$[0] = (float)RH+(float)RL/10.00; } if(TL>=10){ rec_data_$rnd_varname_pre$[1] = (float)TH+(float)TL/100.00; }else{ rec_data_$rnd_varname_pre$[1] = (float)TH+(float)TL/10.00; } } } timer_set(&timer_at_$rnd_varname_pre$, 80 );//每次测量需要留出时间间隔,如果短时间(几百毫秒内)多次测量,就会出现这种情况。保证2秒以上的测量间隔,就不会出现这种情况 timer_restart(&timer_at_$rnd_varname_pre$); PROCESS2_WAIT_UNTIL(process_pt , timer_expired(&timer_at_$rnd_varname_pre$)!=0); PT_END(process_pt); } [$init_code_for_init_val] #get_P口_to_PxM1_PxM0_set_code(group_xml,rand1,block_name,ref_complier,extinfo,"[($_xgm$data),type=pin]","1","DHT11温湿度传感器data信号")% IO_Write(dataPin_$rnd_varname_pre$ ,1) ; [$timer0_1ms_code] ccc_max_count++; ccc_max_count2++; [$toolbox_block_code] [$replace_map] $_xgm$data = $field$data,mytype|pin, ptype|TIMES