本文带来的是基于51单片机的循迹温湿度检测小车。
使用四路红外进行循迹,DH11检测温湿度值,OLED显示
DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。 DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。
DHT11 的技术参数如下:
工作电压范围:3.3V -5.5V
工作电流 :平均 0.5mA
输出:单总线数字信号
测量范围:湿度 20~90%RH,温度 0~50℃
精度 :湿度±5%,温度±2℃
分辨率 :湿度 1%,温度 1℃
DHT11有效总线包含三条,VCC GND DAT,看起来与DS18B20类似,但是简单很多,不需要设置命令,只需要读取数据包就可以了,每次读取数据一共读取40个bit也就是五个字节,高位在前MSB五个字节分别是: 8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据 +8bit校验
话不多说直接上代码!
下面的代码也不知道搁哪抄的,亲测能用
void COM(void)
{
U8 i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!P1_7)&&U8FLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0;
if(P1_7)U8temp=1;
U8FLAG=2;
while((P1_7)&&U8FLAG++);//超时则跳出for循环
if(U8FLAG==1)break;//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
U8comdata<<=1;
U8comdata|=U8temp; //0
}//rof
}
void RH(void)
{
//主机拉低18ms
P1_7=0;
Delay(180);
P1_7=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主机设为输入 判断从机响应信号
P1_7=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!P1_7) //T !
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!P1_7)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((P1_7)&&U8FLAG++);
//数据接收状态
COM();
U8RH_data_H_temp=U8comdata;
COM();
U8RH_data_L_temp=U8comdata;
COM();
U8T_data_H_temp=U8comdata;
COM();
U8T_data_L_temp=U8comdata;
COM();
U8checkdata_temp=U8comdata;
P2_0=1;
//数据校验
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}
}
}
循迹的代码如下(考虑在简单条件下)
void xunji(){
if((hy1==0||hy2==0)&&hy3==1&&hy4==1){PWM(1,3);PWM(2,0);}
else if((hy3==0||hy4==0)&&hy1==1&&hy2==1){PWM(1,0);PWM(2,3);}
else {PWM(1,3);PWM(2,3);}
}
这里面的PWM()函数为输出四个逻辑值与两路PWM值,理论上PWM应放在定时器中断中,这里做简单处理
void PWM(int a,int c){ //aê?μ??ú±ào?£?bê??ù?è //????
if(a==1){
if(c>0){
IN11=1;IN12=0;
if(c>=ti) {ENA=1;} //?y×a
else {ENA=0;}
}
if(c==0){IN11=1;IN12=0;ENA=0;} //í£
if(c<0){
c=(-c);
IN11=0;IN12=1;
if(c>=ti) {ENA=1;} //·′×a
else {ENA=0;}
}
}
if(a==2){
if(c>0){
IN21=1;IN22=0;
if(c>=ti) {ENB=1;} //?y×a
else {ENB=0;}
}
if(c==0){IN21=1;IN22=0;ENB=0;} //í£
if(c<0){
c=(-c);
IN21=0;IN22=1;
if(c>=ti) {ENB=1;} //FAN×a
else {ENB=0;}
}
}
if(ti>=5){
ti=0;
}
ti++;
}
下面是主函数
void main()
{
OLED_Init(); //初始化OLED
OLED_Clear() ;
OLED_ShowCHinese(0,0,0);//温
OLED_ShowCHinese(18,0,1);// 度
OLED_ShowCHinese(0,2,2);// 湿
OLED_ShowCHinese(18,2,3);// 度
while(1)
{
RH();
OLED_ShowNum(65,2,U8RH_data_H,2,16);
OLED_ShowNum(65,0,U8T_data_H,2,16) ;
xunji();
}
}
这里要注意一点,OLED函数及其占用时间,以至于PWM不放在中断,方波的频率低到可怜,这里建议优化一下PWM产生再去使用,演示视频如下
51单片机温湿度循迹小车
提供各种功能小车代做哦