2008-11-04 02:11 AM
ADC / ADC Watchdog Triggered by Timer
2011-05-17 03:47 AM
Hi,
I'm trying to get an ADC conversation, triggered by TIM1 CC2 to work here is my code for ADC conversation:Code:
<BR> ADC_InitSingleShot.ADC_Mode = ADC_Mode_Independent; <BR> ADC_InitSingleShot.ADC_ScanConvMode = DISABLE; <BR> ADC_InitSingleShot.ADC_ContinuousConvMode = DISABLE; <BR> ADC_InitSingleShot.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC2; <BR> ADC_InitSingleShot.ADC_DataAlign = ADC_DataAlign_Right; <BR> ADC_InitSingleShot.ADC_NbrOfChannel = USED_REGULAR_ADC_CHANNELS; <BR> ADC_Init(ADC1, &ADC_InitSingleShot); <BR> <BR> // ADC1 regular channel14 configuration <BR> ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5); <BR> //ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_1Cycles5); <BR> <BR> // Set injected sequencer length <BR> ADC_InjectedSequencerLengthConfig(ADC1, 1); <BR> <BR> // ADC1 injected channel Configuration <BR> ADC_InjectedChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_1Cycles5); <BR> <BR> // ADC1 injected external trigger configuration <BR> ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); <BR> <BR> // Disable automatic injected conversion start after regular one <BR> ADC_AutoInjectedConvCmd(ADC1, DISABLE); <BR> <BR> /* Enable ADC1 external trigger */ <BR> ADC_ExternalTrigConvCmd(ADC1, ENABLE); <BR> <BR> /* Enable EOC interupt */ <BR> ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); <BR> <BR> // Enable ADC1 <BR> ADC_Cmd(ADC1, ENABLE); <BR> <BR> // Enable ADC1 reset calibaration register <BR> ADC_ResetCalibration(ADC1); <BR> // Check the end of ADC1 reset calibration register <BR> while(ADC_GetResetCalibrationStatus(ADC1)); <BR> <BR> // Start ADC1 calibaration <BR> ADC_StartCalibration(ADC1); <BR> // Check the end of ADC1 calibration <BR> while(ADC_GetCalibrationStatus(ADC1)); <BR> <BR>
And this is the code for the ADC Watchdog part. At this point I made the assumption, that the Watchdog would not fire, as long as the ADC conversation is not running. So my goal is to set up the ADC conversation in continious mode, trigger it via an timer and stop the conversation later in the AWD_IT.Code:
<BR> // Enable ADC2 clock <BR> RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); <BR> <BR> //ADC2 configuration <BR> ADC_InitWatchdog.ADC_Mode = ADC_Mode_Independent; <BR> ADC_InitWatchdog.ADC_ScanConvMode = DISABLE; <BR> ADC_InitWatchdog.ADC_ContinuousConvMode = ENABLE; <BR> ADC_InitWatchdog.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; <BR> ADC_InitWatchdog.ADC_DataAlign = ADC_DataAlign_Right; <BR> ADC_InitWatchdog.ADC_NbrOfChannel = 1; <BR> ADC_Init(ADC2, &ADC_InitWatchdog); <BR> <BR> // ADC2 regular channel14 configuration <BR> ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_1Cycles5); <BR> <BR> // Configure high and low analog watchdog thresholds <BR> ADC_AnalogWatchdogThresholdsConfig(ADC2, 505, 500); <BR> <BR> // Configure channel4 as the single analog watchdog guarded channel <BR> ADC_AnalogWatchdogSingleChannelConfig(ADC2, ADC_Channel_4); <BR> <BR> // Enable analog watchdog on one regular channel <BR> ADC_AnalogWatchdogCmd(ADC2, ADC_AnalogWatchdog_SingleRegEnable); <BR> <BR> // Disable automatic injected conversion start after regular one <BR> ADC_AutoInjectedConvCmd(ADC2, DISABLE); <BR> <BR> // Disable EOC interupt <BR> ADC_ITConfig(ADC2, ADC_IT_EOC, DISABLE); <BR> <BR> // Enable ADC1 external trigger <BR> //ADC_ExternalTrigConvCmd(ADC2, ENABLE); <BR> <BR> // Enable ADC2 <BR> ADC_Cmd(ADC2, ENABLE); <BR> <BR> // Enable ADC2 reset calibaration register <BR> ADC_ResetCalibration(ADC2); <BR> // Check the end of ADC2 reset calibration register <BR> while(ADC_GetResetCalibrationStatus(ADC2)); <BR> <BR> // Start ADC2 calibaration <BR> ADC_StartCalibration(ADC2); <BR> // Check the end of ADC2 calibration <BR> while(ADC_GetCalibrationStatus(ADC2)); <BR>
I enabled TIM1 and set the CCs, and enabled the ADC1_2_IRQChannel in the NVIC. But for some reason I never get an EOC or AWD interrupt. I confirmed, that this code works, If I set TrigerConvetion to None, and use ADC_SoftwareStartConvCmd to start the conversation Thanks in Advance Janosch [ This message was edited by: janosch.machowinski on 09-10-2008 17:34 ]2011-05-17 03:47 AM
I looked further into this issue and discovered the following :
As far as I can see, the timer, that should trigger the ADC needs to be configured as PWM Output. As I use TIM1 only as an internal timer, I remapped TIM1 pins to the nirvana (PE) and configured it as PWM output. Anyway, PLEASE INCLUDE THIS IN THE DOCUMENTATION. I spend 3 days on this, and it could all have been avoided by the little sentence ''ADC CC Triggering only works if configured as PWM''.2011-05-17 03:47 AM
Just to clarify this, Everything works, if I set
ADC_InitWatchdog.ADC_ExternalTrigConv = ADC_ExternalTrigConvNone ADC_InitWatchdog.ADC_ExternalTrigConv = ADC_ExternalTrigConvNone and use ADC_SoftwareStartConvCmd(ADC1, ENABLE); ADC_SoftwareStartConvCmd(ADC2, ENABLE); to trigger the whole thing. But as I do some high speed H-Bridge Control I rely on starting ADC Conversion, and Watchdog functionality at a certain small time window. That's why I chose to use the whole trigger thing. And this is the point where it stops working. I watch the Timer1 over USART and can see that it runs into CC2 and CC3, but my ADC doesn't start to do anything. So my main question is why dosen't the CC2 or CC3 event start my ADC conversation ?2011-05-17 03:47 AM
I've been trying to do much the same thing see my earlier
post with subject [example: 3ADCs_DMA]. Just run the 3ADCs_DMA example in the Firmware Library examples (\FWLib\examples\ADC\3ADCs_DMA), and try to set a breakpoint inside of the interrupt service routine (ADC1_2_IRQHandler()). Though I haven't yet put any signal on the (ISR converted) channel13, I have run the example and GET NO BREAK when a breakpoint is set inside the ADC1_2_IRQHandler(). What the example does is it throws an HardFaultException(). I had a look at the assembly listing (see my post here: ) and I halted the code just before it entered the HardFaultException() Just before it entered the HardFaultException() the PC was zero (would make sense that it threw a HardFaultException()) with that, but what puzzles me is this: 0x00000000 ; PADDING 353: ADC2ConvertedValue = ADC_GetConversionValue(ADC2); This is where the PC points to just before the exception. It appears to be the data location for where the ISR is supposed to put the ADCs result (am I right?) Wierd hu? Did anybody test this piece of code before it went out? From what I've seen ADC works fine as long as you use DMA to transfer the result. Unfortunately there are precious few examples that do NOT use DMA (this the only one I've seen and it doesn't work.) Just in case its my tools, I'm using Ride7/GCC to compile/link, and Signum's JTagJet/Cortex3M with their Chameleon debugger. I do NOT think it's the tools but who knows. CC2011-05-17 03:47 AM
Hi Janosch,
I am trying to do a similar task to yourself with no luck. The documentation was not clear about needing to use the pwm mode. Would it be possible to see yours/a sample solution to this using the PWM feature as i am struggling to get the adc to start even using it. the CC2 interupt is being set but no further action is occuring. thankyou in advance Gareth