主题中讨论的其他器件:ENERGYTRACE
你好,福米特人。
我计划使用2节 AA 电池开发一个为期一年的实验原型。 我的目标是尽可能减小平均电流。 为此、我使用的是 Energy Trace (不是++)、因此我只能看到我的 LaunchPad 消耗了多少电流、或者消耗了多少功率和能量。 显然、出于开发目的、我每8秒记录一次温度。
我使用具有周期性唤醒功能的 LPM3模式、并在唤醒后激活内部温度传感器中断、以便可以执行单次读取并再次进入睡眠模式。 但是、我如何才能从该原型中获得更多能量? 我正在按照 ULP 的建议执行此操作:将 除 A12 (引脚1.2)以外的所有引脚转换为启用下拉的输入。 我将 ACLK 时钟用于 ADC 内核和计时器。 任何建议都值得赞赏。 我不要求任何人给我提供代码、不要让我出错、而是让我激活禁用代码等
我还在睡眠模式下花费100uA (LMP0规定为40uA、根据数据表、LPM3和 RTC 的花费1uA)、必须有一些外设处于活动状态、我需要在某个位置禁用更多外设。
//****************************************************************************** // In this example project, we are mostly sleeping and waking up every 8 seconds // to measure temperature and record it to FRAM Information Memory Region. // // Memory Layout: // Byte 1: Session ID(To track how many times recording session is started) // Byte 2: How many recordings are saved in the session // Byte 3-..: Start to put recordings from byte 3 and onward. Use the counter // value in Byte 2 to understand how many readings are valid. //****************************************************************************** #include <msp430.h> void FRAMWriteTemp(void); void FRAMWriteSession(void); void initGPIOUnusedInputPulldown(void); void initADC(void); void initACLKTimer(void); // See device datasheet for TLV table memory mapping #define CALADC_15V_30C *((unsigned int *)0x1A1A) // Temperature Sensor Calibration-30 C #define CALADC_15V_85C *((unsigned int *)0x1A1C) // Temperature Sensor Calibration-85 C #define FRAM_TEST_START 0x1800 volatile long temp = 0; volatile long ADC_Value = 0; unsigned int count = 0; char *FRAM_start_ptr = (char*) FRAM_TEST_START; char *FRAM_count_ptr = (char*) (FRAM_TEST_START + 1); char *FRAM_write_ptr = (char*) (FRAM_TEST_START + 2); int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer initGPIOUnusedInputPulldown(); initACLKTimer(); initADC(); FRAMWriteSession(); while (count < 250) { // The temperature (Temp, C)= temp = (ADC_Value - CALADC_15V_30C) * 55 / (CALADC_15V_85C - CALADC_15V_30C) + 30; FRAMWriteTemp(); __bis_SR_register(GIE | LPM3_bits); // Enable maskables and start Low Power Mode 0 } return 0; } // Timer A0 interrupt service routine: Enable the ADC interrupts and start // ADC conversion. Delay for some time to settle ref voltage setting. #pragma vector = TIMER0_A1_VECTOR __interrupt void Timer_A(void) { TA0CTL &= ~(TAIFG); // Clear the interrupt ADCIE |= ADCIE0; // Enable the conversion complete interrupt; ADCCTL0 |= ADCENC | ADCSC; // Enable and start the conversion __delay_cycles(400); // Delay for reference settling } // Record ADC Reading and disable ADC Interrupts. After this ISR, control goes // to main loop #pragma vector = ADC_VECTOR __interrupt void ADC_ISR(void) { __bic_SR_register_on_exit(LPM3_bits); ADC_Value = ADCMEM0; ADCIE &= ~ADCIE0; // Disable the conversion complete interrupt; } void FRAMWriteTemp(void) { SYSCFG0 = FRWPPW | PFWP; // This instruction removes DFWP, makes FRAM writeable *FRAM_count_ptr = (*FRAM_count_ptr) + 1; // Update count field in FRAM *FRAM_write_ptr++ = temp; // Record the temperature SYSCFG0 = FRWPPW | PFWP | DFWP; // This instruction locks FRAM again count++; // Update count } void FRAMWriteSession(void) { SYSCFG0 = FRWPPW | PFWP; *FRAM_start_ptr = (*FRAM_start_ptr) + 1; *FRAM_count_ptr = 0; SYSCFG0 = FRWPPW | PFWP | DFWP; } void initGPIOUnusedInputPulldown(void) { // Set all P1 pins except 1.2 to input with pulldown resistor P1SEL1 = P1SEL0 = 0; P1DIR = 0; P1OUT &= ~(BIT0 | BIT1 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P1REN |= BIT0 | BIT1 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7; // Set all P2 pins to input with pulldown resistor P2SEL1 = P2SEL0 = 0; P2DIR = 0; P2OUT = 0; P2REN = 0xFF; // Set all P3 pins to input with pulldown resistor P3SEL1 = P3SEL0 = 0; P3DIR = 0; P3OUT = 0; P3REN = 0xFF; // Finally, set P1.2 to analog function P1SEL1 |= BIT2; P1SEL0 |= BIT2; // Set 11 to both bits for Temp Sensor(A12 -> P1.2) PM5CTL0 &= ~LOCKLPM5; // Turn on IO } // Configure Analog 12(Internal Temp Sensor) void initADC(void) { // Configure the ADC ADCCTL0 &= ~ADCSHT_15; // Clear Conversion Clock Cycles ADCCTL0 |= ADCSHT_1; // Set SHT to 8 Conversion Clock Cycles ADCCTL0 |= ADCON; // Set ADC Core on ADCCTL1 |= ADCSSEL_1; // Choose ACLK as Source Clock ADCCTL1 |= ADCSHP; // Sample signal source = sampling timer //ADCCTL1 |= ADCDIV_7; // ADC Clock Divider set to /8 to slow sampling ADCCTL2 |= ADCRES_1; // 10-bit conversion results //ADCCTL2 |= ADCPDIV__64; // ADC Pre Clock Divider set to /64 to slow sampling ADCMCTL0 |= ADCSREF_1 | ADCINCH_12; // Set A2 as ADC Input // Configure reference PMMCTL0_H = PMMPW_H; // Unlock the PMM registers PMMCTL2 |= INTREFEN | TSENSOREN; // Enable internal reference and temperature sensor } // Intended to raise interrupt every 8 seconds to initiate temperature sensing void initACLKTimer(void) { TA0CTL |= TASSEL__ACLK; // Set clock source to ACLK TA0CTL |= TAIE; // Enable Timer A Interrupts TA0CTL |= TACLR; // Clear Timer A Register TA0CTL |= ID_2; // Slow Timer by 2^X (ID_X) //TA0EX0 |= TAIDEX_7; // Slow timer by Y+1 times (TAIDEX_Y) TA0CTL |= MC__CONTINUOUS; // Set continuous mode }