基于stm32的无线多点温度采集系统设计


            本科时候做过关于ds18b20温度传感器的课程设计,当时好像是先用单片机A采集温度,其中用矩阵键盘设置报警值,然后通过232串口将温度值传给单片机B,单片机B上的数码管显示,同时单片机B的矩阵键盘也可以设置报警值。我当时搞A和B通信这块,至于老师给的分数就不提了。后来学习stm32,想着用stm32通过单总线采集8个ds18b20的值,在通过无线传给另一个stm32,另一个stm32通过串口发给电脑,电脑上的上位机显示8个温度值。

       stm32选用的stm32rct6,无线模块选用的是nrf24l01,温度传感器是ds18b20。其中DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温。

  温度传感器通过单总线协议与stm32进行通讯,对于温度传感器的就不在介绍了,可以百度它的中文手册。至于单点采集,就是将ds18b20的DQ与STM32的一个管脚相连,然后地接地,VCC接VCC,而采集8个点无非就是将8个温度传感器并联,这里我用到是PE4作为信号线,因为每个ds18b20都有一个独特的64位序列号,从而允许多个ds18b20同时连在一根单总线上。STM32依靠每个温度传感器独有的64位片序列号辨认总线上的器件,对8个点的温度分别进行采集,首先要知道每个ds18b20的序列号,读取序列号的程序如下:

  基于stm32的无线多点温度采集系统设计_第1张图片

得到的8个温度传感器的序列号:

基于stm32的无线多点温度采集系统设计_第2张图片

有了这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;
}
然后就是需要把这8个温度值通过无线发给另一个STM32,主要用到NRF24l01模块,一次最多发32个字节。用到的是SPI通讯方式,至于NRF24l01的使用方法和一些例程什么的,大家可以百度或者看一下原子,野火的例子。
基于stm32的无线多点温度采集系统设计_第3张图片
STM32(A)把采集的温度值处理后,发送的程序如下:
	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);//打包发送
					}
STM32(B)接受8个温度值,并且通过串口发给电脑:
NRF24L01_RX_Mode();		  
		while(1)
		{	  		    		    				 
			NRF24L01_RxPacket(tmp_buf);//打包接受
			
			 delay_ms(1000);//发现不延时的话,VB上位机接受不到数据
			  printf("%s\r\n",tmp_buf);//发给上位机(96 N 8 1 格式)
			  }
下位机的事情都完成后,然后就是上位机界面的编写,本人当时在学习VB,就用VB写了个简单的界面,不过大家也可以用Labview写,都可以。

基于stm32的无线多点温度采集系统设计_第4张图片

以上内容,难免有错误与不足之处,大家踊跃拍砖。







你可能感兴趣的:(基于stm32的无线多点温度采集系统设计)