⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 质谱仪第3版.c

📁 使用FT245开发的USB接口的质谱仪
💻 C
字号:
//新版2.5
#include 	<reg51.h>
#include 	<absacc.h>
#include 	<intrins.h>
#include 	<IIC.h>
#include    <USB.h>
#define 	uchar 	unsigned char
#define 	uint 	unsigned int
#define		ulong	unsigned long

sbit 	AD_STU=P3^5;//AD的状态位
sbit 	AD_A0=P3^4;//AD的转换信号位
sbit    IO_RAM=P1^7;//高电平选择外设,低电平选择RAM
sbit    LED_RXD=P3^1;//单片机串口发送指示灯



sbit    A16=P1^0;
sbit    A17=P1^1;
sbit    A18=P1^2;//RAM的最高3位地址
uint	RAMadd=0;//RAM的19位地址  

uchar 	Control=0;//全局变量的控制字
uchar 	rtControl=0;//当前控制字

//'D'-接受设定值的控制
uchar 	OnTime=0xff;//是否是及时发送,0xff是及时发送,0是储存后发送
uchar 	Page=0;//读取整幅图的总次数0~255
uint 	DelayPage=0;//每幅图之间的延时
uchar 	Segment=0;//每幅图的段数0~255
uint  	Rate=1;//扫描速度,rate越大,速度越慢
uint	PageLength=0;//每幅图的长度

//'C'-采样控制位
uchar	PageCount=0;//图幅计数
uchar 	SegCount=0;//段计数
uchar 	rtPGA=0;//当前的放大倍数

// 'Z'-温度压强控制
uint	Tem_Pre_Point=4096;// 间隔点数
uchar	Pre_PGA=0x0;// 压强的放大倍数0
uchar	Tem_PGA=0x0;// 温度的放大倍数,高字节温度2,低字节温度1
uint	FirstPoint=0;


uint	DELAYSEGMENT=255;//段与段之间的延时

uint 	rtSegPoint=0;//当前的段点位置
uint	rtPoint=0;//全幅图点的位置

uint 	BeginSeg=0,EndSeg=0;//段开始、段结束和放大倍数
uchar 	PGASeg=0;//段放大倍数
//uint 	PageAddress=0;//页地址
uint	rtRAMPoint=0;//存入RAM时的计数器

//延时(thetime)毫秒
void Delay(uint thetime)
{     
	uchar j;
	while (thetime!=0)
   	{
    	thetime--;
      	for(j=0;j<220;j++){}          
	}	    	
}

//延时秒
void Delay_s(uint thetime)
{     
	uchar count;
    while(thetime>0)
	{	
		
		for(count=0;count<10;count++)
		{
			if(Control=='S')return ;
			Delay(100);//延时1秒
		}
		thetime--;
	}
	
}
// 程控放大器的控制
void PGA(uchar gain)
{	
	IO_RAM=1;
	XBYTE[04]=gain;//写入增益大小
}


// 输出控制
void WriteDAC(uint num)
{	
	uint high8;
	high8=num>>8;

	IO_RAM=1;
	XBYTE[01]=high8;//写高四位到锁存器   
	XBYTE[00]=num;//写低八位到锁存器

	
}
//读取RAM低地址的内容
uchar ReadLowRAM(void)
{
	IO_RAM=0;//选中RAM
	A16=0;//RAM的最高位为0
	return XBYTE[RAMadd];//以字节读取内容
}

//向RAM低地址写入数据
void  WriteLowRAM(uchar num)
{	
	IO_RAM=0;
	A16=0;
	XBYTE[RAMadd]=num;
}
//读取RAM高地址的内容
uchar ReadHighRAM(void)
{	
	IO_RAM=0;
	A16=1;
	return	XBYTE[RAMadd];//以字节读取内容	 
}


//向RAM高地址写入数据
void  WriteHighRAM(uchar num)
{	
	IO_RAM=0;
	A16=1;//选中高位
	XBYTE[RAMadd]=num;
}

//系统启动时的初始化工作
void InitSystem(void)
{
	uint i;uchar dat;
	LED_RXD=0;
	A17=0;//如果用HY628100就加上这条语句,如果用628400则不用

	Delay_s(1);
	for(i=0;i<255;i++)
	{
		dat=IIC_RandomRead(i);
		RAMadd=i+0x200;
		WriteHighRAM(dat);
	}

	//读取段与段之间的延时ms
	RAMadd=0x200;//先高位
	DELAYSEGMENT=ReadHighRAM();
	RAMadd=0x201;//后低位 
	DELAYSEGMENT=(DELAYSEGMENT<<8)|ReadHighRAM();

	LED_RXD=1;
	Delay(500);
	LED_RXD=0;
	Delay(500);
	LED_RXD=1;
	Delay(500);
	LED_RXD=0;
	Delay(500);
	LED_RXD=1;//闪烁3次
}

//接受数据的设置
void SetData(void)
{
	uchar 	count=0;//计输入的段数个数
	uchar	Seg;//段的控制点,开始,结束,增益
	uint	PageBeg,PageEnd;//一幅图的开始点,和结束点
	
	Rate=Rec();//扫描速度高8位(1-255);//2
	Rate=Rec()|(Rate<<8);//扫描速度(1-65536);//3
	OnTime=Rec();//接受是否是及时发送位//4
	//if(OnTime!=0)OnTime=0xff;(有主机保证正确)
	Page=Rec();//整幅图的总页数0~255//5
	//if((Page>15)&&(OnTime==0))Page=0;//不允许超过15图(留给主机判断)
	DelayPage=Rec();//每幅图之间的延时//6
	DelayPage=Rec()|(DelayPage<<8);//7
	Segment=Rec();//每幅图的段数0~255//8
	
	// 温度压强处理
	Tem_Pre_Point=Rec()*20;// 压强和温度的监测点间隔
	Tem_PGA=Rec();// 温度的放大设置
	Pre_PGA=Rec();// 压强的放大设置
	
	for(count=0;count<Segment;count++)
	{
		Seg=Rec()&0x0f;//段count起始点高8位
		RAMadd=count;
		if(count==0)PageBeg=Seg;
		WriteHighRAM(Seg);//写入RAM的高位
		Seg=Rec();//段count起始点低8位
		if(count==0)PageBeg=(PageBeg<<8)|Seg;//页的起始点
		WriteLowRAM(Seg);//写入RAM的低位	
	
		Seg=Rec()&0x0f;//段count结束点高8位
		if(count==(Segment-1))PageEnd=Seg;
		RAMadd=count+0x100;
		WriteHighRAM(Seg);//写入RAM的高位
		Seg=Rec();//段count结束点低8位
		if(count==(Segment-1))PageEnd=(PageEnd<<8)|Seg;
		WriteLowRAM(Seg);//写入RAM的低位
		
		Seg=Rec();//段count增益值
		RAMadd=count+0x200;
		WriteLowRAM(Seg);//写入RAM的高位
	}
		// 对压强和温度间隔采样
	if(Tem_Pre_Point<20)Tem_Pre_Point=20;
	RAMadd=0;
	FirstPoint=ReadLowRAM()|(ReadHighRAM()<<8);

	PageLength=PageEnd-PageBeg+1;
	if(Rec()!='d');//Segment=0;//判断是否正常结束
	Sen('F');//回信号起始1
	Sen(OnTime);//2
	Sen(Page);//3
	Sen(DelayPage);//4
	Sen(Segment);//5
	Sen('f');//回信号表示结束//6	
}
// AD 转换
uint AD_Con(void)
{
	//IO_RAM=1;
	uint 	dat;
	//XBYTE[CS_COV]=0;
	//XBYTE[CS_COV]=0;//启动AD转换
	while(AD_STU){};//等待AD转换结束
	AD_A0=0;//读入高八位
	dat=XBYTE[02];
	AD_A0=1;//读入低四位
	dat=(dat<<4)+XBYTE[02];
	return dat;
}
// 读取温度和压强
void Get_Tem_Pre(bit flag)
{
	uint data_temp[4];
	uchar i;
	
	// 读取温度1
	// 设置通道5和放大倍数
	PGA((Tem_PGA<<4)|0x01);// 设置放大倍数
	Delay(Tem_PGA&0xf);
	data_temp[0]=AD_Con();
	

	// 读取压强1
	// 设置通道7和放大倍数
	PGA((Pre_PGA<<4)|0x03);  // 设置放大倍数
	Delay(Pre_PGA&0xf);
	data_temp[1]=AD_Con();
	
	// 读取温度2
	// 设置通道6和放大倍数
	PGA((Tem_PGA&0xf0)|0x02);// 设置放大倍数
	Delay(Tem_PGA>>4);
	data_temp[2]=AD_Con();	

	// 读取压强2
	// 设置通道4和放大倍数
	PGA((Pre_PGA&0xf0)|0x04);// 设置放大倍数
	Delay(Pre_PGA>>4);
	data_temp[3]=AD_Con();
	
	PGA(rtPGA); // 恢复以前的放大倍数

	if(flag)// 直接发送
	{
		Sen('z');
		for(i=0;i<4;i++)
		{
			Sen(data_temp[i]>>8);
			Sen(data_temp[i]);
		}
	}
	else
	{	// 存入内存
		for(i=0;i<4;i++)
		{
			RAMadd=rtRAMPoint+0x400;//生成存入数PageAddress+据的地址
			rtRAMPoint++;//计数存入的地址
			//将数据低8位写到低地址
			WriteLowRAM(data_temp[i]);
			//将数据高8位写到高地址
			WriteHighRAM((data_temp[i]>>8)|0xf0);// 标记
			//将数据高8位写到高地址
		}
	}
}
//测试命令
void Test(void)
{
	Sen('t');//回信号
	///Delay(30);
}

