📄 rf24e1.c
字号:
return 100;
}
//================================================================
//函数功能:检验接收
//filename:VerifyRxd()
//input:none
//output:数据报头位置(eb90eb90+数据报)
//================================================================
unsigned char VerifyRxd(void)
{
//signed char locat;
Loc=FindHead();
if( Loc > 10 )
{//没有找到同步头
return 0xff;
}
if( (inBuf[Loc]+Loc) > inCnt )
{//长度不够
return 0xff;
}
if( inBuf[Loc+1] != 0x11 )
{//类型不对
return 0xff;
}
if( inBuf[Loc+2] != 0 )
{//组号不对
return 0xff;
}
if( inBuf[Loc+3] != 0 )
{//地址不对
return 0xff;
}
if(!RxdCheckSum())
{//校验不对
return 0xff;
}
//SBUF=locat;
return Loc;
}
//================================================================
//函数功能:启动发送
//filename:StartSend()
//input:none
//output:none
//================================================================
void StartSend(void)
{
outBuf[0] = 0xeb;
outBuf[1] = 0x90;
outBuf[2] = 0xeb;
outBuf[3] = 0x90;
outBuf[5] = 0x11;
outBuf[6] = 0x00;
outBuf[7] = 0x00;
outBuf[9] = 0x00;//????????????????状态
outCnt = outBuf[4]+3;
cTxdDptr = 1;//注:串口发送中断从outBuf[1]开始发送,直到outCnt为零
TxdCheckSum( );
SBUF = 0xeb;
}
//================================================================
//函数功能:检查串口接收缓冲区,根据命令段含义作出响应动作
//filename:CheckRxd()
//input:none
//output:none
//================================================================
void CheckRxd(void)
{
unsigned char locat,jj;
unsigned int kk;
// unsigned char cpu_sr;
if( bRxd )
{
if( cRxdTime >3) //串口有接收20ms 后可以认为全部数据业已到达
{
//20ms后查看接收缓冲区的信息是什么冬冬。
// ES=0; //正在处理接收缓冲区,禁止中断,以免这时有以外的数据进来
bRxd = 0;
locat = VerifyRxd(); //校验数据
if(locat < 10 )
{// Led_Tx=0; //找到同步头
switch( inBuf[locat+4] )//这个位置是命令段
{
case 0: //查询数据(呼叫电池组电压、电流)
outBuf[4] = 12; //长度段
outBuf[8] = 0x80; //命令段(或0x80)
outBuf[10]=LOCAL_ADC.adcByte[1]; //电池组电压值
outBuf[11]=LOCAL_ADC.adcByte[0];
outBuf[12]=LOCAL_ADC.adcByte[3]; //电池组电流值
outBuf[13]=LOCAL_ADC.adcByte[2];
StartSend();
break;
case 1: //查询单节电池电压
//串口发送缓冲区:255,所以每次仅可以发送60个节点的信息,60x4=240
if(Group1_Num)
{
kk=4*Group1_Num;
outBuf[8] = 0x81;
/*locat=0;
do
{
outBuf[11+locat]=Node_V[NdBfoutV++];
}while((++locat<240)&&(NdBfoutV<(4*Group1_Num)));
if(NdBfoutV>=(4*Group1_Num))
NdBfoutV=0;*/
/*if(jj<=240)
{
for(locat=0;locat<jj;locat++)
outBuf[11+locat]=Node_V[NdBfoutV];
}
else
{
if(NdBfoutV<240)
{
for(locat=0;locat<240;locat++)
{
outBuf[11+locat]=Node_V[NdBfoutV++];
}
}
else
{
jj=jj-NdBfoutV;
for(locat=0;locat<jj;locat++)
outBuf[11+locat]=Node_V[NdBfoutV++];
NdBfoutV=0;
}
}*/
for(locat=0;locat<241;locat++)
{
if(NdBfoutV>=kk)
{
NdBfoutV=0;
break;
}
outBuf[11+locat]=Node_V[NdBfoutV++];
}
outBuf[4]=9+locat;
outBuf[10]=locat;
StartSend();
}
break;
case 2://查询单节电池温度
if(Group1_Num)
{
kk=Group1_Num<<2;
outBuf[8] = 0x82;
/*locat=0;
do
{
outBuf[11+locat]=Node_T[NdBfoutT++];
}while((++locat<240)&&(NdBfoutT<(4*Group1_Num)));*/
for(locat=0;locat<240;locat++)
{
if(NdBfoutT>=(4*Group1_Num))
{
NdBfoutT=0;
break;
}
outBuf[11+locat]=Node_T[NdBfoutT++];
}
outBuf[4]=9+locat;
outBuf[10]=locat;
StartSend();
}
break;
case 3://节点地址注册,每次少于等于100个节点
//inBuf[115]:4+8+121=133
Group1_Num=inBuf[locat+6];
for(jj=0;jj<Group1_Num;jj++)//节点数量
{
Group1_Table[jj]=inBuf[locat+7+jj];
}
outBuf[4] = 0x08;
outBuf[8] = 0x83;//注册完成回复
StartSend();
NodeResistered=1;
break;
case 4://启动巡检
enrF = 1;
outBuf[4] = 0x08;
outBuf[8] = 0x84;
StartSend();
break;
case 5://本机无线地址和节点地址高三字节的确定
//PtAddr=(unsigned char xdata *)(0x0fe8);
for(jj=0;jj<4;jj++)
{
rconf.buf[ADDR_INDEX+jj]=inBuf[10+jj];//本机地址
tconf.buf[ADDR_INDEX+jj]=inBuf[14+jj];//节点地址
}
outBuf[4]=8;
outBuf[8]=0x85;
rFaddrResistered=1;
fRfInit();//每配置一次节点、本机无线地址都必须初始化无线子系统一次because....
StartSend();
break;
default:
break;
}//switch( inBuf[locat+4] )
}//if( locat < 10 )
EA=0;
cRxdTime = 0;
inCnt = 0;//接收处理完毕,计数器清零
EA=1;
// ES=1;
}///if(cRxTime>2)
}//if(bRxd)
else
{
cRxdTime = 0;
}
}
/*
void SendCh(unsigned char c)
{
EA=0;
TI=0;
SBUF = c;
while(!TI);
TI=0;
EA=1;
}*/
//================================================================
//函数功能:将收到的节点采样值按顺序存入节点采样值缓冲区
//filename:SaveNodeInfo()
//input:bit valid=1,收到有效的采样值,如实存入,否则该节点无响应,存入max value
//output:none
//================================================================
void SaveNodeInfo(bit valid)
{ unsigned char jj;
if(!valid)//节点无响应。
{
for(jj=0;jj<4;jj++)
{
adcResult_list[jj][0]=0xff;
adcResult_list[jj][1]=0xff;
}
}
// 一个节点的2个通道的电压存入缓冲
Node_V[NodeBufCnt]=adcResult_list[0][1];//低字节
Node_V[NodeBufCnt+1]=adcResult_list[0][0];
Node_V[NodeBufCnt+2]=adcResult_list[1][1];//高字节
Node_V[NodeBufCnt+3]=adcResult_list[1][0];
//一个节点的2个通道的温度存入缓冲,并调整指针
Node_T[NodeBufCnt++]=adcResult_list[2][1];
Node_T[NodeBufCnt++]=adcResult_list[2][0];
Node_T[NodeBufCnt++]=adcResult_list[3][1];
Node_T[NodeBufCnt++]=adcResult_list[3][0];
if(NodeBufCnt>=400)NodeBufCnt=0;
else
{
if(NodeBufCnt>=4*Group1_Num)
NodeBufCnt=0;//100个以下节点的情况
}
}
//================================================================
//main()>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//================================================================
main()
{
unsigned char idata RxMsg=0;
unsigned int idata adc_temp;
unsigned int idata adctime;
unsigned char idata i,b,jj;
// unsigned int xdata t_50ms;
SysInit();
InitADC();
ptnode=0;
EA=1;
while((!NodeResistered)||(!rFaddrResistered))//上电后等待m128注册节点和无线地址
CheckRxd();
// NodeResistered=0;
// rFaddrResistered=0;
// Led_Rx=0;
while(1)
{
//SetTxMode();
//////////////////////////////设置发送模式//////////////
re_ask: CE = 0;
CS = 1;
Delay100us(0);
SpiReadWrite(tconf.buf[14]);
CS = 0;
////////////////////////////////////////////////////////
Led_Tx=0;
Led_Rx=1;
//TransmitCMD(Group1_Table[ptnode]);
//////////////////////////////发送查询命令//////////////
CE = 1;
Delay100us(0);
tconf.buf[ADDR_INDEX+ADDR_COUNT-1]=Group1_Table[ptnode];
for(i=0;i<ADDR_COUNT;i++)
{
SpiReadWrite(tconf.buf[ADDR_INDEX+i]); //写目标地址
}
SpiReadWrite('f'); //写数据(8字节)
CE = 0;
Delay100us(3); // Wait ~300us
/////////////////////////////////////////////////////////
//Delayms(5); //这个时间是必须的,因为可能没发完不要改变工作模式
Delayms(3); //250kbps,64bits需要0.256ms
/* Delay100us(200);
Delay100us(200);
Delay100us(200); */
//SetRxMode();
////////////////////////////////////设置接收模式///////
CE = 0;
CS = 1;
Delay100us(0);
SpiReadWrite(rconf.buf[14]);
CS = 0;
///////////////////////////////////////////////////////
Led_Tx=1;
CheckRxd();
ReqTimeout=0;
//Led_Tx=1;
//RxPack();
///////////////////////////////////无线接收///////////////
CE = 1;
while(!DR1)
{
if(ReqTimeout>50)//50ms超时
{
ReqTimeout=0xff;
goto asktimeout;//break;
}
}
jj=0;
while(DR1)
{
b = SpiReadWrite(0);
adcResult_list[jj][0]=b;
b=SpiReadWrite(0);
adcResult_list[jj++][1]=b;
ReqTimeout=0;
}
asktimeout:CE = 0;
//////////////////////////////////////////////////////////
if(ReqTimeout==0xff) //超时出来的
{
if(++CallTime==2) //重呼2次,坚决放弃和她的联系
{ SaveNodeInfo(0);//该节点对应的缓冲位置存入0xff
goto endQ;
}
goto re_ask;
}
Led_Rx=0; //接收LED闪烁
SaveNodeInfo(1); //缓冲接收到的节点采样值
Delay100us(100);
endQ: if(++ptnode>=Group1_Num)
ptnode=0;
CallTime=0;
//200ms搞一次电池组电压电流采样
//----------------ADC采样处理,平滑均值滤波处理---------------------
//----------------ADC_LIST[2][16]
//----------------ADC_SUM[2]
//----------------adcResult_list[X]=ADC_SUM[X]/16
/*if(++adctime>2000)
{ adctime=0;*/
/* ADC_SUM[0] -=ADC_LIST[0][ADC_Cnt]; //各个通道的累加和减去最老采样值,
ADC_SUM[1] -=ADC_LIST[1][ADC_Cnt];
InitADC(); //不明白,否则转换结果保持是最后一个通道的结果
ADC_LIST[0][ADC_Cnt]=ReadShowADC(1); //读出第1个通道的采样值(电流)
InitADC();
ADC_LIST[1][ADC_Cnt]=ReadShowADC(2); //读出第2个通道的采样值(电压)
ADC_SUM[0] +=ADC_LIST[0][ADC_Cnt]; //各个通道的累加和加上最新采样值,
ADC_SUM[1] +=ADC_LIST[1][ADC_Cnt];
*/
/**************************
InitADC();
adc_temp=ReadShowADC(1);
ADC_SUM[0]+=adc_temp;
adc_temp=ReadShowADC(2);
ADC_SUM[1]+=adc_temp;
ADC_Cnt++;
if(ADC_Cnt>=128)
{
ADC_Cnt=0;
LOCAL_ADC.adc_value.local_A=ADC_SUM[0]>>7;
LOCAL_ADC.adc_value.local_V=ADC_SUM[1]>>7;
ADC_SUM[0]=0;
ADC_SUM[1]=0;
}*/ //*****
//LOCAL_ADC.adc_value.local_A=(ADC_SUM[0])>>4; //通道1平均值(sum/16)
//LOCAL_ADC.adc_value.local_V=(ADC_SUM[1])>>4; //通道2平均值
/* Led_Rx=~Led_Rx;
SendCh(LocalADC[0]>>8);
SendCh(LocalADC[0]);
SendCh(LocalADC[1]>>8);
SendCh(LocalADC[1]);
*/
//if(++ADC_Cnt==16)ADC_Cnt=0; //调整指针
/* }*/
}
}
//================================================================
//函数功能:TIMER0中断服务程序(实现1秒定时)
//filename:
//input: none
//output:none
//================================================================
void Timer0_isr(void) interrupt 1
{ // static unsigned char idata OneSCnt;
TR0 = 0;
TH0=0xcb;
TL0=0xea; //reload the counter
if(bRxd)
cRxdTime++;
ReqTimeout++; //无线查询超时计数器
TR0=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -