我想利用MSP430F6736芯片自己编程用来测量单相电能消耗,按照官方提供的PDF来做,可是自己编的代码测量时数据变化特别大,并且没有输入时也会有数据出现,求代码!
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我想利用MSP430F6736芯片自己编程用来测量单相电能消耗,按照官方提供的PDF来做,可是自己编的代码测量时数据变化特别大,并且没有输入时也会有数据出现,求代码!
这是我编写的代码,附件中是我参照的PDF,请大家帮忙指出问题,谢谢了~
#include "msp430f6736.h"
#include "math.h"
#define PRE1 0
#define sampleCount0 4096
#define sampleCount1 4096
float Kv0=0.82605547515;
float Kv1=1;
/* Array to store SD24 conversion internal offset */
long int offset[4];
/* Array to store SD24 conversion results */
long int results[4];
double tempCH0,tempCH1,VotageCH0,VotageCH1;
//increasing core voltage.Note: Change core voltage one level at a time,see datasheet f6736
void SetVCoreUp(unsigned int level)
{
// Open PMM registers for write access
PMMCTL0_H = 0xA5;
// Make sure no flags are set for iterative sequences
while ((PMMIFG & SVSMHDLYIFG) == 0);
while ((PMMIFG & SVSMLDLYIFG) == 0);
// Set SVS/SVM high side new level
SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
// Set SVM low side to new level
SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
// Wait till SVM is settled
while ((PMMIFG & SVSMLDLYIFG) == 0);
// Clear already set flags
PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
// Set VCore to new level
PMMCTL0_L = PMMCOREV0 * level;
// Wait till new level reached
if ((PMMIFG & SVMLIFG))
while ((PMMIFG & SVMLVLRIFG) == 0);
// Set SVS/SVM low side to new level
SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
// Lock PMM registers for write access
PMMCTL0_H = 0x00;
}
// Initialize DCO to 16MHz
void TIME(void)
{
//SetVCoreUp(1); //一次提高Vcore电压等级,具体请参考手册
//SetVCoreUp(2);
//SetVCoreUp(3);
/*
* 默认状态下:ACLK=FLLREFCLK=XT1 SMCLK=MCLK=DCOCLKDIV XT2关闭
* 为了不产生XT1LFOFFG,将ACLK和FLLREFCLK设置为REFOCLK
* 并打开XT2OFF,否则XT2将处于无法使用状态
* */
//UCSCTL6 &= ~(XT2DRIVE0|XT2DRIVE1|XT2OFF);
UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0=0x0000; // Set lowest possible DCOx, MODx
UCSCTL1=DCORSEL_7; //DCO max 19.6MHz
UCSCTL1=FLLD_4|33; // Set DCO Multiplier for 16MHz
//DCOCLKDIV = (N+1)*(REFCLK/n)=(33+1)*(32768/1)=1.1MHz;default:REFCLK=XT1CLK=32.768KHz,n=1
// Set FLL Div = fDCOCLK/16
__bic_SR_register(SCG0); // Enable the FLL control loop
__delay_cycles(782000);
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
void SD24Init(void)
{
SD24BCTL0=SD24REFS+SD24SSEL__SMCLK; // Use internal reference, SMCLK
SD24BCTL1=SD24GRP0SC+SD24GRP1SC;
SD24BCCTL0=SD24DF_1+SD24CAL+0x0008+SD24SCS_4; //Data Format: 2's complement,right aligned,SD24B Calibration, continuous conversion,SD24SCSx=100b
SD24BOSR0=256-1; //Default is 256
SD24BCCTL1=SD24DF_1+SD24CAL+0x0100+0x0008+SD24SCS_4; //Data Format: 2's complement,right aligned,SD24B Calibration, Single conversion,SD24SCSx=100b
SD24BOSR1=256-1;
SD24BPRE1=PRE1;
//SD24BTRGCTL=SD24SNGL;
SD24BIE=SD24IE0+SD24IE1;
for (int i = 0; i < 0x3600; i++); // Delay for 1.2V ref startup
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
TIME();
UCSCTL4=SELS_4+SELM_4; //SMCLK=MCLK=DCODIV=1.1MHz
SD24Init();
while(1)
{
SD24BCCTL0 |= SD24SC; //+SD24SCS_4// Start of conversion
SD24BCCTL1 |= SD24SC; //+SD24SCS_4// Start of conversion
//SD24BTRGCTL=SD24SC;
__bis_SR_register(LPM0_bits+GIE); // Enter LPM0 w/ interrupts
}
// P1DIR |= 0x80; // Set P1.0 to output direction( to control led )
}
#pragma vector=SD24B_VECTOR
__interrupt void SD24BISR(void)
{
static int getOffset=0,countCH0=0,countCH1=0;
//Get internal offset,without voltage input
if(getOffset==0)
{
switch (SD24BIV)
{
case 2:
break;
case 4:
break;
case 6: // SD24_B converter 0 memory interrupt flag; InterruptFlag: SD24IFG0
offset[0]=SD24BMEMH0;
offset[1]=SD24BMEML0;
break;
case 8: // SD24_B converter 1 memory interrupt flag; InterruptFlag: SD24IFG1
offset[2]=SD24BMEMH1;
offset[3]=SD24BMEML1;
break;
}
getOffset++;
}
//Get Vrms
else
{
switch (SD24BIV)
{
case 2:
break;
case 4:
break;
case 6: // SD24_B converter 0 memory interrupt flag; InterruptFlag: SD24IFG0
results[0] = SD24BMEMH0-offset[0];
results[1] = SD24BMEML0-offset[1];
tempCH0+=pow(((results[0]<<16)|results[1])>>16,2);
countCH0++;
if(countCH0==sampleCount0)
{VotageCH0=Kv0*sqrt(tempCH0/sampleCount0);tempCH0=0;countCH0=0;}
break;
case 8: // SD24_B converter 1 memory interrupt flag; InterruptFlag: SD24IFG1
results[2] = SD24BMEMH1-offset[2];
results[3] = SD24BMEML1-offset[3];
countCH1++;
tempCH1+=pow(((results[2]<<16)|results[3])>>16,2);
if(countCH1==sampleCount1)
{VotageCH1=Kv1*sqrt(tempCH1/sampleCount1);tempCH1=0;countCH1=0;}
break;
}
}
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
您可以参考 http://www.ti.com.cn/cn/lit/an/slaa517d/slaa517d.pdf 这个文档是针对MSP430F6736(A)的