//向EEPROM中写入2402
void Eprom()
{
	uchar dat;//数据
	uint address1;//地址
	
	address1=Rec();//读地址高8位
	address1=Rec()|(address1<<8);//形成16位地址
	dat=Rec();//读数据
	IIC_RandomWrite(address1&0xff,dat);//写入2402
	
	Sen('p');//回信号
	Sen(dat);
	RAMadd=address1+0x200;
	WriteHighRAM(dat);//回写到RAM中

	//读取段与段之间的延时ms
	RAMadd=0x200;//先高位
	DELAYSEGMENT=ReadHighRAM();
	RAMadd=0x201;//后低位
	DELAYSEGMENT=(DELAYSEGMENT<<8)|ReadHighRAM();
}
//读EEPROM2402
void ReadE()
{	
	uchar Low8,datae;
	uint High8;
	High8=Rec();//EEPROM的高位地址
	Low8=Rec();//EEPROM的低位地址
	datae=IIC_RandomRead((High8<<8)|Low8);
	Sen('W');
	Sen(datae);
	Sen('w');
}

//终止命令
void Stop()
{	
	Sen('s');//回信号
	PGA(0);//使放大倍数为1
	WriteDAC(0);//输出为0
	rtControl=0;//当前控制字为零
	Control=0;//清控制字为零

	PageCount=0;//图幅计数
	SegCount=0;//段计数
	rtPGA=0;//当前的放大倍数
 	rtSegPoint=0;//当前的段点位置
 	rtRAMPoint=0;//RAM的位置为零
	rtPoint=0;//全幅图的点
	LED_RXD=1;
}

//提供采样过程中的参数变化
void CollectChange(void)
{
	RAMadd=SegCount+0x200;
	PGASeg=ReadLowRAM();//读取放大倍数
	if(PGASeg!=rtPGA)
	{
		PGA(PGASeg);// 恢复原来的放大倍数
		if(!rtPoint)Delay(PGASeg);//延时,确保放大倍数及时设定
		rtPGA=PGASeg;
	}//若与当前的放大倍数不一样,重新设置
	RAMadd=SegCount;
	BeginSeg=ReadLowRAM()|(ReadHighRAM()<<8);//一段的起始点
	RAMadd=SegCount+0x100;
	EndSeg=ReadLowRAM()|(ReadHighRAM()<<8);//一段的结束点
}

