📄 cs5463.c
字号:
{
g_sEneryCnt.dwEQbn++;//B相反向无功电能计数值++
QBsign = 0;
}
pgsPort0Int->regIntClr = P25;
if(PBsign)
{
if(QBsign) g_sEneryCnt.dwEQ1++;
else g_sEneryCnt.dwEQ4++;
}
else
{
if(QBsign) g_sEneryCnt.dwEQ2++;
else g_sEneryCnt.dwEQ3++;
}
}
//**************** C **********
if(dwIntFlag & P31) //有功电能
{
if(dwDir & P29)
{
g_sEneryCnt.dwEPcp++; //C相正向有功电能计数值++
PCsign =1;
}
else
{
g_sEneryCnt.dwEPcn++;//C相反向有功电能计数值++
PCsign = 0;
}
pgsPort0Int->regIntClr = P31;
}
if(dwIntFlag & P30)//无功电能
{
if(dwDir & P29)
{
g_sEneryCnt.dwEQcp++; //C相正向无功电能计数值++
QCsign = 1;
}
else
{
g_sEneryCnt.dwEQcn++;//C相反向无功电能计数值++
QCsign = 0;
}
pgsPort0Int->regIntClr = P30;
if(PCsign)
{
if(QCsign) g_sEneryCnt.dwEQ1++;
else g_sEneryCnt.dwEQ4++;
}
else
{
if(QCsign) g_sEneryCnt.dwEQ2++;
else g_sEneryCnt.dwEQ3++;
}
}
if(dwIntFlag & (P22|P23|P25|P26|P30|P31))
{
SendPulseUpdateSignal();
}
}
/*****************AD转换对应的SSP1中断服务程序***********************
本中断服务进入一次,说明至少有half Rxfifo个,即4个数据进入 Rxfifo了,
把这4个数据全部读出。注意在AD初始化已经设定4个数据为4个字节。
根据AD当前的中断标志byAdcSampleType,(即有效值等的采样,还是波形采样)
把数据放入到对应的结构数组中
*/
BYTE flag=0; /*mod,lyq,2007-03-07, 希望变量定义时,能从名称看出实际用途*/
BYTE flag_int =0;
BYTE flag_w=0;
BYTE flag_int_w =0;
BYTE byException =0;
DWORD iTimerCnt =0;
/************** AD转换完成外部中断1服务程序,脉冲计数中断***********
进入本中断,则标志着一次AD转换完成,转换类型由状态寄存器中的DRDY和CRDY标志
DRDY与CRDY不同时置位(在屏蔽寄存器中两者不同时置位,见AD初始化及SSP1中断)
*/
void ADCConvertFiqSrv(void)
{
BYTE *pRev;
BYTE *preg;
DWORD dwTemp;
//*****脉冲计数中断**************
if(pgsVic->regFiqStatus & P17)
{
flag =2;
ADCPulseFiqSrv();
}
//*********AD转换完成外部中断1服务程序 INT_CH_EXTINT1
if(pgsVic->regFiqStatus & P15 )
{
pgsFPort0->regOutSet = ADCSB | ADCSC | ADCSO;
pgsFPort0->regOutClr = ADCSA;
preg = (BYTE*)&pgsSsp1->regData;
if(byAdcCommandIndex >0 ) //在读取数据期间又来了一次中断此次中断为异常的中断,
{
if(byAdcSampleType==0) byException =1;
else byException =2;
}
else
{
if(!byAdcSampleType) //是有效值 功率 等的采样
{
flag_int =3;
pg_sRealCode = (DWORD*)&g_sRealCode;
pRev = (BYTE*) &dwReadAdcCommand[0][0];
}
else//是波形数据的采样
{
pgsTimer2->regCounter =0;
pgsTimer2->regCtrl = 1;//启动
flag_int_w =4;
if(dwWaveSampleCount==0)
{
pg_sRealCode = (DWORD*)&g_sWaveCode;
}
pRev = (BYTE*) &dwReadAdcWaveCommand[0][0]; //mod zhw 2007-4-17 pRev = (BYTE*) &dwReadAdcWaveCommand[0]
}
pRev += 3; /*mod,lyq,2007-03-07,可以调整命令数组内的字节顺序或方式,从而消除该项计算*/
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
byAdcCommandIndex = 1;
pgsExInt->regIntFlag = 0x02; //pgsExInt->regIntFlag |= 0x02 mod zhw 2007-4-19 clear interrupt flag
}
}
//**************SSP1接收中断**************
if(pgsVic->regFiqStatus & P11)
//SSP1Srv(); /*mod,lyq,2007-03-07 可以考虑直接将该函数代码直接放在这里,减少调用时间,同时还可以做一些变量的优化*/
{
//考虑加入对异常接收的处理
pRev = (BYTE*)&dwTemp;
pRev +=3; //调整为高字节 /*mod,lyq,2007-03-07,可以调整命令数组内的字节顺序或方式,从而消除该项计算*/
preg = (BYTE*)&pgsSsp1->regData;
*pRev --= *preg;
*pRev --= *preg;
*pRev --= *preg;
*pRev --= *preg;
if( ! byAdcSampleType )//是有效值 功率 等的采样
{
*pg_sRealCode ++= dwTemp;
pgsFPort0->regOutSet = dwregSet_RMS[byAdcCommandIndex];//片选,byAdcCommandIndex对应的AD芯片
pgsFPort0->regOutClr = dwregClr_RMS[byAdcCommandIndex];
if(byAdcCommandIndex >= 26)//所有的读取命令都已经发送,且收到了数据,
{
byAdcCommandIndex = 0;
if(byStartWaveSample) byAdcSampleType = 1; ////转入波形数据转换标志
else byAdcSampleType = 0; //继续有效值的采样
byStartWaveSample = 0;
dwWaveSampleCount = 0;
SendAdcFinishiSignal();
pgsVic->regVectAddr = 0x00;
return;
}
if(byAdcCommandIndex==25 && byStartWaveSample)//需要波形转换
{
pRev = (BYTE*)&byStartWavCommand[0]; //下发波形转换的命令
byAdcCommandIndex++;
}
else
pRev = (BYTE*)&dwReadAdcCommand[byAdcCommandIndex++][0];
pRev += 3; /*mod,lyq,2007-03-07,可以调整命令数组内的字节顺序或方式,从而消除该项计算*/
preg = (BYTE*)&pgsSsp1->regData;
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
}/*if*/
else//是波形数据的采样
{
if(byAdcCommandIndex < 7 || byAdcCommandIndex == 8)
{
*pg_sRealCode ++= dwTemp;
}
pgsFPort0->regOutSet = dwregSet_Wav[byAdcCommandIndex];//片选,byAdcCommandIndex对应的AD芯片
pgsFPort0->regOutClr = dwregClr_Wav[byAdcCommandIndex];
if(byAdcCommandIndex >=7) //所有的读取(写)命令都已经发送,且收到了数据,
{
dwWaveSampleCount ++;
if(dwWaveSampleCount < MAX_WAVE_NUM)
{
byAdcCommandIndex =0;
byAdcSampleType =1;
pgsFPort0->regOutSet = ADCSA | ADCSB | ADCSC | ADCSO;
}
else if(dwWaveSampleCount ==MAX_WAVE_NUM || dwWaveSampleCount==(MAX_WAVE_NUM+1))
{
pRev = (BYTE*)&dwReadAdcWaveCommand[byAdcCommandIndex++][0];
pRev += 3;
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
}
else if( dwWaveSampleCount >= MAX_WAVE_NUM+2) //
{
flag_w =1;
pgsFPort0->regOutSet = ADCSA;
dwWaveSampleCount = 0;
byAdcCommandIndex = 0;
SendWaveFinishiSignal();
byAdcSampleType =0; //转入AD有效值数据的初始化
pgsTimer2->regCtrl = 0;//停止
if(iTimerCnt < pgsTimer2->regCounter)
iTimerCnt = pgsTimer2->regCounter;
}
pgsVic->regVectAddr = 0x00; //interrupt finish
return;
}
pRev = (BYTE*)&dwReadAdcWaveCommand[byAdcCommandIndex++][0];
pRev += 3;
preg = (BYTE*)&pgsSsp1->regData; //add zhw 2007-4-13
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
*preg = *pRev--;
}
}
pgsVic->regVectAddr = 0x00; // interrupt finish
}
/********初始化AD的读写命令****************
1.当一次AD转换完成,引起快速中断时,快速中断服务程序ADCConvertFiq
根据需要确定 AD读写的第一条命令(4个字节),发送到SSP1的TxFifo。
2.由于SSP1时双向的,SSP1的RXFIFO会收到同样字节的(由AD发送)的数据。
当RXFIFO为half full时(4个字节),引起SSP1的接收中断。
3.在SSP1的接收中断服务程序SSP1Irq中,读取RXFIFO的4个字节,然后发送下一条命令。
4.再次会引起SSP1的接收中断。。。。直至发送完需要的命令,清除相应的中断标志。
本函数,把所有的命令初始化,减轻了中断服务的负担。
命令由分为读命令 和写命令,具体含义见注释和AD手册。
*/
void InitTimer2(void)
{
pgsTimer2->regPrescale = 0;
}
void TestAdcNoCom(void)
{
SADCoef sADCoef[4];
SCs5460Coef sCs5460Coef;
INT32 i;
DWORD dwTemp;
DWORD *ptr;
// Print("5555");
LoadParam((DWORD)&p_gcSysParam->sADCoef[0],&sADCoef[0],sizeof(SADCoef)*4);
ptr = (DWORD*)&sADCoef[0];
for(i=0; i<sizeof(SADCoef)/sizeof(DWORD)*4; i++)
{
WriteCom(0,(BYTE*)ptr,4);
ptr++;
}
/* LoadParam((DWORD)&p_gcSysParam->sCs5460Coef,&sCs5460Coef,sizeof(SCs5460Coef));
ptr = (DWORD*)&sCs5460Coef;
for(i=0; i<sizeof(SCs5460Coef)/sizeof(DWORD); i++)
{
WriteCom(0,(BYTE*)ptr,4);
ptr++;
}*/
InitAdc(sADCoef,4);
}
void InitAdc(SADCoef *pADCoef,INT32 iChipSum) //pdwOffset,pdwGain==NULL时,gain及offset采用CS5460A硬件复位时的默认参数
{
// #define INITADC
SADCoef *pAdc;
INT32 i;
BYTE j=0;
INT32 iTemp;
DWORD dwTemp;
float fRealVal;
pAdc = pADCoef;
g_dwEnergyCntRatio = 100; //should change if, 100
//为了安全期见,在初始化AD之前,先把用到的中断禁止,
pgsVic->regIntEnableClr = 0x01 << INT_CH_EXTINT1;
pgsVic->regIntEnableClr = 0x01 << INT_CH_EXTINT2;
pgsVic->regIntEnableClr = 0x01 << INT_CH_EXTINT3;
pgsVic->regIntEnableClr = 0x01 << INT_CH_SSP1;
InitAdcCommand();
pgsFPort0->regDirCtrl |=ADCSA| ADCSB | ADCSC |ADCSO |ADRST; //out
pgsFPort0->regOutSet = ADCSA |ADCSB |ADCSC | ADCSO;//disable chipA chipB,chipC, cs5460A
pgsFPort0->regOutClr = ADRST; //hardware reset cs5460a
InitSSp1();//初始化SSP1口
//add zhw 2007-3-26 掉电监测
PINSEL4 &=0xFCFFFFFF;//P2.12 as I/O
pgsFPort2->regDirCtrl &= ~P12; // as INPUT
//脱离硬件复位状态
Delay(30); //must be at least 60ms, delay wait
pgsFPort0->regOutSet = ADRST;
Delay(30);//this line must use for safe reset ,add zhw 2007-3-15
for(i=0; i<iChipSum; i++)
{
SelectAdc(i);
if(i<3) //前三片为CS5463
{
WriteSTATUS(0xffffff);
WriteAdc24Bits(CYCCONT, 2000); //N=2000;
if(i == 0)
WriteAdc24Bits(MASKR,0x800000);//只有A片DRDY=10x800000
else WriteAdc24Bits(MASKR,0x000000); //B C片不置DRDY位
WriteAdc24Bits(MODER,0x000001); //;操作寄存器
// WriteAdc24Bits(MODER,0x000061); //;操作寄存器
if(pAdc != NULL ) //采用初始化时的默认参数
{
iTemp = pAdc->iPhaseOffset << 17;
iTemp |=0x001001; //k=1 、下降沿(INT 通常处于高电平)
WriteAdc24Bits(CONFR,iTemp);////k=1 、下降沿(INT 通常处于高电平)
// WriteAdc24Bits(VACOFFR, pAdc->dwVACOffset);//设置电压通道OFFSET系数
WriteAdc24Bits(VDCOFF, pAdc->dwVDCOffset);//设置电压通道OFFSET系数
WriteAdc24Bits(VGN, pAdc->dwVACGain);//设置电压通道GAIN系数
// WriteAdc24Bits(IACOFFR, pAdc->dwIACOffset);//设置电压通道OFFSET系数
WriteAdc24Bits(IDCOFF, pAdc->dwIDCOffset);//设置电压通道OFFSET系数
WriteAdc24Bits(IGN, pAdc->dwIACGain); //设置电流通道GAIN系数
WriteAdc24Bits(PULRATE,pAdc->dwPulseRateE);// 设置脉冲速率寄存器 10000 250V 6A
// WriteAdc24Bits(PULRATE,0xBDA1);// 设置脉冲速率寄存器 10000 250V 6A
pAdc ++;
}
}
else //初始化CS5460A
{
WriteSTATUS(0xffffff);
WriteAdc24Bits(MASKR, 0x000000); //LSD=1
WriteAdc24Bits(CONFR, 0x000061); //k=1 、低电平
WriteAdc24Bits(CYCCONT, 2000); //N=2000;
if(pAdc != NULL ) //采用初始化时的默认参数
{
WriteAdc24Bits(VACOFFR, pAdc->dwVACOffset);//设置电压通道OFFSET系数
// WriteAdc24Bits(VDCOFF, pAdc->dwVDCOffset);//设置电压通道OFFSET系数
WriteAdc24Bits(VGN, pAdc->dwVACGain);//设置电压通道GAIN系数
WriteAdc24Bits(IACOFFR, pAdc->dwIACOffset);//设置电压通道OFFSET系数
// WriteAdc24Bits(IDCOFF, pAdc->dwIDCOffset);//设置电压通道OFFSET系数
WriteAdc24Bits(IGN, pAdc->dwIACGain); //设置电流通道GAIN系数
}
}
UnSelAdc(i);
}
for(i=0; i<iChipSum; i++)
{
SelectAdc(i);
WriteSTATUS(0xffffff);
UnSelAdc(i);
}
OS_ENTER_CRITICAL(); //add zhw 2007-4-17 为保证ADCS同时启动,必须关闭所有的中断,才能执行下面的语句,这里使用OS_ENTER_CRITICAL。
for(i=0; i<iChipSum; i++)
{
SelectAdc(i);
WriteAdcCommand(STARTC); //启动AD转换
UnSelAdc(i);
}
OS_EXIT_CRITICAL();
for(i=0; i<8; i++) //清空RXFIFO, for safe
{
dwTemp = pgsSsp1->regData;
}
g_iAdcUpdateFlag = 0;
g_iAdcWaveUpdateFlag = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -