This post was last edited by elike on 2019-9-22 21:39
NUCLEO-G431RB Review
The DAC in this chip is a 12 -bit DAC with a total of 4 DAC interfaces . There are two channels of DAC that can be output from GPIO , as shown in the figure below.
To control the normal operation of this DAC , you first need to understand its port status. The port description is given in the document.
It can be seen that the input data of the two DACs are both 16 bits , and the system register is 32 bits, so when used as a DAC , there are corresponding interception bits. For a single-channel output DAC , the data interception format is as follows:
It should be noted that when the DAC input clock dac_hclk>80MHz , HFSEL must be set accordingly to delay the output of the DAC_DHRx register from being transferred to DAC_DORx in order to leave enough setup time for the DAC .
The output voltage formula of the entire DAC is as follows
The basic programming configuration is as follows
sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC;
sConfig.DAC_DMADoubleDataMode = DISABLE;
sConfig.DAC_SignedFormat = DISABLE;
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO;
sConfig.DAC_Trigger2 = DAC_TRIGGER_T6_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
As can be seen from the following program, two triggers DAC_TRIGGER_T2_TRGO and DAC_TRIGGER_T6_TRGO are used to control each frame of data and the entire cycle data respectively. These two triggers are equivalent to a frequency divider. The basic configuration of the two triggers is as follows:
htim2.Instance = TIM2;
htim2.Init.Prescaler = 149;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
Indicates that the division factor of this trigger is ( 150*500 )
htim6.Instance = TIM6;
htim6.Init.Prescaler = 0;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 2499;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
The division factor of this trigger is ( 1*2500 )
The clock configuration of the entire system is as follows
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
RCC_OscInitStruct.PLL.PLLN = 75;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
So the clock frequency added to the trigger by the system is
16MHz/4*75/2/1/1/1=150MHz
The division numbers of the two triggers are ( 150*1000 , 2500 ) and the corresponding output frequencies are ( 1kHz , 60kHz ), so the period of the output signal is 1kHz .
Connect an oscilloscope to the output end and observe the waveform on the oscilloscope.
Press the USER button to display the sine wave.
The sine wave is exported to MATLAB for FFT analysis, as shown below.
As can be seen from the figure, there is no problem with the waveform output, but the influence of noise and distortion caused by high-order harmonics are still relatively serious, and when the frequency is ~60kHz , the internal high-frequency sampling clock leakage reaches -39dB relative to the input .
To confirm the result again, I directly took out the input digital signal
uint16_t sinewave[60] = {
0x07ff,0x08cb,0x0994,0x0a5a,0x0b18,0x0bce,0x0c79,0x0d18,0x0da8,0x0e29,0x0e98,0x0ef4,0x0f3e,0x0f72,0x0f92,0x0f9d,
0x0f92,0x0f72,0x0f3e,0x0ef4,0x0e98,0x0e29,0x0da8,0x0d18,0x0c79,0x0bce,0x0b18,0x0a5a,0x0994,0x08cb,0x07ff,0x0733,
0x066a,0x05a4,0x04e6,0x0430,0x0385,0x02e6,0x0256,0x01d5,0x0166,0x010a,0x00c0,0x008c,0x006c,0x0061,0x006c,0x008c,
0x00c0,0x010a,0x0166,0x01d5,0x0256,0x02e6,0x0385,0x0430,0x04e6,0x05a4,0x066a,0x0733};
Repeat 17 cycles in MATLAB , then perform FFT on the ideal signal to see its spectrum distribution.
It is found that the digital signal has a high degree of similarity to the simulation of the sine wave, there are no even harmonics, and the remaining ones are mainly odd harmonics.
When I reduce the output sine wave frequency to 500Hz , the waveform output result is shown in the figure below.
Also import into MATLAB for analysis
The harmonics will be better, but the noise injected by the clock still has a greater impact and there is no change.
When the output frequency increases to 5kHz , the result on the oscilloscope is as follows:
The waveform can also be changed by changing the value of the input signal. If the input value is changed to the following,
uint16_t sinewave[60] = {
0x07ff,0x08cb,0x0994,0x0a5a,0x0b18,0x0bce,0x0c79,0x0d18,0x0da8,0x0e29,0x0e98,0x0ef4,0x0f3e,0x0f72,0x0f92,0x0f9d,
0x0f92,0x0f72,0x0f3e,0x0ef4,0x0e98,0x0e29,0x0da8,0x0d18,0x0c79,0x0bce,0x0b18,0x0a5a,0x0994,0x08cb,0x07ff,0x07ff,
0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,
0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff};
The output is shown in the figure
This content is originally created by EEWORLD forum user elike . If you want to reprint or use it for commercial purposes, you must obtain the author's consent and indicate the source