Bootstrap

Web植物管理系统-下位机部分

本节主要展示上位机部分,采用BSP编程,不附带BSP中各个头文件的说明,仅仅是对main逻辑进行解释


 main.c

上下位机通信

通过串口通信,有两位数据验证头(verify数组中保存对应的数据头 0xAA55)

通信格式

上位发送11字节数据,其中前两位是0xAA55用于数据验证,第三位用于判断当前上位机发送数据的功能

当第三位数据为0x00时,表明当前是验证数据,用于检验串口通信是否成功,若成功返回字节序列 [0xaa ,0x55,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09]

当第三位数据为0x01时,表明当前是收集温度,光照,土壤湿度数据,返回字节序列 [0xaa ,0x55,0x01,0x温度十位,0x温度个位,0x温度小数位,0x光照百位,0x光照十位,0x光照个位,0x,0x电压个位,0x电压小数位]

当第三位数据为0x02时,表明当前是修改温度,光照,土壤湿度阈值

 在函数my1S中定义了收集温度,光照,土壤湿度数据的实现函数,并且通过检验数据是否超过阈值来触发蜂鸣器报警,根据不同的触发条件来发出不同的声音。

全部代码

#include "STC15F2K60S2.H"        //±ØÐë¡£
#include "sys.H"                 //±ØÐë¡£
#include "Uart1.H" 
#include "adc.h"
#include "displayer.H"
#include "Beep.H"
#include "StepMotor.h"

#define N 11

#ifdef _displayer_H_
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01, 0x41, 0x48, 
	              /* ÐòºÅ:   0   1    2	   3    4	    5    6	  7   8	   9	 10	   11		12   13    14     15     */
                /* ÏÔʾ:   0   1    2    3    4     5    6    7   8    9  (ÎÞ)   ÏÂ-  ÖÐ-  ÉÏ-  ÉÏÖÐ-  ÖÐÏÂ-   */  
	                       0x3f|0x80,0x06|0x80,0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80 };  
             /* ´øСÊýµã     0         1         2         3         4         5         6         7         8         9        */
#endif

code unsigned long SysClock=11059200;         //±ØÐë¡£¶¨Òåϵͳ¹¤×÷ʱÖÓƵÂÊ(Hz)£¬Óû§±ØÐëÐ޸ijÉÓëʵ¼Ê¹¤×÷ƵÂÊ£¨ÏÂÔØʱѡÔñµÄ£©Ò»ÖÂ

unsigned char rxdbuf[N],txdbuf[N];
code char verify[2]={0xaa,0x55};
unsigned int s0,s1,s2,s3,s4,s5,s6,s7;
unsigned char limit[8] = {3,7,5,0,9,0,1,0};

int rt_to_tem(unsigned int adc, unsigned char adcbit)
{ code int temtable[32]={2000,1293,1016,866,763,685,621,567,520,477,439,403,370,338,308,278,250,222,194,167,139,111,83,53,22,-11,-4.7,-87,-132,-186,-256,-364};
	unsigned char resh;      //¸ß5bit   ²é±í
	unsigned int resl;       //µÍ11bit  ²åÖµ
		
	resl=adc<<(16-adcbit);         //ÏÈͳһÀ©Õ¹³É16bit
	resh=resl>>11;
	resl=resl & 0x07ff;
	return(temtable[resh]-(((temtable[resh]-temtable[resh+1])*resl)>>11));
}

void check_received_data(void) {
	unsigned int flag = 0;
	unsigned int data_flag = 0;
	unsigned int change_flag = 0;
	
	if(rxdbuf[2] == 0x00) flag = 1;
	if(rxdbuf[2] == 0x01) data_flag = 1;
	if(rxdbuf[2] == 0x02) change_flag = 1;
	
	if(flag){
		txdbuf[0] = 0xaa;
		txdbuf[1] = 0x55;
		txdbuf[2] = 0x00;
		txdbuf[3] = 0x01;
		txdbuf[4] = 0x02;
		txdbuf[5] = 0x03;
		txdbuf[6] = 0x04;
		txdbuf[7] = 0x05;
		txdbuf[8] = 0x06;
		txdbuf[9] = 0x07;
		txdbuf[10] = 0x08;
		Uart1Print(txdbuf, sizeof(txdbuf));
	}if(!flag && data_flag){// 
		txdbuf[0] = 0xaa;
		txdbuf[1] = 0x55;
		txdbuf[2] = 0x01;
		txdbuf[3] = s0;
		txdbuf[4] = s1;
		txdbuf[5] = s2;
		txdbuf[6] = s3;
		txdbuf[7] = s4;
		txdbuf[8] = s5;
		txdbuf[9] = s6;
		txdbuf[10] = s7;
		Uart1Print(txdbuf, sizeof(txdbuf));	
	}if(!flag && change_flag){
		limit[0] = rxdbuf[3];
		limit[1] = rxdbuf[4];
		limit[2] = rxdbuf[5];
		limit[3] = rxdbuf[6];
		limit[4] = rxdbuf[7];
		limit[5] = rxdbuf[8];
		limit[6] = rxdbuf[9];
		limit[7] = rxdbuf[10];
		
		txdbuf[0] = 0xaa;
		txdbuf[1] = 0x55;
		txdbuf[2] = 0x02;
		txdbuf[3] = limit[0];
		txdbuf[4] = limit[1];
		txdbuf[5] = limit[2];
		txdbuf[6] = limit[3];
		txdbuf[7] = limit[4];
		txdbuf[8] = limit[5];
		txdbuf[9] = limit[6];
		txdbuf[10] = limit[7];
		Uart1Print(txdbuf, sizeof(txdbuf));	
	}
}

void my1S()
{	
	static unsigned int temperature_sum=0;
	static unsigned int light_sum = 0;
	static unsigned int voltage_ge_sum = 0;
	static unsigned int voltage_xiaoshu_sum = 0;
	
	static unsigned int count=0;
	int temperature_tem;
	int light_tem;
	int voltage_ge_tem;
	int voltage_xiaoshu_tem;
	
	struct_ADC adcres;
	
	int temperature_shi;
	int temperature_ge;
	int temperature_xiaoshu;
	int temperature;
	int temperature_aac;
	int light_bai;
	int light_shi;
	int light_ge;
	int voltage_ge;
	int voltage_xiaoshu;
	int voltage;
	int i=0;
	adcres=GetADC();
	
	temperature_sum = adcres.Rt;
	temperature_tem = rt_to_tem(temperature_sum,14);
	temperature_shi = temperature_tem/100%10;
	temperature_ge = temperature_tem/10%10;
	temperature_xiaoshu = temperature_tem%10;
	
	temperature = temperature_shi *100 + temperature_ge * 10 + temperature_xiaoshu - 320;
	temperature_shi = (temperature * 10 / 18) /100;
	temperature_ge = (temperature * 10 /18) %100 /10;
	temperature_xiaoshu = (temperature * 10 /18) %10;
	
	s0 = temperature_shi;
	s1 = temperature_ge-2;
	s2 = temperature_xiaoshu;
	
	temperature_aac=s0*10+s1*1+s2*0.1;
	
	light_sum = adcres.Rop;
	light_tem = light_sum;
	light_bai = light_tem%1000/100;
	light_shi = light_tem%100/10;
	light_ge = light_tem%10;
		
	s3 = light_bai;
	s4 = light_shi;
	s5 = light_ge;
		
	voltage_ge_sum = adcres.EXT_P10/50;
	voltage_xiaoshu_sum = adcres.EXT_P10%50/5;
	voltage_ge = voltage_ge_sum;
	voltage_xiaoshu = voltage_xiaoshu_sum;
	
	voltage = (adcres.EXT_P10%1000/100) * 100 + (adcres.EXT_P10%100/10) * 10 + adcres.EXT_P10%10;
	
	s6 = voltage / 50;
	s7 = voltage%50/5;
	
	if(light_sum>90)
	{SetBeep(1000,200);}
	
	if(temperature_aac>38)
		{SetBeep(8000,50);}
		
	if(s6>=3)
	{SetBeep(2000,100);
   P41 &=~ 0X2;
  }
	if(s6<3)
	{
		for( i=0;i<60;i++)
		{
		P41 |= 0X2;
	  }
}
	
		
	Seg7Print(s0,16+s1,s2,s3,s4,s5,16+s6,s7);   //ÿ160mSÏÔʾһ´Îζȣ¬Ã¿´ÎÊÇ16´Î²âÁ¿µÄƽ¾ù tem%10	
}

void main() 
{ 
  Uart1Init(9600);
	AdcInit(ADCexpEXT);  
	DisplayerInit();
	BeepInit();
	StepMotorInit();
	SetDisplayerArea(0,7);
	LedPrint(0);
	
	P41 |= 0X2;
  SetUart1Rxd(rxdbuf, sizeof(rxdbuf), verify, 2);	
	
	SetEventCallBack(enumEventSys1S,my1S);	
	SetEventCallBack(enumEventUart1Rxd, check_received_data);
	
  MySTC_Init();	 
	while(1)             	
		{ 
			MySTC_OS();    
		}	             
}                 

硬件电路连接

扩展了树莓派的自动灌溉模块,链接如下:灌溉元件

元件单独使用的链接图,但是由于我们需要获取实时电压,我们选择将 AO 接入到 P1.0 来做数模转换,与之对应的是对于继电器的 IN 端口,我们采用stc-b板的vcc来给它供电,这是因为电池提供的电压是6v,超过了继电器的 5v 需求,电源只用来给水泵供电。

整体线路图

外加电源

黄色的模块竖串联,横断路

检测单元

驱动模块

;