📄 emeter-setup.c
字号:
#if defined(BATTERY_MONITOR_SUPPORT)
ADC12MCTL5 = SREF_0 | VOLTAGE_INPUT;
ADC12MCTL6 = EOS | SREF_0 | BATTERY_INPUT;
#else
ADC12MCTL5 = EOS | SREF_0 | VOLTAGE_INPUT;
#endif
#else
#if GAIN_STAGES > 1
ADC12MCTL0 = SREF_0 | LIVE_LOW_CURRENT_INPUT_1;
ADC12MCTL1 = SREF_0 | LIVE_HIGH_CURRENT_INPUT_1;
ADC12MCTL2 = SREF_0 | VOLTAGE_INPUT_1;
ADC12MCTL3 = SREF_0 | LIVE_LOW_CURRENT_INPUT_2;
ADC12MCTL4 = SREF_0 | LIVE_HIGH_CURRENT_INPUT_2;
ADC12MCTL5 = SREF_0 | VOLTAGE_INPUT_2;
ADC12MCTL6 = SREF_0 | LIVE_LOW_CURRENT_INPUT_3;
ADC12MCTL7 = SREF_0 | LIVE_HIGH_CURRENT_INPUT_3;
#if defined(NEUTRAL_CURRENT_INPUT)
ADC12MCTL8 = SREF_0 | VOLTAGE_INPUT_3;
ADC12MCTL9 = EOS | SREF_0 | NEUTRAL_CURRENT_INPUT;
#else
ADC12MCTL8 = EOS | SREF_0 | NEUTRAL_CURRENT_INPUT;
#endif
#else
ADC12MCTL0 = SREF_0 | LIVE_CURRENT_INPUT_1;
ADC12MCTL1 = SREF_0 | AGND_INPUT;
ADC12MCTL2 = SREF_0 | VOLTAGE_INPUT_1;
ADC12MCTL3 = SREF_0 | LIVE_CURRENT_INPUT_2;
ADC12MCTL4 = SREF_0 | AGND_INPUT;
ADC12MCTL5 = SREF_0 | VOLTAGE_INPUT_2;
ADC12MCTL6 = SREF_0 | LIVE_CURRENT_INPUT_3;
ADC12MCTL7 = SREF_0 | AGND_INPUT;
#if defined(NEUTRAL_CURRENT_INPUT)
ADC12MCTL8 = SREF_0 | VOLTAGE_INPUT_3;
ADC12MCTL9 = EOS | SREF_0 | NEUTRAL_CURRENT_INPUT;
#else
ADC12MCTL8 = EOS | SREF_0 | VOLTAGE_INPUT_3;
#endif
#endif
#if defined(BATTERY_MONITOR_SUPPORT)
/* Battery sensing control pin */
P3DIR &= ~(BIT1);
P3OUT |= (BIT1);
#endif
#endif
/* Later, we will program the ADC for the following. For now
we just get the basic configuration done, and wait until
we are sure there is enough power to do more. */
/* Sample & hold time 0 (for low ADC channels) */
/* Sample & hold time 1 (for high ADC channels) */
/* Multiple sample & hold off */
/* Reference voltage is switched on at 2.5V */
/* ADC12 module is switched on */
/* Interrupt at the end of every ADC conversion */
ADC12CTL0 = MSC;
/* First conv. result is stored in ADC12MEM0 */
/* ADC12SC bit triggers sample & hold */
/* ISSH trigger is NOT inverted */
/* Sample pulse is generated by sampling timer */
/* Clock Source: TIMER_A OUT 1 */
/* Clock divider: 1 */
/* Sequence of channels conversion */
ADC12CTL1 = SHS_1 | CONSEQ_1 | SHP | ADC12SSEL_0;
/* Turn off the digital input circuit for the ADC pins */
P6SEL = BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0;
#endif
#if defined(__MSP430_HAS_SD16_3__)
disable_analog_front_end();
#endif
#if defined(POWER_UP_BY_SUPPLY_SENSING)
/* Set up comparator A to monitor a drooping voltage within the
e-meter's main power supply. This is an early warning of power
fail, so we can get to low power mode before we start burning the
battery. */
CACTL1 = CAREF_1;
CACTL2 = P2CA1 | CAF;
P1SEL |= BIT7;
CAPD |= BIT7;
#endif
#if defined(IEC1107_SUPPORT) || defined(SERIAL_CALIBRATION_SUPPORT) || defined(SERIAL_CALIBRATION_REF_SUPPORT)
#if defined(__MSP430_HAS_UART0__)
/* Configure UART0 */
UCTL0 = CHAR; /* 8-bit character */
#if USART0_BAUD_RATE == 9600
/* 9600 Rx doesn't work very well from 32768Hz. Use the fast clock. */
UTCTL0 = SSEL1; /* UCLK = SMCLK */
UBR00 = 0x69;
UBR10 = 0x3;
UMCTL0 = 0x77;
#elif USART0_BAUD_RATE == 4800
UTCTL0 = SSEL0; /* UCLK = ACLK */
UBR00 = 6; /* 32k/4800 - 6.8266 */
UBR10 = 0;
UMCTL0 = 0x6F;
#elif USART0_BAUD_RATE == 2400
UTCTL0 = SSEL0; /* UCLK = ACLK */
UBR00 = 13; /* 32k/2400 - 13.653 */
UBR10 = 0;
UMCTL0 = 0x6B;
#else
UTCTL0 = SSEL0; /* UCLK = ACLK */
UBR00 = 27; /* 32k/1200 - 27.307 */
UBR10 = 0;
UMCTL0 = 0x03;
#endif
#if defined(SERIAL_CALIBRATION_REF_SUPPORT)
U0ME |= (UTXE0 | URXE0); /* Enable USART0 TXD/RXD */
U0IE |= URXIE0;
#elif defined(SERIAL_CALIBRATION_SUPPORT)
U0ME |= URXE0; /* Enable only USART0 RXD */
U0IE |= URXIE0;
#else
U0ME |= UTXE0; /* Enable only USART0 TXD */
#endif
/* If you do not initially kick the Tx port the TXEPT bit is not set. */
TXBUF0 = 0;
#endif
#if defined(__MSP430_HAS_UART1__)
/* Configure UART1 */
//UCTL1 = PENA | PEV; /* 7-bit + even parity character */
UCTL1 = CHAR; /* 8-bit character */
//UCTL1 = PENA | PEV | CHAR; /* 8-bit + even parity character */
#if USART1_BAUD_RATE == 9600
/* 9600 Rx doesn't work very well from 32768Hz. Use the fast clock. */
UTCTL1 = SSEL1; /* UCLK = SMCLK */
UBR01 = 0x69;
UBR11 = 0x3;
UMCTL1 = 0x77;
#elif USART1_BAUD_RATE == 4800
UTCTL1 = SSEL0; /* UCLK = ACLK */
UBR01 = 6; /* 32k/4800 - 6.8266 */
UBR11 = 0;
UMCTL1 = 0x6F;
#elif USART1_BAUD_RATE == 2400
UTCTL1 = SSEL0; /* UCLK = ACLK */
UBR01 = 13; /* 32k/2400 - 13.653 */
UBR11 = 0;
UMCTL1 = 0x6B;
#else
UTCTL1 = SSEL0; /* UCLK = ACLK */
UBR01 = 27; /* 32k/1200 - 27.307 */
UBR11 = 0;
UMCTL1 = 0x03;
#endif
ME2 |= (UTXE1 | URXE1); /* Enable USART1 TXD/RXD */
IE2 |= URXIE1;
/* If you do not initially kick the Tx port, the TXEPT bit is not set. */
TXBUF1 = 0;
#endif
#if defined(IEC1107_SUPPORT)
/* Configure the IR receiver control line - we need to be able to power it down
in limp mode, to conserve current. */
disable_ir_receiver();
#endif
#endif
meter_status &= ~(STATUS_REVERSED | STATUS_EARTHED | STATUS_PHASE_VOLTAGE_OK);
clr_normal_indicator();
clr_earthed_indicator();
clr_reverse_current_indicator();
#if defined(TOTAL_ENERGY_SUPPORT)
clr_total_energy_pulse_indicator();
#endif
clr_total_reactive_energy_pulse_indicator();
#if defined(PER_PHASE_ENERGY_SUPPORT)
#if !defined(SINGLE_PHASE)
clr_phase_1_energy_pulse_indicator();
clr_phase_2_energy_pulse_indicator();
clr_phase_3_energy_pulse_indicator();
#else
clr_energy_pulse_indicator();
#endif
#endif
#if !defined(SINGLE_PHASE)
phase = chan;
phase_nv = nv_parms.seg_a.s.chan;
for (j = 0; j < NUM_PHASES; j++)
{
#endif
/* Prime the DC estimates for quick settling */
phase->current.I_dc_estimate[0] = phase_nv->current.initial_dc_estimate;
phase->current.I_endstops = ENDSTOP_HITS_FOR_OVERLOAD;
#if defined(SINGLE_PHASE) && defined(NEUTRAL_MONITOR_SUPPORT)
phase->neutral.I_dc_estimate[0] = phase_nv->current.initial_dc_estimate;
phase->neutral.I_endstops = ENDSTOP_HITS_FOR_OVERLOAD;
#endif
#if GAIN_STAGES > 1
phase->current.I_dc_estimate[1] = phase_nv->current.initial_dc_estimate;
#if defined(SINGLE_PHASE) && defined(NEUTRAL_MONITOR_SUPPORT)
phase->neutral.I_dc_estimate[1] = phase_nv->current.initial_dc_estimate;
#endif
#endif
#if defined(LIMP_MODE_SUPPORT)
phase->V_dc_estimate[0] = phase_nv->initial_v_dc_estimate;
phase->V_dc_estimate[1] = phase_nv->initial_v_limp_dc_estimate;
#else
phase->V_dc_estimate = phase_nv->initial_v_dc_estimate;
#endif
phase->V_endstops = ENDSTOP_HITS_FOR_OVERLOAD;
#if defined(MAINS_FREQUENCY_SUPPORT)
phase->mains_period = ((SAMPLES_PER_10_SECONDS*6554)/MAINS_NOMINAL_FREQUENCY) << 8;
#endif
#if !defined(SINGLE_PHASE)
phase++;
phase_nv++;
}
#endif
#if !defined(SINGLE_PHASE) && defined(NEUTRAL_MONITOR_SUPPORT)
neutral.I_dc_estimate = nv_parms.seg_a.s.neutral.initial_dc_estimate;
neutral.I_endstops = ENDSTOP_HITS_FOR_OVERLOAD;
#endif
#if defined(TEMPERATURE_SUPPORT)
temperature = 0;
#endif
#if defined(RTC_SUPPORT)
if (!check_rtc_sumcheck())
{
rtc.year = 7;
rtc.month = 6;
rtc.day = 11;
rtc.hour = 12;
rtc.minute = 0;
rtc.second = 0;
set_rtc_sumcheck();
}
#endif
#if defined(EXTERNAL_EEPROM_SUPPORT)
external_eeprom_init();
#endif
custom_initialisation();
_EINT();
#if defined(POWER_DOWN_SUPPORT)
/* Now go to lower power mode, until we know we should do otherwise */
switch_to_powerfail_mode();
#else
#if defined(__MSP430_HAS_SVS__)
/* Before we go to high speed we need to make sure the supply voltage is
adequate. If there is an SVS we can use that. There should be no wait
at this point, since we should only have been woken up if the supply
is healthy. However, it seems better to be cautious. */
SVSCTL |= (SVSON | 0x60);
/* Wait for adequate voltage to run at full speed */
while ((SVSCTL & SVSOP))
/* dummy loop */;
/* The voltage should now be OK to run the CPU at full speed. Now it should
be OK to use the SVS as a reset source. */
SVSCTL |= PORON;
#endif
/* Take control of the EEPROM signals. */
#if defined(EXTERNAL_EEPROM_SUPPORT)
enable_eeprom_port();
#endif
#if defined(__MSP430_HAS_FLLPLUS__) || defined(__MSP430_HAS_FLLPLUS_SMALL__)
/* Speed up the clock to 8.388608MHz */
SCFI0 = FN_3 | FLLD_4;
SCFQCTL = 64 - 1;
#if 0
{
int i;
for (i = 0xFFFF; i; i--);
_NOP();
_BIS_SR(SCG0);
}
SCFQCTL |= SCFQ_M;
SCFI0 &= ~0x03;
SCFI1 &= ~0x07;
SCFI1 += 8;
#endif
/* There seems no benefit in waiting for the FLL to settle at this point. */
#endif
#if defined(__MSP430_HAS_TA3__) && defined(__MSP430_HAS_ADC12__)
/* Enable the TIMER_A0 interrupt */
TACTL = TACLR | MC_1 | TASSEL_1;
TACCTL0 = CCIE;
#endif
kick_watchdog();
switch_to_normal_mode();
#endif
}
#else
void system_setup(void)
{
#if !defined(SINGLE_PHASE)
struct phase_parms_s *phase;
int j;
#endif
#if !defined(SINGLE_PHASE)
phase = chan;
for (j = 0; j < NUM_PHASES; j++)
{
#endif
/* Prime the DC estimates for quick settling */
#if defined(NEUTRAL_MONITOR_SUPPORT)
phase->neutral.I_dc_estimate = phase_nv->current.initial_dc_estimate;
#endif
phase->current.I_dc_estimate = phase_nv->current.initial_dc_estimate;
phase->V_dc_estimate[0] = phase_nv->initial_v_dc_estimate;
//phase->V_dc_estimate[1] = phase_nv->initial_v_limp_dc_estimate;
#if MAINS_FREQUENCY_SUPPORT
phase->mains_period = ((SAMPLES_PER_10_SECONDS*6554)/MAINS_NOMINAL_FREQUENCY) << 8;
#endif
#if !defined(SINGLE_PHASE)
phase++;
}
#endif
samples_per_second = SAMPLES_PER_10_SECONDS/10;
#if defined(TEMPERATURE_SUPPORT)
temperature = 0;
#endif
}
#endif
#if defined(__MSP430__)
void switch_to_normal_mode(void)
{
/* Switch to full speed, full power mode */
meter_status |= STATUS_PHASE_VOLTAGE_OK;
set_normal_indicator();
#if defined(__MSP430_HAS_ADC12__)
/* Change the ADC reference to Vref+ */
_DINT();
/* Must disable conversion while reprogramming the ADC */
ADC12CTL0 &= ~ENC;
/* Turn the Vref and ADC on. */
ADC12CTL0 = REFON | MSC | REF2_5V | ADC12ON | SHT0_2 | SHT1_2;
#if defined(SINGLE_PHASE)
ADC12MCTL0 = SREF_1 | AGND_INPUT;
ADC12MCTL1 = SREF_1 | NEUTRAL_CURRENT_INPUT;
ADC12MCTL2 = SREF_1 | AGND_INPUT;
ADC12MCTL3 = SREF_1 | LIVE_CURRENT_INPUT;
ADC12MCTL4 = SREF_1 | AGND_INPUT;
#if defined(TEMPERATURE_SUPPORT) | defined(BATTERY_MONITOR_SUPPORT)
ADC12MCTL5 = SREF_1 | VOLTAGE_INPUT;
#else
ADC12MCTL5 = EOS | SREF_1 | VOLTAGE_INPUT;
#endif
#if defined(BATTERY_MONITOR_SUPPORT)
#if defined(TEMPERATURE_SUPPORT)
ADC12MCTL6 = SREF_1 | BATTERY_INPUT;
#else
ADC12MCTL6 = EOS | SREF_1 | BATTERY_INPUT;
#endif
#endif
#if defined(TEMPERATURE_SUPPORT)
ADC12MCTL7 = EOS | SREF_1 | INCH_10; /* Temperature */
#endif
#else
#if GAIN_STAGES > 1
ADC12MCTL0 = SREF_1 | LIVE_LOW_CURRENT_INPUT_1;
ADC12MCTL1 = SREF_1 | LIVE_HIGH_CURRENT_INPUT_1;
ADC12MCTL2 = SREF_1 | VOLTAGE_INPUT_1;
ADC12MCTL3 = SREF_1 | LIVE_LOW_CURRENT_INPUT_2;
ADC12MCTL4 = SREF_1 | LIVE_HIGH_CURRENT_INPUT_2;
ADC12MCTL5 = SREF_1 | VOLTAGE_INPUT_2;
ADC12MCTL6 = SREF_1 | LIVE_LOW_CURRENT_INPUT_3;
ADC12MCTL7 = SREF_1 | LIVE_HIGH_CURRENT_INPUT_3;
ADC12MCTL8 = SREF_1 | VOLTAGE_INPUT_3;
#if defined(NEUTRAL_CURRENT_INPUT)
ADC12MCTL9 = SREF_0 | NEUTRAL_CURRENT_INPUT;
ADC12MCTL10 = EOS | SREF_1 | INCH_10; /* Temperature */
#else
ADC12MCTL9 = EOS | SREF_1 | INCH_10; /* Temperature */
#endif
#else
ADC12MCTL0 = SREF_1 | LIVE_CURRENT_INPUT_1;
ADC12MCTL1 = SREF_1 | AGND_INPUT;
ADC12MCTL2 = SREF_1 | VOLTAGE_INPUT_1;
ADC12MCTL3 = SREF_1 | LIVE_CURRENT_INPUT_2;
ADC12MCTL4 = SREF_1 | AGND_INPUT;
ADC12MCTL5 = SREF_1 | VOLTAGE_INPUT_2;
ADC12MCTL6 = SREF_1 | LIVE_CURRENT_INPUT_3;
ADC12MCTL7 = SREF_1 | AGND_INPUT;
ADC12MCTL8 = SREF_1 | VOLTAGE_INPUT_3;
#if defined(NEUTRAL_CURRENT_INPUT)
ADC12MCTL9 = SREF_0 | NEUTRAL_CURRENT_INPUT;
ADC12MCTL10 = EOS | SREF_1 | INCH_10; /* Temperature */
#else
ADC12MCTL9 = EOS | SREF_1 | INCH_10; /* Temperature */
#endif
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -