主题中讨论的其他器件:MSP430WARE、
工具与软件:
您好!
我希望每1s 启动一次 ADC 转换、而不是连续转换。 转换后、ADC 应进入睡眠状态。
- 采样时间1ms
- ACD12_B 时钟为 ACLK 32kHz
- 我正在检测来自两个 ADC 通道(A8和 A14)(通道序列)的数据
有任何与此相关的 driverlib 示例吗?
我在数据表中找到了下面的屏幕截图、请说明以下数据。
提前感谢、
Sarwath
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.
工具与软件:
您好!
我希望每1s 启动一次 ADC 转换、而不是连续转换。 转换后、ADC 应进入睡眠状态。
有任何与此相关的 driverlib 示例吗?
我在数据表中找到了下面的屏幕截图、请说明以下数据。
提前感谢、
Sarwath
您好、Sarwath、
感谢您问这个问题! 我认为、MSP430Ware 3.80.14.01 SDK 中的 msp430fr6043_ADC12_11示例是一个很好的实施起点。 此示例包含计时器代码、因此您可以对其进行调整以每秒触发 ADC 采样。 此 SDK 中还有一些示例、提供了将 MCU 置于低功耗模式、对多个 ADC 通道进行采样等的代码
相对于图表中的数据、这里显示了 ADC 不同的可用外部触发源连接。 您还可以使用基于软件的触发器、它是表中的第一个触发器。
-Brian
尊敬的 Brian Dempsey:
感谢您的答复。
我学习了这个msp430fr6043_adc12_11
示例、并在 ADC 应用中进行了类似的设置。
我以32kHz 的 ACLK 运行 ADC 和 Timer_A1。
ADC 设置:
Fadcclock=32kHz
1个周期= 31.25us
"我的采样时间为1ms、所以我要ADC12_B_CYCLEHOLD_32_CYCLES
在ADC12_B_setupSamplingTimer
函数中进行设置
void adcSetup() { /***** adc hw 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_4; /***** sc bat channel A8 setup ******/ memory_init1.memoryBufferControlIndex = ADC12_B_MEMORY_0; memory_init1.inputSourceSelect = ADC12_B_INPUT_A8; memory_init1.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS; memory_init1.endOfSequence = ADC12_B_NOTENDOFSEQUENCE; memory_init1.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE; memory_init1.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE; /***** bat inv channel A14 setup ******/ memory_init2.memoryBufferControlIndex = ADC12_B_MEMORY_1; memory_init2.inputSourceSelect = ADC12_B_INPUT_A14; memory_init2.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS; memory_init2.endOfSequence = ADC12_B_ENDOFSEQUENCE; memory_init2.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE; memory_init2.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE; /***** adc initialization ******/ ADC12_B_init(ADC12_B_BASE, &adc_init); /***** adc sampling timer ******/ ADC12_B_setupSamplingTimer(ADC12_B_BASE, ADC12_B_CYCLEHOLD_32_CYCLES, ADC12_B_CYCLEHOLD_4_CYCLES, ADC12_B_MULTIPLESAMPLESENABLE); /***** configuring Memory 0 ******/ ADC12_B_configureMemory(ADC12_B_BASE, &memory_init1); /***** configuring Memory 1 ******/ ADC12_B_configureMemory(ADC12_B_BASE, &memory_init2); /***** clear adc interrupt ******/ ADC12_B_clearInterrupt(ADC12_B_BASE, 0, 0); /***** enable adc interrupt on memory 1 ******/ //ADC12_B_enableInterrupt(ADC12_B_BASE, ADC12_B_IE1, 0, 0); /***** enable adc ******/ ADC12_B_enable(ADC12_B_BASE); /***** start conversion ******/ ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_SEQOFCHANNELS); }
计时器 A1设置:
FtimerA1时钟:32kHz/8:4kHz
一个周期为250 µs。 我想生成10秒的 ISR。 每隔10秒、ADC 会在 Timer_A1 ISR 中开始转换、并且我将通过轮询来读取 ADC 数字转换数据
void timerSetup() { TA1CCTL0 = CCIE; TA1CCR0 = 40000-1; // PWM Period TA1CCTL1 = OUTMOD_3; // TACCR1 set/reset TA1CCR1 = 39999; // TACCR1 PWM Duty Cycle TA1CTL = TASSEL__ACLK|ID__8| MC__UP; // ACLK, up mode } #pragma vector = TIMER1_A0_VECTOR __interrupt void Timer1_A0_ISR (void){ /**** enable adc *****/ ADC12_B_enable(ADC12_B_BASE); /***** start conversion *****/ ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_SEQOFCHANNELS); }
在运行时、我只在第一次转换时获得 ADC 数据。 如果我更改电压、ADC 数据保持不变(之前的数据)。
如何得出 ADC 转换时间。 是否有任何可用的公式
提前感谢、
Sarwath
这里显示为混合模式:startConversion 使用 ADC12SC 启动转换(就像 ADC12SHS=0一样)、但通过设置 ADC12SHS=4、计时器也会触发转换。
转换需要(SAMPLE_TIME + 13* ADC_CLOCK_PERIOD)或大约(1ms + 13 * 32usec)或大约1.4ms。 由于计时器在计时器中断之前发生(8*32usec)=~250usec、因此当 startConversion 再次启动时、ADC 很可能仍在运行。 这(加上您的症状)表明您因勘误表 ADC42而跳闸、在上一个转换处于活动状态时触发新的转换会使 ADC 停转[参考勘误表(SLAZ715B)第5页]。
考虑到您所显示的代码、最简单/最小的更改可能是在 ISR 中保留 startConversion 调用、但切换到 ADC12_B_SAMPLEHOLDSOURCE_0 (软件触发器)。
您好 Bruce McKenney、
我已根据上述建议对代码进行了更改。
1. ADC 转换触发: ADC12_B_SAMPLEHOLDSOURCE_SC
void adcSetup() { /***** adc hw 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; /***** sc bat channel A8 setup ******/ memory_init1.memoryBufferControlIndex = ADC12_B_MEMORY_0; memory_init1.inputSourceSelect = ADC12_B_INPUT_A8; memory_init1.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS; memory_init1.endOfSequence = ADC12_B_NOTENDOFSEQUENCE; memory_init1.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE; memory_init1.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE; /***** bat inv channel A14 setup ******/ memory_init2.memoryBufferControlIndex = ADC12_B_MEMORY_1; memory_init2.inputSourceSelect = ADC12_B_INPUT_A14; memory_init2.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS; memory_init2.endOfSequence = ADC12_B_ENDOFSEQUENCE; memory_init2.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE; memory_init2.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE; /***** adc initialization ******/ ADC12_B_init(ADC12_B_BASE, &adc_init); /***** adc sampling timer ******/ ADC12_B_setupSamplingTimer(ADC12_B_BASE, ADC12_B_CYCLEHOLD_32_CYCLES, ADC12_B_CYCLEHOLD_4_CYCLES, ADC12_B_MULTIPLESAMPLESENABLE); /***** configuring Memory 0 ******/ ADC12_B_configureMemory(ADC12_B_BASE, &memory_init1); /***** configuring Memory 1 ******/ ADC12_B_configureMemory(ADC12_B_BASE, &memory_init2); }
2.在10秒内开始 ADC 转换 Timer1_A0_ISR 触发信号。
void timerSetup() { TA1CCTL0 = CCIE; TA1CCR0 = 40000-1; // PWM Period TA1CCTL1 = OUTMOD_3; // TACCR1 set/reset TA1CCR1 = 39999; // TACCR1 PWM Duty Cycle (39999 cycles is 10seconds) TA1CTL = TASSEL__ACLK|ID__8 | MC__UP; // ACLK, up mode } #pragma vector = TIMER1_A0_VECTOR __interrupt void Timer1_A0_ISR (void){ /**** enable adc *****/ ADC12_B_enable(ADC12_B_BASE); /**** start conversion *****/ ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_SEQOFCHANNELS); }
在我的应用程序中、我正在使用ADC12_B_SEQOFCHANNELS
而不是ADC12_B_REPEATED_SEQOFCHANNELS
。 ADC 转换在计时器 ISR 中开始、并在转换时间后完成。 要启动下一次转换、ADC 必须等待计时器 ISR 再次触发它。
我担心的是转换之间的等待时间:在此等待时间期间、ADC 是否会进入自动关断模式? 在我的应用中、我还使用低功耗模式3 (LPM3)来节约能源。
谢谢!
是的、它将在突发之间自动断电。 [勘误表 ADC65仅适用于突发脉冲、因此 在使用 ADC12_B_MULTIPLESAMPLESENABLE 时并不重要。]
如果你想确定一点、可以 在 ADC 完成 ISR 中调用 ADC12_B_disableConversions()、设置 ADC12ENC=0。 您稍后的 ADC12_B_startConversion ()将为您设置 ADC12ENC=1。
使用时会自动断电吗 ADC12_B_MULTIPLESAMPLESENABLE。
2.是的,我理解你的观点。 ADC 转换完成并触发 ISR 后、我将读取数据、然后禁用 ADC 转换。 在10秒计时器 ISR 中、我将启用 ADC 转换。 ADC12_B_disableConversions
禁用 ADC 转换是更好ADC12_B_disable
的选择、还是更好的选择?
1)是的,一旦爆破完成——在那一点,它已经完成了它被要求做的一切。
2) 2) ADC12_B_DISABLE 设置 ADC12ON=0。 (它还会设置 ADC12ENC=0、这样可以节省一个步骤。) 我不知道设置 ADC12ON=0或者关于这一点、ADC12ENC=0是否会为你节省任何可测量值(我还没有测量它)。 另一方面,如果你每10秒只做一次,这可能被认为是"廉价保险"(强调"廉价")。 切记在您返回时调用 ADC12_B_ENABLE (ADC12ON=1)、因为 startConversion 不会提供。