cancel
Showing results for 
Search instead for 
Did you mean: 

F301 ADC injected conversion std peripheral lib commands

avik
Associate II
Posted on February 16, 2016 at 23:14

I'd like get analog readings from pin PB0 triggered from timer 1 CC4, on my F301K6. I have configured the GPIO settings to set PB0 for analog input. There aren't any examples of injected conversion in the peripheral library examples directory, so I'm trying to figure out the API commands to do this.

  ADC_InjectedDiscModeCmd(ADC1, ENABLE);

  ADC_InjectedInitTypeDef initStruct;

  ADC_InjectedStructInit(&initStruct);

  initStruct.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_1;

  initStruct.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigInjecEventEdge_FallingEdge;

  initStruct.ADC_NbrOfInjecChannel = 1;

  initStruct.ADC_InjecSequence1 = ADC_InjectedChannel_11;

  ADC_InjectedInit(ADC1, &initStruct);

Even before setting up the timer trigger, am I correctly setting ''ADC_InjecSequence1 = ADC_InjectedChannel_11'' correctly? PB0 is listed as ADC1_IN11 in the datasheet. 

I have other problems with timer triggering, but even when I software start the conversion using ''ADC_StartInjectedConversion(ADC1);'' the values I get seem wrong so I'm worried that I'm not connecting to PB0 properly.
3 REPLIES 3
avik
Associate II
Posted on February 17, 2016 at 20:25

I've gotten software start to work now, by setting ADC_ExternalTrigEventEdge_None and calling ADC_StartInjectedConversion(ADC1). However, I'm not able to get timer1 CC4 to trigger the conversion. Timer1 is configured correctly since channels 1-3 are properly driving a motor.

  TIM_OCInitTypeDef  TIM_OCInitStructure;

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = 0;

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC4Init(TIM1, &TIM_OCInitStructure);

  // detect 10% into the PWM cycle

  TIM_SetCompare4(TIM1, (uint32_t)(0.1*TIM1->ARR));

  // GPIO setup for PB0...

  ADC_InjectedChannelSampleTimeConfig(ADC1, ADC_InjectedChannel_11, ADC_SampleTime_7Cycles5);

  ADC_InjectedDiscModeCmd(ADC1, ENABLE);

  ADC_InjectedInitTypeDef initStruct;

  ADC_InjectedStructInit(&initStruct);

  initStruct.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_1;

  initStruct.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigInjecEventEdge_FallingEdge;

  initStruct.ADC_NbrOfInjecChannel = 1;

  initStruct.ADC_InjecSequence1 = ADC_InjectedChannel_11;

  ADC_InjectedInit(ADC1, &initStruct);

With the code above, ''ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC)'' never returns ''SET''. Additionally I got the injected conversion event 1 from the reference manual table 33 which says:

''JEXT1 | TIM1_CC4 event | Internal signal from on chip timers''

I'm not sure I am reading/implementing correctly but this was my best guess.

What am I doing wrong? Thanks for any help!

PS. I can't figure out how to format the code above, but hopefully it's small enough that everything is legible.

Posted on February 17, 2016 at 21:57

Format Code Block is ''Paintbrush [< >]''  Icon.

Not using an F301 here, but it does look like TIM1_CH4 should trigger here. You could output via a pin and confirm. CH4 doesn't have the N channel, but does require the TIM_OCIdleState setting. Fill or clear the whole structure.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
avik
Associate II
Posted on February 18, 2016 at 18:31

Thanks clive1 for the answer. I output Tim1 Ch4 on PA11, and checked on a scope. It was outputting a 10% duty cycle wave at 19KHz, so that part seems OK.

I found some new info by reading the comments for

ADC_StartInjectedConversion

in the stm32f30x_adc.c file: ''Enable the selected ADC conversion for injected group on external event and start the selectedADC injected conversion''. So my new ADC-related code is now:

// 1. set JSQR
ADC_InjectedInitTypeDef initStruct;
ADC_InjectedStructInit(&initStruct);
initStruct.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_1;
// initStruct.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigEventEdge_None;
initStruct.ADC_ExternalTrigInjecEventEdge = ADC_ExternalTrigInjecEventEdge_FallingEdge;
initStruct.ADC_NbrOfInjecChannel = 1;
initStruct.ADC_InjecSequence1 = ADC_InjectedChannel_11;
ADC_InjectedInit(ADC1, &initStruct);
// 3. set sample time
ADC_InjectedChannelSampleTimeConfig(ADC1, ADC_InjectedChannel_11, ADC_SampleTime_7Cycles5);
// 4. set JQM
ADC_SelectQueueOfContextMode(ADC1, DISABLE);
// 5. set JAUTO
ADC_AutoInjectedConvCmd(ADC1, DISABLE);
ADC_InjectedDiscModeCmd(ADC1, ENABLE);
// Hardware-injected conversion is started after the JADSTART bit is set, and at the next active edge of the selected injected hardware trigger.
ADC_StartInjectedConversion(ADC1);

CC4 setup code:

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM1, &TIM_OCInitStructure);
// detect 10% into the PWM cycle
TIM_SetCompare4(TIM1, (uint32_t)(0.1*TIM1->ARR));

However the conversion is still not triggered by the timer, and only by explicitly calling ''ADC_StartInjectedConversion''.Do I need to enable/handle any interrupts? I assumed that the conversions would happen triggered by the timer and I could read the converted value usingADC_GetInjectedConversionValue.