//数据采样
void Collect()
{	
	uint 	datad1=0;	// ad的数据
	uint 	SegOut;		// 段与段之间电压输出
	uint 	i;			// 扫描速度计数

	uint	ADCNum=0;//adc的数据

	ulong	total=0;//ADC的总值
	uchar	BeginDelay=0;	

	if(!rtPoint)
	{
		Sen('c');
		CollectChange();
		if(BeginSeg!=0)BeginDelay=1;
	}
	if(PageCount<Page)//该页没有结束
	{
		if(SegCount<Segment)//该段没有结束
		{	
			rtPoint=rtSegPoint+BeginSeg;//当前点的位置

			if(rtPoint<=EndSeg)
			{	
				// DA输出
				WriteDAC(rtPoint);

				if(BeginDelay)Delay(DELAYSEGMENT);// 起始延时

				for(i=0;i<Rate;i++)//与扫描速度有关
				{
					ADCNum=AD_Con();
					if(Rate>1)total=total+ADCNum;
				}

				if(Rate>1)ADCNum=total/Rate;

				if(OnTime)//及时发送
				{		
					Sen('L');//起始标志 
					Sen((rtPoint>>8)&0xf);//点的位置高8位
					Sen(rtPoint);//点的位置低8位&0xff
					Sen((ADCNum>>8)&0x0f);//数据的高8位
					Sen(ADCNum);//数据的低8位&0xff
						   
					// 发送温度和压强
					if(((rtPoint-FirstPoint)%Tem_Pre_Point)==10)Get_Tem_Pre(1);
				}
				else//存入RAM
				{
					RAMadd=rtRAMPoint+0x400;//生成存入数PageAddress+据的地址
					rtRAMPoint++;//计数存入的地址
				
					WriteLowRAM(ADCNum);//将数据低8位写到低地址
					WriteHighRAM(ADCNum>>8);//将数据高8位写到高地址
					
					// 存入温度和压强,标志是将高4位置1
					if(((rtSegPoint-FirstPoint)%Tem_Pre_Point)==10)Get_Tem_Pre(0);
				}
				rtSegPoint++;
				//LED_AD=1;//关灯
			}
			else //该段结束
			{	
				rtSegPoint=0;
				SegCount++;//段加1
				CollectChange();
				if(SegCount<Segment)//段和页未结束时
				{	
					RAMadd=SegCount;//段计数地址			
					SegOut=ReadLowRAM()|(ReadHighRAM()<<8);//获得段的输出值
					WriteDAC(SegOut);//段与段之间先输出
					//RAMadd=0x200;//段与段之间延时的地址
					Delay(DELAYSEGMENT);//ReadHighRAM());//读出段与段之间的延时
				}
			}
		}	
		else//页结束
		{	
			rtSegPoint=0;
			SegCount=0;
			CollectChange();
			PageCount++;//页加1
			WriteDAC(0);//回到第一点
			if(OnTime)Sen('n');//一页结束标志符
			if((Page-1)){EX0=1;Delay_s(DelayPage);EX0=0;}//页与页之间延时,单位是秒
			//AD_COV=1;AD_COV=0;//新的采样
		}
	}	
	else Stop();//所有结束采样		
}

//读RAM中的内容
void ReadRAM()
{	
	uint addrlow=0,addrhigh=0;//地址的低位和高位
	uint dataRam=0;//数据
	uchar page=0;//图号
	uint point=0;//点	
	uchar i;// 

	page=Rec();//图号,暂时用不到
	addrlow=Rec();//接受地址的高8位
	addrlow=(addrlow<<8)|Rec();//并成12位的起始地址
	addrhigh=Rec();
	addrhigh=(addrhigh<<8)|Rec();//并成12位的终止地址

	Sen('a');//回信号
	point=1;
	while(addrlow<=addrhigh)
	{	
		RAMadd=addrlow;
		if((ReadHighRAM()&0xf0)==0xf0)// 没有温度和压强,发送一个数据
		{
		
			Sen('L');//发送标记
			Sen((point>>8)&0xf);//地址的高8位
			Sen(point);//地址的低8位
			dataRam=ReadHighRAM();
			Sen(dataRam&0x0f);//发数据高8位
			dataRam=ReadLowRAM();
			Sen(dataRam);//发数据低8位
			addrlow++;
			point++;
		}
		else// 有数据和压强,发送2个压强和2个温度数据
		{
			Sen('z');
			for(i=0;i<4;i++)
			{
				RAMadd=addrlow;
				dataRam=ReadHighRAM();
				Sen(dataRam&0x0f);//发数据高8位
				dataRam=ReadLowRAM();
				Sen(dataRam);//发数据低8位
				addrlow++;
				point++;
			}
			
		}
			
	}
	Sen('n');//图结束标志符
	Sen('s');//数据传送结束标志符
}

// 设置温度和压强的放大倍数
void Pre_Tem()
{
	// 温度和放大倍数的设置
	Tem_PGA=Rec();// 温度的放大,高4位温度1,低4位温度2
	Pre_PGA=Rec();// 压强的放大
	Get_Tem_Pre(1);// 发送温度压强数据
}

//主程序
void main()
{	
	WriteDAC(0);//初始化DAC,使之输出为0
	PGA(0);	//设置放大倍数为1
	InitSystem();//系统初始化
	InitSerial();//初始化串口通讯
	while(1)//主循环
	{	
		switch(Control)
		{	
			//读RAM
			case 'A':ReadRAM();Control=0;break;
			//读EEPROM
			case 'M':ReadE();Control=0;break;
			//采样开始命令
			case 'C':Collect();break;                                                                  
			//测试命令
			case 'T':Test();Control=0;break;
			//向EEPROM中写入
			case 'E':Eprom();Control=0;break;
			//设置采样数据
			case 'D':SetData();Control=0;break;
			//终止命令
			case 'S':Stop();break;
			// 压强和温度
			case 'Z':Pre_Tem();Control=0;break;
		}
	}
}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -