基于STC89C51的单片机和TLC1543模数转换器的环境指标采集器

本次设计采用TLC1543作为模数转换芯片,STC89C51系列单片机作为主控制器芯片,采集来自变送器(集成传感器)信号线端的电压(依据不同的传感器,可转换为相应的量值输出)。

采集到的数据可实现两种方式传输:1、通过Zigbee实现串口透传(无线传输) 

 2、串口(RS-232)传输(有线)。

软件平台:keil

本设计在8路模拟输入端(AI0~AI7)共地接入了250欧姆的精密电阻,可以采集到传感器的输出电压(0~5V),再通过欧姆定律,得到相应的输出电流。

根据单片机串口传输的字节要求,传输的数据格式设置为十六进制,并且为了得到较准确的电压输出,将电压放大10倍(考虑到十六进制转换为带小数的十进制较复杂。比如处理:实际输出电压为3.5V,处理后的为35V,对应的十六进制为23)。

为了区分采集到的每一路数据,在每路8位十六进制数据之后加上通道标志(8路分别是F0~F7),且数据每隔一秒钟(可修改)送至串口,通过有线或者无线的方式传输。

C语言代码如下:

1、main.c

#include <reg51.h>
#include "channel.h"
#include "math.h"

int Channel8_Data[8]={0,0,0,0,0,0,0,0};
uchar i,j,k,q;
uint t2;
uchar keyNum;
unsigned char	datas[5] = {0, 0, 0, 0, 0};

void Display( int);
void delay(uint);
void flag(uint);
uchar Key_Scan();
void delay1ms(uint);
void UsartConfiguration();		 //"串口通信初始化"


void main()
{
		UsartConfiguration();
		while(1)
		{

		//	for(j=0;j<1;j++)
		//	{
			//	delay1ms(20);//"延迟200ms"
				//Channel8_Data[j]=Ad_vldata(j);
				int a=Ad_vldata(4);	
		//	}
			

		//	for(i=0;i<8;i++)
		//	{	
		//		switch(i)
		//		{
				/*	case(0):
							if(port0==0)
							{
								//Display((Channel8_Data[0]*0.04098-4)*4.375-20);flag(0);delay1ms(1000);break;	  //"温度   没乘以100"
								Display((Channel8_Data[0]*10.000));flag(0);delay1ms(1000);break;	   //"输出电流*10  4——>40"
				 			}
							else
								break;
					  
					case(1):
							if(port1==0)
							{
								//Display((Channel8_Data[1]*0.06944-4)*125);	  //"CO2"
								Display((Channel8_Data[1]*0.04));flag(1);delay1ms(1000);break;
							}
							else
								break;
							*/
			//	case(1):
						//	if(port2==0)
						//	{
								//Display((Channel8_Data[2]*0.04098-4)*0.0625);	  //"大气湿度"
							//	Display((Channel8_Data[0]*0.1));//flag(2);
								Display(a);
								//Channel8_Data[0]=0;
								delay1ms(1000);//break;
						//	}
						//	else
						//		break;
							
				/*		case(3):
							if(port3==0)
							{
								//Display((Channel8_Data[3]*0.04098-4)*0.0625);	  //"土壤湿度"
								Display((Channel8_Data[3]*0.04));flag(3);delay1ms(1000);break;
							}
							else
								break;
							
					case(4):
							if(port4==0)
							{
								//Display((Channel8_Data[4]*0.04098-4)*4.375-20);	  //"土壤温度"
								Display((Channel8_Data[4]*0.04));flag(4);delay1ms(1000);break;
							}
							else
								break;
							
					case(5):
							if(port5==0)
							{
								//Display((Channel8_Data[5]*0.04098-4)*937.5);	  //"盐分电导率"
								Display((Channel8_Data[5]*0.04));flag(5);delay1ms(1000);break;
							}
							else
								break;								 
				
					case(6):
							if(port6==0)
							{
								//Display((Channel8_Data[6]*0.04098-4)*12500);flag(6);delay1ms(1000);break;	  //"照度"
								Display((Channel8_Data[6]*0.04));flag(6);delay1ms(1000);break;
							}
							else
								break;
	
					case(7):
							if(port7==0)
							{
								//Display((Channel8_Data[7]*0.04098-4)*0.875);flag(7);delay1ms(1000);break; 	  //"PH "
								Display((Channel8_Data[7]*0.04));flag(7);delay1ms(1000);break;	
							}
							else
								break;
				*/			
																																			
				//}
			}
			delay1ms(10000);
		}


void delay1ms(uint y)
{
	uint x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}

void Scan_Switch()
{
	
}

void Display( int  tt)
{
	long int  temp;
	temp=tt+0.5;



/*	if(temp< 0)				  
  	{	
		SBUF='-';             //"SBUF在左边,则为发送缓冲区" 
		while(!TI);			  //"等待发送完毕"       
		TI=0;					 	    	
		temp=temp-1;				  //"处理温度"
		temp=~temp;	

  	}
 	else
  	{				
		SBUF='+';
		while(!TI);			       
		TI=0;					

	}
 */
	//"将转化好的温度分别放入数组中,并通过串口传输"	 //"temp传送过的值是实际值*100"

	datas[0] = temp / 1000000;
	datas[1] = temp % 1000000 / 100000;
	datas[2] = temp % 100000 / 10000;
	datas[3] = temp % 10000 / 1000;
	datas[4] = temp % 1000 / 100;
//"小数点后2位"
	datas[5] = temp % 100 / 10;
	datas[6] = temp % 10;

	SBUF = '0'+datas[0];     
	while (!TI);			    		  
	TI = 0;
	
	SBUF = '0'+datas[1];        
	while (!TI);		
	TI = 0;

	SBUF = '0'+datas[2];      	 //"datas[2]为个位   '0'可用于温度补偿"
	while (!TI);			    
	TI = 0;


	SBUF = '0'+datas[3];       
	while (!TI);			  
	TI = 0;

	SBUF = '0'+datas[4];       
	while (!TI);			   
	TI = 0;

	SBUF = '.';            
	while (!TI);			
	TI = 0;

	SBUF = '0'+datas[5];       
	while (!TI);			  
	TI = 0;

	SBUF = '0'+datas[6];       
	while (!TI);			   
	TI = 0;	

/*		t2=tt%100;
		SBUF = t2;
		while (!TI);	        
		TI = 0;
		SBUF = 255;
		while (!TI);	        
		TI = 0;
*/
}

void flag(uint l)
{

		SBUF = 240+l;
		while (!TI);	        
		TI = 0;

}

void UsartConfiguration()		//"串口和定时器初始化"
{
	SCON=0X40;		
	TMOD=0X20;		
	PCON=0X00;		
	TH1=0XFD;			
	TL1=0XFD;
//	ES=1;					
//	EA=1;					
	TR1=1;		//"使能定时器1"	
}
2、channel.c

#include <reg51.h>
#include "channel.h"
#include "intrins.h"
#include "math.h"

uint Ad_vldata(uchar port)
{
	uint ad=0;
	uint i;
	uchar al=0,ah=0;

	AD_clk=0;
	AD_cs=0;
//"取高四位地址	"
	port<<=4;
	for(i=0;i<4;i++)
	{
		AD_add=(bit)(port&0x80);	 //"AD_add为AD地址寄存器"
		AD_clk=1;
		AD_clk=0;
		port<<=1;
	}

//"补全剩下的6个时钟周期"
	for(i=0;i<6;i++)
	{
		AD_clk=1;
		AD_clk=0;	
		//_nop_();  //???
	}
//"10时钟周期完成地址的输送,下面直接采集数据即为当前值"


//"等待转换	  "
	AD_cs=1;
	for(i=0;i<20;i++)
	{
		_nop_();
	}
	AD_cs=0;
	_nop_();_nop_();_nop_();_nop_();  
	//_nop_();

//"获得测量的值"
    for(i=0;i<2;i++)
	{
	 	AD_dat=1;
		AD_clk=1;
		ah<<=1;
		if(AD_dat)  ah|=0x01;
		AD_clk=0;	
	}
    for(i=0;i<8;i++)
	{
	 	AD_dat=1;
		AD_clk=1;
		al<<=1;
		if(AD_dat) al|=0x01;
		AD_clk=0;	
	}	
//" 结束 "
	AD_cs=1;

	ad=(uint)ah;
	ad<<=8;
	ad|=(uint)al;
	
	ad=(ad*0.004887)*100;	  //"(ad*0.004887)实际电压值,转化要*100,为了要测试输出电压"
//	ad=ad*5/1024*100;
	return(ad);	
	
}


3.头文件部分代码

sbit AD_eoc=P3^7;
sbit AD_clk=P3^6;
sbit AD_add=P3^5; //D_IN
sbit AD_dat=P3^4; //D_OUT
sbit AD_cs=P3^3;

/*sbit port0=P1^0;
sbit port1=P1^1;
sbit port2=P1^2;
sbit port3=P1^3;
sbit port4=P1^4;
sbit port5=P1^5;
sbit port6=P1^6;
sbit port7=P1^7;
*/


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值