Part Number: MSP430FR6043 Tool/software: Hello, I want to configure the ADC12_B and REF_A module based on the power state. Power Source ADC Behavior Internal Battery ADC12_B and REF_A is triggered once every 1 second , then turned off in the ISR to save power. External Supply ADC12_B and REF_A is reconfigured to run in repeated sequence mode for continuous conversion . Internal Battery Mode configuration: void ADC_initInternalMode() { ADC12_B_disableConversions(ADC12_B_BASE, ADC12_B_PREEMPTCONVERSION); ADC12_B_disable(ADC12_B_BASE); // Disable reference and wait for it to be free REFCTL0 &= ~REFON; while (REFCTL0 & REFGENBUSY); REFCTL0 |= REFVSEL_1 | REFON; // 2.0V internal ref while (!(REFCTL0 & REFGENRDY)); __delay_cycles(75); // Allow settling time // ADC hardware setup adc_init.clockSourceSelect = ADC12_B_CLOCKSOURCE_ACLK; adc_init.clockSourceDivider = ADC12_B_CLOCKDIVIDER_1; adc_init.clockSourcePredivider = ADC12_B_CLOCKPREDIVIDER__1; adc_init.internalChannelMap = ADC12_B_NOINTCH; adc_init.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC; // Configure channels: Battery (A8), Valve (A9), External (A14) // Memory buffer setup (0 to 2) // End-of-sequence marked on last channel memory_init1 = (ADC12_B_configureMemoryParam){ .memoryBufferControlIndex = ADC12_B_MEMORY_0, .inputSourceSelect = ADC12_B_INPUT_A8, .refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS, .endOfSequence = ADC12_B_NOTENDOFSEQUENCE }; memory_init2 = (ADC12_B_configureMemoryParam){ .memoryBufferControlIndex = ADC12_B_MEMORY_1, .inputSourceSelect = ADC12_B_INPUT_A9, .refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS, .endOfSequence = ADC12_B_NOTENDOFSEQUENCE }; memory_init3 = (ADC12_B_configureMemoryParam){ .memoryBufferControlIndex = ADC12_B_MEMORY_2, .inputSourceSelect = ADC12_B_INPUT_A14, .refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS, .endOfSequence = ADC12_B_ENDOFSEQUENCE }; ADC12_B_init(ADC12_B_BASE, &adc_init); ADC12_B_setupSamplingTimer(ADC12_B_BASE, ADC12_B_CYCLEHOLD_32_CYCLES, ADC12_B_CYCLEHOLD_4_CYCLES, ADC12_B_MULTIPLESAMPLESENABLE); ADC12_B_configureMemory(ADC12_B_BASE, &memory_init1); ADC12_B_configureMemory(ADC12_B_BASE, &memory_init2); ADC12_B_configureMemory(ADC12_B_BASE, &memory_init3); ADC12_B_clearInterrupt(ADC12_B_BASE, 0, ADC12_B_IFG2); ADC12_B_enableInterrupt(ADC12_B_BASE, ADC12_B_IE2, 0, 0); ADC12_B_enable(ADC12_B_BASE); ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_SEQOFCHANNELS); } External power mode configuration: void ADC_initExternalMode() { ADC12_B_disableConversions(ADC12_B_BASE, ADC12_B_PREEMPTCONVERSION); ADC12_B_disable(ADC12_B_BASE); REFCTL0 &= ~REFON; while (REFCTL0 & REFGENBUSY); REFCTL0 |= REFVSEL_1 | REFON; while (!(REFCTL0 & REFGENRDY)); __delay_cycles(75); adc_init.clockSourceSelect = ADC12_B_CLOCKSOURCE_ACLK; adc_init.clockSourceDivider = ADC12_B_CLOCKDIVIDER_1; adc_init.clockSourcePredivider = ADC12_B_CLOCKPREDIVIDER__1; adc_init.internalChannelMap = ADC12_B_NOINTCH; adc_init.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC; // Same memory configuration as internal mode ADC12_B_init(ADC12_B_BASE, &adc_init); ADC12_B_setupSamplingTimer(ADC12_B_BASE, ADC12_B_CYCLEHOLD_32_CYCLES, ADC12_B_CYCLEHOLD_4_CYCLES, ADC12_B_MULTIPLESAMPLESENABLE); ADC12_B_configureMemory(ADC12_B_BASE, &memory_init1); ADC12_B_configureMemory(ADC12_B_BASE, &memory_init2); ADC12_B_configureMemory(ADC12_B_BASE, &memory_init3); ADC12_B_clearInterrupt(ADC12_B_BASE, 0, ADC12_B_IFG2); ADC12_B_disableInterrupt(ADC12_B_BASE, ADC12_B_IE2, 0, 0); ADC12_B_enable(ADC12_B_BASE); ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_REPEATED_SEQOFCHANNELS); } In internal battery mode, the ADC ISR is enabled. At each ISR trigger, I turn off both the ADC12_B and REF_A modules. They are re-enabled after a 1-second timeout. void ADC_Handler() { // ADC handler running in 10ms timer loop if(PowerstateSwitch == "Internal") { //ADC_UPDATE_DURATION is 1000 if (ADC_capture_enable_counter >= ADC_UPDATE_DURATION) { Ref_A_enableReferenceVoltage(REF_A_BASE); if(Ref_A_isRefGenActive(REF_A_BASE)) { ADC12_B_enable(ADC12_B_BASE); ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_SEQOFCHANNELS); ADC_capture_enable_counter = 0; } ADC_DataRead(); } else { ADC_capture_enable_counter += 10; } } else { ADC_DataRead(); } } #pragma vector=ADC12_B_VECTOR __interrupt void ADC12ISR(void) { if (PowerstateSwitch == false) // internal supply { ADC12_B_disable(ADC12_B_BASE); // Save power Ref_A_disableReferenceVoltage(REF_A_BASE); // Save more power } ADC12_B_clearInterrupt(ADC12_B_BASE, 0, ADC12_B_IFG2); ADC_DataRead(); // Read the latest values } In external supply mode, both modules are reconfigured and run continuously without the ADC ISR. Could anyone confirm if my implementation is correct? To reduce power consumption I made this setup. Regards, Sakhan
↧