2023-05-16 11:59 AM
I have a project where I'm using a Nucloe G474RE to produce a sine wave, all is working great; I have an array of 2500 values which produce a SINE wave starting at 0 degrees; I would like to add 2 further Sine waves starting 120 and 240 degrees later.
To do this, I could create 2 additional arrays with the values shifted to reflect the 120-degree and 240 degrees shift, but I was wondering whether I could use one array and produce the remaining 2 arrays by preloading the index the timer produces for phase 2 and 3 , indexing, reading and sending the value to the 2nd and 3rd DAC output.
Is this achievable
Thanks for any guidance
Nick
I think I know how this could work, but I have to set the registers manually rather than using the HAL,
The HAL seems to hide the details on how to set the source address,
DMA1_Channel1->CPAR = (unint32_t(&dataArray[index_to_start_from); //DMA in circular mode.
Can I override this in the Cubemx generated project, or do I need to code without using CubeMX
Thanks
Nick
Solved! Go to Solution.
2023-05-19 12:41 PM - edited 2023-11-20 05:19 AM
Thanks Michal,
I have managed to sort it using DMA only , no software in main() at all.
Its really simple .
I have a 1 x array with 5000 values as the look up table covering 2 cycles (Thanks KnarfB)
When you Start each DAC you add the number you want to index from in the HAL_DAC_Start_DMA call
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)Wave_LUT_BIG
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)(Wave_LUT_BIG+1666
HAL_DAC_Start_DMA(&hdac2, DAC_CHANNEL_1, (uint32_t*)(Wave_LUT_BIG+1070
the only inconsistency Is that DAC 1 channels 1 and 2 are synchronised but DAC 2 channel 1 is delayed compared the DAC 1 channels , hence why the index is lower on the 3rd DAC output.
Regards
Nick
Code snippet below.
MX_DMA_Init();
MX_DAC1_Init();
MX_TIM2_Init();
MX_DAC2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)Wave_LUT_BIG, 2500, DAC_ALIGN_12B_R); //Phase A Start At 0 degrees
HAL_TIM_Base_Start(&htim2);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)(Wave_LUT_BIG+1666), 2500, DAC_ALIGN_12B_R); //Phase B Start At 120 degrees +1666
HAL_TIM_Base_Start(&htim2);
HAL_DAC_Start_DMA(&hdac2, DAC_CHANNEL_1, (uint32_t*)(Wave_LUT_BIG+1070), 2500, DAC_ALIGN_12B_R); //Phase C Start At 240 degrees
HAL_TIM_Base_Start(&htim2);
2023-05-17 01:04 AM
Multiple DMAs on the same array will work, unless at very high frequencies when bus access may become a bottleneck. Keep in mind that you need a longer array (say 2 periods) if you start not at the beginning. You may add your code in USER code sections in a generated HAL project.
Why do you need overriding the HAL code? Didn't code like
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)buffer, DAC_BUFFER_SAMPLES, DAC_ALIGN_12B_R);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)(buffer+256), DAC_BUFFER_SAMPLES, DAC_ALIGN_12B_R);
work?
hth
KnarfB
2023-05-17 02:12 AM
Thanks KnarfB,
The array is only holding values for one cycle and the max frequency is 60 Hz , thanks for the code snippet , it looks really simple to index into the array.
if it's in circular mode, won't it loop around, or maybe it will try and continue to increment to the end of the 2500 array size and then loop around to 0?
Regards
Nick
2023-05-17 11:30 PM
You, of course, were correct; I needed 2 cycles of data in the array.
I had to add an additional Dac channel for the 3rd phase output. I don't know the latency between the 2 DACs, but they are not in synchronisation unless I'm missing something,
phase 1 and 2 on DAC1 channels 1 and 2 are synchronised,
but phase 3 on DAC2 channel 1 isn't synchronised with DAC1. it's not a problem because I need to offset each channel anyway.
Thanks for your help
2023-05-19 10:37 AM
If i understand correctly, you need to generate three same (sine) waveforms. Using three memory buffers is an obvious waste of memory. you simply want to have only one buffer and just to start DMA in circular mode, but with shifted index. DMA generally does not allow this, but you can do simple trick.
2023-05-19 12:41 PM - edited 2023-11-20 05:19 AM
Thanks Michal,
I have managed to sort it using DMA only , no software in main() at all.
Its really simple .
I have a 1 x array with 5000 values as the look up table covering 2 cycles (Thanks KnarfB)
When you Start each DAC you add the number you want to index from in the HAL_DAC_Start_DMA call
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)Wave_LUT_BIG
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)(Wave_LUT_BIG+1666
HAL_DAC_Start_DMA(&hdac2, DAC_CHANNEL_1, (uint32_t*)(Wave_LUT_BIG+1070
the only inconsistency Is that DAC 1 channels 1 and 2 are synchronised but DAC 2 channel 1 is delayed compared the DAC 1 channels , hence why the index is lower on the 3rd DAC output.
Regards
Nick
Code snippet below.
MX_DMA_Init();
MX_DAC1_Init();
MX_TIM2_Init();
MX_DAC2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)Wave_LUT_BIG, 2500, DAC_ALIGN_12B_R); //Phase A Start At 0 degrees
HAL_TIM_Base_Start(&htim2);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)(Wave_LUT_BIG+1666), 2500, DAC_ALIGN_12B_R); //Phase B Start At 120 degrees +1666
HAL_TIM_Base_Start(&htim2);
HAL_DAC_Start_DMA(&hdac2, DAC_CHANNEL_1, (uint32_t*)(Wave_LUT_BIG+1070), 2500, DAC_ALIGN_12B_R); //Phase C Start At 240 degrees
HAL_TIM_Base_Start(&htim2);
2023-05-19 12:55 PM
OK, that is nice. All DAC can be perfectly synchronised if are configured in trigger mode. One timer triggers DAC conversion on all three channels simultaneously. (Start timer only once, after "starting" all three DMA channels)
2023-06-24 08:40 AM
Hi All,
I have a further query about the DAC output for this that is puzzling me, I have 3 sine waves all DAC conversions triggered correctly but I seem to have lost the bottom portion of the sine 1 and 2 ( these are on the same DAC) , it was working fine until I connected the output of this on pin PA5 and PA6 to the input of an OPAMPS, I think I have somehow damaged the buffer that I'm using inside the STM32 and it no longer outputs the full swing in voltage.
Here's a screen grab of the scope for the 3 phases. Has anyone seen this before? and is it possible to calibrate the output to correct it?
Thanks
Nick
2024-08-02 02:51 AM
Hi NOMal.1
I have been trying to produce sine wave of two different frequencies. But Only on DAC channel is giving out sine wave. When i searched in the internet it says that we cant use two DMAs at the same time.
Here is the code I used
MX_GPIO_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
MX_DAC1_Init();
MX_USB_OTG_HS_USB_Init();
MX_TIM1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
get_sineval();
HAL_TIM_Base_Start(&htim1);
HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1, sine_val, 100, DAC_ALIGN_12B_R);
HAL_TIM_Base_Start(&htim2);
HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_2, sine_val, 100, DAC_ALIGN_12B_R);
I am getting output only in one channel. Can you Please help me with this?