cancel
Showing results for 
Search instead for 
Did you mean: 

Hello! I purchased the STM32G431RBT-Nucleo board. When trying to write code to control the DAC, I ran into a problem - regardless of the code change, the result is 0v, there is a straight line on the oscilloscope. The code itself runs on STM32F407. Do you

DTorn.1
Associate II

One of the variint main(void)

{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */

 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */

 MX_GPIO_Init();

 MX_DMA_Init();

 MX_DAC1_Init();

 MX_TIM6_Init();

 /* USER CODE BEGIN 2 */

 HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);

 HAL_DAC_Start(&hdac1, DAC_CHANNEL_2);

 uint16_t sinewave[60];

 uint16_t i;

 for(i=0;i<60;i++){

  sinewave[i]=sin(i/60.0*2*3.1415926)*500+1000;

 }

 HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1,(uint32_t *)sinewave,60,DAC_ALIGN_12B_R);

 HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2,(uint32_t *)sinewave,60,DAC_ALIGN_12B_R);

 if (HAL_TIM_Base_Start(&htim6) != HAL_OK){

  Error_Handler();

 }

 /* USER CODE END 2 */

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 }

 /* USER CODE END 3 */

}

ants of the code in HAL:

17 REPLIES 17

Try a simple implementation first, using DAC without trigger (DAC_CR.TENx=0), writing various values into DAC_DHRx, maybe eveb manually in debugger.

Check the relevant GPIO registers content.

JW

I tried writing directly to the DAC1_DHR12R1 register, the result is the same. I tried using LL, HEL and CMSIS, the result is the same - a smooth line on the oscilloscope.

Set given pins to GPIO Output and toggle them - do you see that on oscilloscope?

JW

Yes! The oscilloscope is working. Also, the microcontroller itself reads the ADC signal and works with the LPUART exchange protocol, but unfortunately is not able to produce either a PWM timer signal or a DAC signal. вт, 14 июн. 2022 г. в 15:53, ST Community :

I did not ask whether the oscilloscope is working, but whether the pins, which you are using for DAC, when set as GPIO outputs and toggled, do produce the expected waveform.

If this is successful, then set up GPIO as needed for DAC, set up the DAC control register for operation without trigger (and without DMA and timer and whatnot) and try writing into the DMA holding register. If that fails, read out and check/post the DAC and GPIO registers content.

JW

DTorn.1
Associate II

Here is a variant of the code:

// 32-sample sine wave.

#define _AMP(x) ( x / 8 )

const size_t SINE_SAMPLES = 32;

const uint16_t SINE_WAVE[] = {

 _AMP(2048), _AMP(2447), _AMP(2831), _AMP(3185),

 _AMP(3495), _AMP(3750), _AMP(3939), _AMP(4056),

 _AMP(4095), _AMP(4056), _AMP(3939), _AMP(3750),

 _AMP(3495), _AMP(3185), _AMP(2831), _AMP(2447),

 _AMP(2048), _AMP(1649), _AMP(1265), _AMP(911),

 _AMP(601), _AMP(346), _AMP(157), _AMP(40),

 _AMP(0),  _AMP(40),  _AMP(157), _AMP(346),

 _AMP(601), _AMP(911), _AMP(1265), _AMP(1649)

};

// Global variable to hold the core clock speed in Hertz.

uint32_t SystemCoreClock1 = 16000000;

// Simple imprecise delay method.

void __attribute__( ( optimize( "O0" ) ) )

delay_cycles( uint32_t cyc ) {

 for ( uint32_t d_i = 0; d_i < cyc; ++d_i ) { asm( "NOP" ); }

}

