stm32选用的stm32rct6,无线模块选用的是nrf24l01,温度传感器是ds18b20。其中DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温。
温度传感器通过单总线协议与stm32进行通讯,对于温度传感器的就不在介绍了,可以百度它的中文手册。至于单点采集,就是将ds18b20的DQ与STM32的一个管脚相连,然后地接地,VCC接VCC,而采集8个点无非就是将8个温度传感器并联,这里我用到是PE4作为信号线,因为每个ds18b20都有一个独特的64位序列号,从而允许多个ds18b20同时连在一根单总线上。STM32依靠每个温度传感器独有的64位片序列号辨认总线上的器件,对8个点的温度分别进行采集,首先要知道每个ds18b20的序列号,读取序列号的程序如下:
有了这8个序列码,就可以通过匹配序列号的原则,对8个点的温度进行采集。其中匹配程序如下:
void DS18B20_Match_Serial(u8 a)
{
u8 i;
u8 id1[8]={0x28,0xee,0x59,0x52,0x18,0x16,0x02,0x08};
u8 id2[8]={0x28,0xee,0xfb,0x49,0x18,0x16,0x02,0x14};
u8 id3[8]={0x28,0xee,0x36,0x52,0x18,0x16,0x02,0x76};
u8 id4[8]={0x28,0xee,0xa5,0x43,0x18,0x16,0x02,0x38};
u8 id5[8]={0x28,0xee,0x77,0x42,0x18,0x16,0x02,0x6a};
u8 id6[8]={0x28,0xee,0xb8,0x4b,0x18,0x16,0x02,0xb4};
u8 id7[8]={0x28,0xee,0xd4,0x49,0x18,0x16,0x02,0x83};
u8 id8[8]={0x28,0xee,0xce,0x4c,0x18,0x16,0x02,0xc3};
u8 id9[8]={0x28,0xee,0x13,0x4b,0x18,0x16,0x02,0xf7};
u8 id10[8]={0x28,0xee,0xc5,0x44,0x18,0x16,0x02,0xaf};
DS18B20_Reset();
DS18B20_Write_Byte(0X55);//发匹配ROM指令
if(a==1)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id1[i]);
}
else if(a==2)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id2[i]);
}
else if(a==3)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id3[i]);
}
else if(a==4)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id4[i]);
}
else if(a==5)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id5[i]);
}
else if(a==6)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id6[i]);
}
else if(a==7)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id7[i]);
}
else if(a==8)
{
for(i=0;i<8;i++)
DS18B20_Write_Byte(id8[i]);
}
然后就是读取温度值函数:
double DS18B20_Get_wd(u8 b)
{
u8 TL=0,TH=0;
u16 temp=0;
double wd=0;
DS18B20_Reset();//复位
DS18B20_Write_Byte(0xCC); //忽略ROM指令
DS18B20_Match_Serial(b); //进行匹配
DS18B20_Write_Byte(0x44); //得到温度
delay_ms(800);
DS18B20_Reset();
DS18B20_Write_Byte(0xCC);
DS18B20_Match_Serial(b);
DS18B20_Write_Byte(0xBE);
TL=DS18B20_Read_Byte();
TH=DS18B20_Read_Byte();
temp=TH;
temp=(temp<<8)+TL;
if((temp&0xF800)==0xF800)//判断正负
{
temp=~temp;
temp=temp+1;
wd=temp*(-0.0625);
}
else
{
wd=temp*0.0625;
}
return wd;
}
NRF24L01_TX_Mode();//发送模式
while(1)
{
temp1=DS18B20_Get_wd(1);
temp2=DS18B20_Get_wd(2);
temp3=DS18B20_Get_wd(3);
temp4=DS18B20_Get_wd(4);
temp5=DS18B20_Get_wd(5);
temp6=DS18B20_Get_wd(6);
temp7=DS18B20_Get_wd(7);
temp8=DS18B20_Get_wd(8);
sprintf( tmp_buf, "%.1f", temp1);//浮点转字符
sprintf( tmp_buf1, "%.1f", temp2 );
sprintf( tmp_buf2, "%.1f", temp3 );
sprintf( tmp_buf3, "%.1f", temp4);
sprintf( tmp_buf4, "%.1f", temp5 );
sprintf( tmp_buf5, "%.1f", temp6 );
sprintf( tmp_buf6, "%.1f", temp7 );
sprintf( tmp_buf7, "%.1f", temp8 );
strcat(tmp_buf,tmp_buf1);//字符拼接
strcat(tmp_buf,tmp_buf2);
strcat(tmp_buf,tmp_buf3);
strcat(tmp_buf,tmp_buf4);
strcat(tmp_buf,tmp_buf5);
strcat(tmp_buf,tmp_buf6);
strcat(tmp_buf,tmp_buf7);
NRF24L01_TxPacket(tmp_buf);//打包发送
}
NRF24L01_RX_Mode();
while(1)
{
NRF24L01_RxPacket(tmp_buf);//打包接受
delay_ms(1000);//发现不延时的话,VB上位机接受不到数据
printf("%s\r\n",tmp_buf);//发给上位机(96 N 8 1 格式)
}