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

📄 ussensor.c

📁 DIY一个属于你的超声波测距传感器程序的构思和设计
💻 C
📖 第 1 页 / 共 3 页
字号:
				}
			}

			if(uitemp.b[0] == 0x01)											//  注:此段程序对2052无效,暂时保留
			{
				// 如果高地址为“0x01”,则写XDATA内容
				ucX_Ptr = uitemp.b[1];										// 因为只有256字节的XDATA,所以只取低字节。
				for(j=0;j<n;j++)
				{
					 *ucX_Ptr = ga_ucRcvBuf[i];
					i = (i+1)&(MaxRcvByte_C-1);						
					ucX_Ptr++;
				}
			}

			// 写 SFR和程序区暂不支持,读者可自己添加,看看有什么难度 :D
			
			i = (gi_ucStartPtr-2)&(MaxRcvByte_C-1);			// 取发送方地址
			ga_ucTxdBuf[2] = ga_ucRcvBuf[i];						// 作为接收方地址发送
			ga_ucTxdBuf[4] = 4;													// 帧长
			ga_ucTxdBuf[5] = WRITE_MEMORY;							// 返回命令
			ga_ucTxdBuf[6] = uitemp.b[1];								// 将要读数据的地址和长度返回
			ga_ucTxdBuf[7] = uitemp.b[0];
			ga_ucTxdBuf[8] = j;													// 返回写成功的字节数
			sum = ga_ucTxdBuf[5]+ga_ucTxdBuf[6]+ga_ucTxdBuf[7]+ga_ucTxdBuf[8];
			
			ga_ucTxdBuf[9] = ~sum;						// 校验和
				
			gc_ucTxdCnt = 10;									// 发送字节计数
			gi_ucTxdPtr = 0;									// 发送指针
			SBUF = ga_ucTxdBuf[0];						// 启动发送
			
			break;
		}
		
		case SET_WORKMODE:
		{
			// 设置工作模式及参数
			i = (gi_ucStartPtr-2)&(MaxRcvByte_C-1);			// 取发送方地址
			g_ucSenderAddr = ga_ucRcvBuf[i];						// 保存发送方地址,为了数据返回

			i = (gi_ucStartPtr + 1)&(MaxRcvByte_C-1);		
			g_ucWorkMode = ga_ucRcvBuf[i];							// 取工作模式
			i =(i+1)&(MaxRcvByte_C-1);
			g_ucModePara = ga_ucRcvBuf[i];							// 取工作参数
			
			if((g_ucWorkMode&GET_MAIN_MODE) != SINGLE_MEASURE)
			{
				// 除单次测量命令外,均返回收到命令信息
				ga_ucTxdBuf[2] = g_ucSenderAddr;						// 作为接收方地址发送
				ga_ucTxdBuf[4] = 2;													// 帧长
				ga_ucTxdBuf[5] = SET_WORKMODE;							// 返回命令
				ga_ucTxdBuf[6] = 0;													// OK 信息
			
				sum = ga_ucTxdBuf[5]+ga_ucTxdBuf[6];
			
				ga_ucTxdBuf[7] = ~sum;											// 校验和
				
				gc_ucTxdCnt = 8;														// 发送字节计数
				gi_ucTxdPtr = 0;														// 发送指针
				SBUF = ga_ucTxdBuf[0];											// 启动发送
			}
			
			break;
		}
		
		case READ_DATA:
		{
			// 读测量数据			
			i = (gi_ucStartPtr + 1)&(MaxRcvByte_C-1);		
			n = ga_ucRcvBuf[i];													// 取读最近几次数据值
			
			if( n > DATA_SAVE_NUM)
			{
				n = DATA_SAVE_NUM;
			}
						
			i = (gi_ucStartPtr-2)&(MaxRcvByte_C-1);			// 取发送方地址
			ga_ucTxdBuf[2] = ga_ucRcvBuf[i];						// 作为接收方地址发送
			ga_ucTxdBuf[4] = 2*n + 1;										// 帧长
			ga_ucTxdBuf[5] = READ_DATA;									// 返回命令
			
			j = (gi_ucDataSavePtr-1)&(DATA_SAVE_NUM-1);	// 指向最近一次数据
			k = 6;																			// 存放到发送缓冲区的指针
			sum = ga_ucTxdBuf[5];
			for(i=0;i<n;i++)
			{
				// 将测量数据送至发送缓冲区
				uitemp.all = ga_uiMeaData[j];
				ga_ucTxdBuf[k] = uitemp.b[1];							// 将整形数顺序改变为符合PC结构的
				sum += ga_ucTxdBuf[k];
				k++;
				ga_ucTxdBuf[k] = uitemp.b[0];
				sum += ga_ucTxdBuf[k];
				k++;
				j = (j-1)&(DATA_SAVE_NUM-1);
			}
						
			ga_ucTxdBuf[k] = ~sum;											// 校验和			
			gc_ucTxdCnt = ga_ucTxdBuf[4] + 6;						// 发送字节计数
			gi_ucTxdPtr = 0;														// 发送指针
			SBUF = ga_ucTxdBuf[0];											// 启动发送
				
			break;
		}
		
		default: break;
	}
}

/********************************************/
/*名称:	startUltraSonicSend									*/
/*用途: 启动测量过程,启动发射超声波脉冲		*/
/********************************************/

void startUltraSonicSend(void)
{
	g_ucWorkStat = ULTRASONIC_T;								// 进入超声波发射工作状态

	g_bCut_Off = CUT_OFF_INVALID;								// 释放回波抑制
	g_b852Inhibit = DIS852OUT;									// 禁止852输出

	gc_ucUltraSonic_T_Cnt = ULTRASONIC_T_NUM;																		// 初始化脉冲计数,
	g_ui852GainCtrlTime.all = ga_uiUS_T_PulsWidth[gc_ucUltraSonic_T_Cnt&0x01];	// 初始化脉宽控制时间,借用增益控制的变量	
	CCAP1L = g_ui852GainCtrlTime.b[1];																					// 加载比较值
	CCAP1H = g_ui852GainCtrlTime.b[0];

	
	g_bSend_Ctrl = SEND_VALID;									// 超声波输出驱动有效
	g_bUltraSonicDrvValid = TRUE;

	gc_ucPCA_OverCnt = 0;												// 启动计时处理
	CL = 0;
	CH = 0;
	CCON = CCON|STARTPCA_C;											// 启动 PCA		
}

/********************************************/
/*名称:	sortLastData												*/
/*参数:最近几个数据需要排序								*/
/*用途: 为了剔除最大最小值,将测量的数据排序*/
/********************************************/
// 最近一次为最小

void sortLastData(unsigned char ucDataNum)
{
	unsigned char i,j,k,l;
	unsigned int uitemp;
	
	
	// 冒泡排序
	for(i = 0; i<(ucDataNum-1);i++)
	{
		k = (gi_ucDataSavePtr-1 - i)&(DATA_SAVE_NUM-1);
		l = (k-1)&(DATA_SAVE_NUM-1);
		
		for(j = 0; j<(ucDataNum - i - 1);j++)
		{
			if(ga_uiMeaData[l] < ga_uiMeaData[k])
			{
				uitemp = ga_uiMeaData[k];
				ga_uiMeaData[k] = ga_uiMeaData[l];
				ga_uiMeaData[l] = uitemp;												// 冒泡一次				
			}
			
			k = (k-1)&(DATA_SAVE_NUM-1);											// 指向下一个数
			l = (l-1)&(DATA_SAVE_NUM-1);
		}
	}
}

/********************************************/
/*名称:	backMeaData													*/
/*参数:说明返回数据的取数方式							*/
/*用途: 单次测量模式的数据返回							*/
/********************************************/

// 之前,已将数据在存放区内排序,最近一次为最小,依次变大,如果为不处理模式,则没有排序

void backMeaData(unsigned char ucMode)
{
	unsigned char i,j,k,n,sum;
	unsigned long ulDataSum;

	union
	{
		unsigned int all;
		unsigned char b[2];
	}uitemp;
		
	
	ga_ucTxdBuf[2] = g_ucSenderAddr;						// 设置模式命令者作为接收方
	ga_ucTxdBuf[5] = g_ucWorkMode;							// 返回工作模式

	switch(ucMode)
	{
		case NOPROC_BACK:
		{
			ga_ucTxdBuf[4] = 2*g_ucModePara + 1;				// 帧长
			j = (gi_ucDataSavePtr-1)&(DATA_SAVE_NUM-1);	// 指向最近一次数据
			n = g_ucModePara;
			break;
		}
		
		case MID_BACK:
		{
			ga_ucTxdBuf[4] = 2*(g_ucModePara-2) + 1;		// 帧长
			j = (gi_ucDataSavePtr-2)&(DATA_SAVE_NUM-1);	// 剔除最小值
			n = g_ucModePara-2;
			break;
		}
			
		case MEAN_BACK:
		{
			// 计算平均值
			j = (gi_ucDataSavePtr-1)&(DATA_SAVE_NUM-1);	
			ulDataSum = 0;
			for(i=0;i<g_ucModePara;i++)
			{
				ulDataSum += (unsigned long)ga_uiMeaData[j];
				j = (j-1)&(DATA_SAVE_NUM-1);
			}
			ulDataSum /= g_ucModePara;
			
			j = (gi_ucDataSavePtr-1)&(DATA_SAVE_NUM-1);	
			ga_uiMeaData[j] = (unsigned int)ulDataSum;	// 将平均值放在最近一次测量结果处
			
			ga_ucTxdBuf[4] = 2 + 1;											// 帧长
			n = 1;
			break;
		}

		case MID_MEAN_BACK:
		{
			// 计算平均值
			j = (gi_ucDataSavePtr-2)&(DATA_SAVE_NUM-1);	
			ulDataSum = 0;
			for(i=0;i<(g_ucModePara-2);i++)
			{
				ulDataSum += (unsigned long)ga_uiMeaData[j];
				j = (j-1)&(DATA_SAVE_NUM-1);
			}
			ulDataSum /= (g_ucModePara-2);
			
			j = (gi_ucDataSavePtr-1)&(DATA_SAVE_NUM-1);	
			ga_uiMeaData[j] = (unsigned int)ulDataSum;	// 将平均值放在最近一次测量结果处
			
			ga_ucTxdBuf[4] = 2 + 1;											// 帧长
			n = 1;
			break;
		}
		
		default: break;
	}
	
	k = 6;																			// 存放到发送缓冲区的指针
	sum = ga_ucTxdBuf[5];
	for(i=0;i<n;i++)
	{
		// 将测量数据送至发送缓冲区
		uitemp.all = ga_uiMeaData[j];
		ga_ucTxdBuf[k] = uitemp.b[1];							// 将整形数顺序改变为符合PC结构的
		sum += ga_ucTxdBuf[k];
		k++;
		ga_ucTxdBuf[k] = uitemp.b[0];
		sum += ga_ucTxdBuf[k];
		k++;
		j = (j-1)&(DATA_SAVE_NUM-1);
	}
						
	ga_ucTxdBuf[k] = ~sum;											// 校验和			
	gc_ucTxdCnt = ga_ucTxdBuf[4] + 6;						// 发送字节计数
	gi_ucTxdPtr = 0;														// 发送指针
	SBUF = ga_ucTxdBuf[0];											// 启动发送
	
	g_ucWorkStat = WAIT_FINISH;									// 转换到等待数据返回结束状态
	g_ucWorkMode = STOP_MEASURE;								// 单次测量,完成后即停止
}


// ------------- 中断处理程序 ---------------------

/********************************************/
/*          定时器 0 中断服务               */ 
/* 说明:  1ms 中断一次, 										*/
/********************************************/

void  Timer0_Int(void) interrupt 1 using 1
{
	TH0 = TIME1msH_C;
	TL0 = TIME1msL_C;
			
	g_b1msFlag = TRUE;	
}

/********************************************/
/*          INT 1 中断服务		              */ 
/* 说明:  收到超声波后中断									*/
/********************************************/

void	INT1_Int(void) interrupt 2 using 1
{
	if(g_ucWorkStat == ULTRASONIC_R)
	{
		g_uiStopTime.b[1] = CL;
		g_uiStopTime.b[0] = CH;						// 读取PCA计时器值
		g_ucPCA_OverVal = gc_ucPCA_OverCnt;	
		
		g_ucWorkStat = CAL_RESULT;				// 转换到计算状态		
		g_b852Inhibit = DIS852OUT;				// 禁止852输出
	
		gc_ucINT1_Cnt ++;									// debug
	}
}

/********************************************/
/*          串口中断服务     	            	*/ 
/* 说明:  将收到的数据保存到接收缓冲区			*/
/********************************************/

void  SioInt(void)  interrupt 4  using 1
{
	if(RI==TRUE)
	{
		RI=FALSE;
		ga_ucRcvBuf[gi_ucSavePtr]=SBUF;												// 将数据填入缓冲区
		gi_ucSavePtr=(gi_ucSavePtr+1)&(MaxRcvByte_C-1);				// 利用屏蔽高位的方式实现指针的环形处理
		g_bNewData = TRUE;
	}
	
	if(TI == TRUE)
	{
		TI = FALSE;																						// 处理发送
		gc_ucTxdCnt--;																				// 发送计数
		if(gc_ucTxdCnt>0)
		{
			gi_ucTxdPtr++;
			SBUF = ga_ucTxdBuf[gi_ucTxdPtr];										// 取下一字节
		}
		else
		{
			g_bTxdFinish = TRUE;
		}
	}	
}

/********************************************/
/*          PCA 中断服务 			              */ 
/* 说明:  PCA0为PTR中断 										*/
/* 				PCA2为产生超声波中断							*/
/********************************************/

// 因为超声波发射的脉宽时间较短,所以放在中断中处理

void  PCA_Int(void) interrupt 6 using 1
{
	if(CF == TRUE)
	{
		CF = FALSE;
		gc_ucPCA_OverCnt++;
	}
	
	if(CCF0 == TRUE)											// 保留
	{
		CCF0 = FALSE;
	}	
	
	if(CCF1 == TRUE)											// 超声波脉冲发射或 852 增益控制
	{
		CCF1 = FALSE;
		
		if(g_ucWorkStat == ULTRASONIC_T)
		{
			// 超声波脉冲发射状态处理
			gc_ucUltraSonic_T_Cnt--;
			
			if(gc_ucUltraSonic_T_Cnt==0)
			{
				g_bSend_Ctrl = SEND_INVALID;																// 超声波输出驱动无效
				g_bUltraSonicDrvValid = FALSE;
				
				g_ucWorkStat = ULTRASONIC_R;																// 发送完成,转换到接收状态,启动增益控制
				gc_ucGainCtrl_No = 0;																				// 增益控制计数序号
				g_uc852GainCtrl = g_uc852GainCtrl&0xF0;											// 增益控制输出
				
				g_b852Inhibit = EN852OUT;																			
				g_bUltraSonic_In = TRUE;																						
				
				g_ui852GainCtrlTime.all += CUT_OFF_DELAY;										// 延时启动回波抑制
				CCAP1L = g_ui852GainCtrlTime.b[1];													
				CCAP1H = g_ui852GainCtrlTime.b[0];
			}
			else
			{
				if(g_bUltraSonicDrvValid)
				{
					g_bSend_Ctrl = SEND_INVALID;															// 超声波输出驱动无效
				}
				else
				{
					g_bSend_Ctrl = SEND_VALID;																// 超声波输出驱动有效
				}
				g_bUltraSonicDrvValid = ~g_bUltraSonicDrvValid;
				
				g_ui852GainCtrlTime.all += ga_uiUS_T_PulsWidth[gc_ucUltraSonic_T_Cnt&0x01];
				CCAP1L = g_ui852GainCtrlTime.b[1];														// 加载下一次比较值
				CCAP1H = g_ui852GainCtrlTime.b[0];
			}
		}
		else
		{
			// 超声波接收状态处理
			g_bGainCtrl = TRUE;																							// 增益控制放在主循环中执行
		}
	}
}

⌨️ 快捷键说明

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