int main(void){

#if (__FPU_USED == 1)

SCB->CPACR |= ((3UL << 10*2) |       /* set CP10 Full Access        */

        (3UL << 11*2));       /* set CP11 Full Access        */

#endif

// Enable peripherals: GPIOA, DMA, DAC, TIM6.

 RCC->AHB2ENR  |= RCC_AHB2ENR_GPIOAEN;

 RCC->AHB1ENR  |= (RCC_AHB1ENR_DMA1EN|

     RCC_APB1ENR1_TIM6EN );

 RCC->AHB2ENR |= RCC_AHB2ENR_DAC1EN ;

 // Pin A4 output type: Analog.

 GPIOA->MODER  &= ~( 0x3 << ( 4 * 2 ) );

 GPIOA->MODER  |= ( 0x3 << ( 4 * 2 ) );

 uint32_t dma_ccr_clr = ~( DMA_CCR_MEM2MEM |

              DMA_CCR_PL |

              DMA_CCR_MSIZE |

              DMA_CCR_PSIZE |

              DMA_CCR_PINC |

              DMA_CCR_EN );

 uint32_t dma_ccr_set = ( ( 0x2 << DMA_CCR_PL_Pos ) |

              ( 0x1 << DMA_CCR_MSIZE_Pos ) |

              ( 0x1 << DMA_CCR_PSIZE_Pos ) |

              DMA_CCR_MINC |

              DMA_CCR_CIRC |

              DMA_CCR_DIR );

 DMA1_Channel1->CCR &= dma_ccr_clr;

 DMA1_Channel1->CCR |= dma_ccr_set;

 // Select DAC Ch1 as DMA Ch1 request source in DMAMUX.

 // Note: DMAMUX channel numbers are slightly confusing in

 // the documentation. They aren't reliably 0- or 1-indexed.

 DMAMUX1_Channel0->CCR &= ~( DMAMUX_CxCR_DMAREQ_ID );

 DMAMUX1_Channel0->CCR |= ( 0x8 << DMAMUX_CxCR_DMAREQ_ID_Pos );

 // Set DMA source and destination addresses.

 // Source: Address of the sine wave buffer in memory.

 DMA1_Channel1->CMAR = ( uint32_t )&SINE_WAVE;

 // Dest.: DAC1 Ch1 '12-bit right-aligned data' register.

 DMA1_Channel1->CPAR = ( uint32_t )&( DAC1->DHR12R1 );

 // Set DMA data transfer length (# of sine wave samples).

 DMA1_Channel1->CNDTR = ( uint16_t )SINE_SAMPLES;

 // Enable DMA1 Channels 1/2.

 DMA1_Channel1->CCR |= ( DMA_CCR_EN );

 // TIM6 configuration.

 // Set prescaler and autoreload for a 440Hz sine wave.

 TIM6->PSC = ( 0x0000 );

 TIM6->ARR = ( SystemCoreClock1 / ( 440 * SINE_SAMPLES ) );

 // Enable trigger output on timer update events.

 TIM6->CR2 &= ~( TIM_CR2_MMS );

 TIM6->CR2 |= ( 0x2 << TIM_CR2_MMS_Pos );

 // Start the timer.

 TIM6->CR1 |= ( TIM_CR1_CEN );

 // DAC configuration.

 // Set trigger source to TIM6 TRGO.

 DAC1->CR &= ~( DAC_CR_TSEL1 );

 DAC1->CR |= ( 0x5 << DAC_CR_TSEL1_Pos );

 // Set outputs to buffered GPIO 'normal mode'.

 DAC1->MCR &= ~( DAC_MCR_MODE1 );

 // Enable DAC DMA requests.

 DAC1->CR |= ( DAC_CR_DMAEN1 );

 // Enable DAC Channels.

 DAC1->CR |= ( DAC_CR_EN1 );

 // Delay briefly to allow sampling to stabilize (?)

 // delay_cycles( 1000 );

 // Enable DAC channel trigger.

 DAC1->CR |= ( DAC_CR_TEN1 );

for(;;){}

}

DTorn.1
Associate II

I have tried hundreds of ways to identify the problem of missing a signal

Pity you still don't answer Jan's question.

PA4 is connected to Arduino Rail A2 pin

If you drive pin high/low as a GPIO does that work?

According to the schematic it's directly connected to the IC, so no solder bridges or anything in the way.

0693W00000Nse6YQAR.jpg

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
DTorn.1
Associate II

Excuse me! There are no jumpers. Connected to pin A4(A2 - CN8). SB37 and SB34 were not installed at the factory