📄 ussensor.c
字号:
}
}
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 + -