cancel
Showing results for 
Search instead for 
Did you mean: 

DAC/ADC conversion + timer triggering

Omar Suárez
Senior
Posted on January 16, 2018 at 10:34

Hello,

I need to control the acquisition and generation of a signal using the STM32F746ZG and its internal DAC and ADC. The idea is to trigger the DAC using one timer and the ADC using another timer (without the use of DMA by now). I will use the STM32F7Cube HAL to generate the code.

I am trying to gather some information and code examples about how to configure those peripherals but I am not finding many examples.

Does anybody knows where I could find some example projects using those peripherals?

I found one using the ADC triggering mode (STM32F7CubeHAL - STM32F769I_EVAL) but I am still trying to make it work with my board but I have nothing using the DAC.

Thanks in advanced,

Omar

#stm32f7-hal #enable-adc #trigger-timer #dac
11 REPLIES 11
Rich G
Associate II
Posted on February 02, 2018 at 15:58

Hi I asked ST a similar question, and they pointed me to an example in their reply:

'You can find an example in the repository of the library for STM32F7

Repository is under c:\your user name\stm32CUBE

You find here repertory for each STM32family , for you at lesast the one for STM32F7 (STM32Cube_FW_F7_V1.8.0

In this last one you have : STM32F769I_EVAL\Examples\ADC\ADC_TriggerMode.

Check in the readmd.txt file the description of this example.

As far as it just a similar (F769) intead of F746, you can use this example with your device.'

However, I can't seem to get the ADC conversion complete callback function to be invoked. As a tester, I got the timer callback function working, but not the ADC.

So, I don't know if this is any help to you, but I share it in case it may be.

henry.dick
Senior II
Posted on February 05, 2018 at 15:58

A few simple steps.

1. Set up a timer to periodically interrupt.

2. Write a piece of code to trigger adc. It is to be called from one of timers isr.

3. Write another piece of code to be called from within the other timers isr.

That's it.

However, you can optimized it further.

1. Adc often takes a long time for the mcu. One approach is free run the adc and you only need to read the most recent result in the is.

Another is to set up the adc in interrupt mode so you only need to trigger it in the timer is. Actually if you pick the timer carefully it can trigger the adc without your participation.

2. Dac is often quite fast but again if you pick a timer that can trigger the dac, life is easier.

All of that and more can be found in the device datasheet/ref manual.

Posted on February 05, 2018 at 15:13

Hi

richard.geering

‌,

I am still trying to make this work. I needed to make some changes with the timers: I am using now TIM3 to trigger TIM2 counting, and TIM2 to trigger ADC conversion using TRGO connection. Using the same project as you as an example I can't make the ADC interrupt work (also like you). I have made a revision in the configuration of the timer and ADC registers and they seems to be OK so I am stuck with this. I don't know whether this could be an error in the HAL code.

Thanks for helping,

Omar

Posted on February 05, 2018 at 15:29

Hi Omar, I've reached out to ST Micro again, if I get any updates I'll pass

them on to you.

Good luck!

Richard

On 5 February 2018 at 14:13, Omar Suárez <st-microelectronics@jiveon.com>

Posted on February 05, 2018 at 16:11

The usual method for an application with equidistant sampling is to setup a timer to trigger the ADC, and DMA to pick up the ADC results.

A DMA TC interrupt gives you then a complete set of sample for the current time step.

Perhaps Cube is able to set up such a configuration, but I never tried. I don't speak Cube.

That method works fine for me on F0, F3 and F4 parts, and code derived from the SPL.

Evaluate if the DAC needs synchronization with the ADC.

If not you can just use another timer.

2. Dac is often quite fast ...

Last time I checked it was not.

You can write to the DAC out register quite fast, but the attached hardware is about one order of magnitude slower (check settling times in the DS).

Posted on February 08, 2018 at 15:04

Thanks for the help!

This is how I need to work with the ADC (and how I configure the project):

* TIM2 is configured to work with the TRGO signal when an UPDATE event takes places.

* ADC is configured to work with the ADC_EXTERNALTRIGCONVEDGE_FALLING and ADC_EXTERNALTRIGCONV_T2_TRGO.

* ADC is init using HAL_ADC_Start_IT

* TIM2 is init using HAL_TIM_Base_Start

The code is the same as the example project ADC_TriggerMode (in the HAL Cube library directory prepared for te board STM32F769I_EVAL). I compared configr of the registers of both peripherals with those in the example project and I can't find differences, but the fact is that the example project works (I tested it in another board) but not mine.

Regarding the DAC, I am finally using one external using the SPI communication.

Posted on February 08, 2018 at 16:25

Hi Omar

So do I understand correctly that the example code works on a STM32F769

board, but not yours (a STM32F746ZG).

I think (an) the issue I'm running into is the timer is not triggering the

ADC. I'm not sure of that, but If I run the ADC as 'Regular COnversin

launched by software', then my callback function 'void

HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)' is invoked.

Do you think your ADC process is actually triggered by the update event?

I'm using:

'hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING;

hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T6_TRGO;'

Still nothing else from STM....

Good luck!

Richard

On 8 February 2018 at 14:05, Omar Suárez <st-microelectronics@jiveon.com>

Posted on February 08, 2018 at 16:32

Hi Rich,

Yes, I run the STM32769 example in a STM32F769 Discovery board and it works well. But my project using the STM32746ZG (after make the code comparison between both and being similar) don't.

I made the same as you, changed the ADC configurtion to start the conversion using the HAL function and it worked, the callback was invoked. I made the same with the timer, change the configuration and enabled the interrupt and the callback for update event and it also worked (the invoke of the update event callback). So somehow the timer is not triggering the ADC when update event takes place. I am quite lost here so I can't find where the problem is.

I've been pulling my hair out with the same problem, but I think I've found the answer. Check the STM32F746 errata sheet.

https://www.st.com/content/ccc/resource/technical/document/errata_sheet/4d/39/a6/8c/84/47/47/67/DM00145382.pdf/files/DM00145382.pdf/jcr:content/translations/en.DM00145382.pdf

"System 2.2.1 Missed ADC triggers from TIM1/TIM8, TIM2/TIM5/TIM4/TIM6/TRGO or TGRO2 event Description The ADC external triggers for regular and injected channels by the TIM1, TIM8, TIM2, TIM5, TIM4 and TIM6 TRGO or TRGO2 events are missed at the following conditions: • Prescaler enabled on the PCLK2 clock. • TIMxCLK = 2xADCCLK and the master mode selection (MMS or MMS2 bits in the TIMx_CR2 timer register) as reset, update, or compare pulse configuration. • TIMxCLK = 4xADCCLK. Workarounds • For TIM1 and TIM8 TRGO or TRGO 2 events: select the trigger detection on both the rising and falling edges. The EXTEN[1:0] or JEXTEN[1:0] bits must be set to 0x11 in the ADC_CR2 register. • For TIM2/TIM4/TIM5/TIM6/ TRGO or TGRO2 events: enable the DAC peripheral clock in the RCC_APB1ENR register."