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

📄 cs5463.c

📁 著名的CS5463抄表模块
💻 C
📖 第 1 页 / 共 4 页
字号:
		{
		   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 + -