你好!
我只想报告我发现了两个错误。HAL_DMA 函数没有错误。我假设预定义常量或枚举存在一些错误。
介绍
我将 STM32CubeIDE 1.7.0 与 STM32F373VBTx 和固件 V1.11.3 一起使用
我要为两个定时器启用 DMA。 tiM17 和 TIM16。
我还将为 Sigma Delta ADC 启用 DMA。
目标
目标是使用 TIM17 和 TIM16,它们将用作输入捕获并将计数器值保存到数组中。
对于 Sigma Delta ADC,我想将 ADC 值存储到数组中。
方法 - 输入捕获
首先,我使用此代码启用输入捕获。
- volatile static uint16_t input_capture0[2] = {0};
- volatile static uint16_t input_capture1[2] = {0};
- void STM32_PLC_Start_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
- /*
- * Input capture for measuring frequency
- * For TIM17 and TIM16
- * Timer clock: 48 Mhz
- * Prescaler: 4799
- * Counter: 65535 (0xffff)
- * Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
- * Example: For every second, it will count 10000
- * Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
- * Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
- */
- if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, 2) != HAL_OK)
- Error_Handler();
- if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, 2) != HAL_OK)
- Error_Handler();
- }
它们都是 DMA 用于循环模式。
![]() ![]() 上面数组的目的是我可以通过调用函数来计算频率
- static float compute_frequency(uint16_t input_capture[]) {
- /*
- * Typical worst case scenarios:
- * T1: 0xFFFF - T0: 0x0
- * T1: 0x0 - T0: 0xFFFF
- * T1: 0x7FFF - T0: 0x7FFF
- * T1: 0x0 - T0: 0x0
- */
- if(input_capture[1] > input_capture[0]) {
- return (float) 1/((input_capture[1] - input_capture[0])*0.0001f);
- } else if(input_capture[1] < input_capture[0]) {
- return (float) 1/((input_capture[1] + 0xFFFF - input_capture[0])*0.0001f);
- } else if(input_capture[1] == 0x7FFF && input_capture[0] == 0x7FFF){
- return (float) 1/(0xFFFF*0.0001f);
- } else {
- return 0;
- }
- }
- float STM32_PLC_Input_Capture_Get(uint8_t i) {
- if(i == 0)
- return compute_frequency((uint16_t*)input_capture0);
- else
- return compute_frequency((uint16_t*)input_capture1);
- }
TIM17 和 TIM16 具有相同的配置。
方法 - Sigma Delta ADC
为了启用 Sigma Delta ADC,我调用了这个函数。
- volatile static int16_t SDADC1_Single[9];
- volatile static int16_t SDADC2_Single[3];
- volatile static int16_t SDADC3_Differential[5];
- static float SDADC_Single_Calibration_Gain[12] = {0};
- static float SDADC_Single_Calibration_Bias[12] = {0};
- static float SDADC_Differential_Calibration_Gain[5] = {0};
- static float SDADC_Differential_Calibration_Bias[5] = {0};
- TIM_HandleTypeDef *handler_tim12;
- TIM_HandleTypeDef *handler_tim13;
- SDADC_HandleTypeDef *handler_sdadc1;
- SDADC_HandleTypeDef *handler_sdadc2;
- SDADC_HandleTypeDef *handler_sdadc3;
- void STM32_PLC_Start_Analog_Input(TIM_HandleTypeDef* htim12, TIM_HandleTypeDef* htim13, SDADC_HandleTypeDef* hsdadc1, SDADC_HandleTypeDef* hsdadc2, SDADC_HandleTypeDef* hsdadc3) {
- /*
- * For TIM12, TIM13
- * Timer clock: 48 Mhz
- * Prescaler: 0
- * Counter: 48000 (0xbb80)
- * Update frequency: 1000 Hz
- */
- HAL_TIM_OC_Start(htim13, TIM_CHANNEL_1); /* TIM13 Channel 1 is trigger source for SDADC1 */
- HAL_TIM_OC_Start(htim12, TIM_CHANNEL_1); /* TIM12 Channel 1 is trigger source for SDADC2 */
- HAL_TIM_OC_Start(htim12, TIM_CHANNEL_2); /* TIM12 Channel 2 is trigger source for SDADC3 */
- if (HAL_SDADC_CalibrationStart(hsdadc1, SDADC_CALIBRATION_SEQ_1) != HAL_OK)
- Error_Handler();
- if (HAL_SDADC_CalibrationStart(hsdadc2, SDADC_CALIBRATION_SEQ_1) != HAL_OK)
- Error_Handler();
- if (HAL_SDADC_CalibrationStart(hsdadc3, SDADC_CALIBRATION_SEQ_1) != HAL_OK)
- Error_Handler();
- if (HAL_SDADC_PollForCalibEvent(hsdadc1, HAL_MAX_DELAY) != HAL_OK)
- Error_Handler();
- if (HAL_SDADC_PollForCalibEvent(hsdadc2, HAL_MAX_DELAY) != HAL_OK)
- Error_Handler();
- if (HAL_SDADC_PollForCalibEvent(hsdadc3, HAL_MAX_DELAY) != HAL_OK)
- Error_Handler();
- if(HAL_SDADC_InjectedStart_DMA(hsdadc1, (uint32_t*)SDADC1_Single, 9) != HAL_OK)
- Error_Handler();
- if(HAL_SDADC_InjectedStart_DMA(hsdadc2, (uint32_t*)SDADC2_Single, 3) != HAL_OK)
- Error_Handler();
- if(HAL_SDADC_InjectedStart_DMA(hsdadc3, (uint32_t*)SDADC3_Differential, 5) != HAL_OK)
- Error_Handler();
- /* Save */
- handler_tim13 = htim13;
- handler_tim12 = htim12;
- handler_sdadc1 = hsdadc1;
- handler_sdadc2 = hsdadc2;
- handler_sdadc3 = hsdadc3;
- }
这是 SDADC1、SDADC2 和 SDADC3 的 DMA 配置。 ![]() 我还选择了 Injected Conversion 并使用定时器来调用 SDADC 函数。
![]() 以及用于 SDADC 的定时器 TIM12 和 TIM13。
![]() 我还可以在 STM32 处理器运行时更改 Sigma Delta ADC 的增益。
- /* Inline is only for optimization */
- static inline int16_t* array_to_pointer(int16_t array[]){
- return array; /* This return the address */
- }
- void STM32_PLC_Analog_Input_Set_Gain_Offset(uint8_t sdadc, uint8_t configuration_index, uint8_t gain, uint16_t offset) {
- /* Initial */
- SDADC_ConfParamTypeDef ConfParamStruct = {0};
- ConfParamStruct.CommonMode = SDADC_COMMON_MODE_VSSA;
- SDADC_HandleTypeDef *handler;
- uint8_t length_DMA;
- uint32_t *array_DMA;
- /* Stop DMA */
- switch(sdadc){
- case 1:
- /* Stop DMA for SDADC1 */
- if(HAL_SDADC_InjectedStop_DMA(handler_sdadc1) != HAL_OK)
- Error_Handler();
- handler = handler_sdadc1;
- length_DMA = 9;
- array_DMA = (uint32_t*)array_to_pointer((int16_t*)SDADC1_Single);
- ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;
- break;
- case 2:
- /* Stop DMA for SDADC2 */
- if(HAL_TIM_OC_Stop(handler_tim12, TIM_CHANNEL_1))
- Error_Handler();
- if(HAL_SDADC_InjectedStop_DMA(handler_sdadc2) != HAL_OK)
- Error_Handler();
- handler = handler_sdadc2;
- length_DMA = 3;
- array_DMA = (uint32_t*)array_to_pointer((int16_t*)SDADC2_Single);
- ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;
- break;
- case 3:
- /* Stop DMA for SDADC3 */
- if(HAL_SDADC_InjectedStop_DMA(handler_sdadc3) != HAL_OK)
- Error_Handler();
- handler = handler_sdadc3;
- length_DMA = 5;
- array_DMA = (uint32_t*)array_to_pointer((int16_t*)SDADC3_Differential);
- ConfParamStruct.InputMode = SDADC_INPUT_MODE_DIFF;
- break;
- default:
- /* Stop DMA for SDADC1 */
- if(HAL_SDADC_InjectedStop_DMA(handler_sdadc1) != HAL_OK)
- Error_Handler();
- handler = handler_sdadc1;
- length_DMA = 9;
- array_DMA = (uint32_t*)array_to_pointer((int16_t*)SDADC1_Single);
- ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;
- break;
- }
- /* Set gain and offset */
- switch(gain){
- case 0:
- ConfParamStruct.Gain = SDADC_GAIN_1_2;
- break;
- case 1:
- ConfParamStruct.Gain = SDADC_GAIN_1;
- break;
- case 2:
- ConfParamStruct.Gain = SDADC_GAIN_2;
- break;
- case 3:
- ConfParamStruct.Gain = SDADC_GAIN_4;
- break;
- case 4:
- ConfParamStruct.Gain = SDADC_GAIN_8;
- break;
- case 5:
- ConfParamStruct.Gain = SDADC_GAIN_16;
- break;
- case 6:
- ConfParamStruct.Gain = SDADC_GAIN_32;
- break;
- default:
- ConfParamStruct.Gain = SDADC_GAIN_1;
- offset = 0;
- break;
- }
- ConfParamStruct.Offset = offset;
- /* Set calibration */
- if (HAL_SDADC_PrepareChannelConfig(handler, configuration_index, &ConfParamStruct) != HAL_OK)
- Error_Handler();
- /* Start ADC again */
- if (HAL_SDADC_CalibrationStart(handler, SDADC_CALIBRATION_SEQ_1) != HAL_OK)
- Error_Handler();
- if (HAL_SDADC_PollForCalibEvent(handler, HAL_MAX_DELAY) != HAL_OK)
- Error_Handler();
- if(HAL_SDADC_InjectedStart_DMA(handler, array_DMA, length_DMA) != HAL_OK)
- Error_Handler();
- }
结果 - 输入捕获
这些数组在 STM32 处理器运行时会得到不同的值。
- volatile static uint16_t input_capture0[2] = {0};
- volatile static uint16_t input_capture1[2] = {0};
我可以阅读它们,但只有 input_capture0 (TIM17) 获取更新值。只有 input_capture1 (TIM16) 获取值一次,然后就什么都不会发生了。
结果 - Sigma Delta ADC
当我尝试更改 Sigma Delta ADC 的增益时,我调用了这个函数。这只是一个示例:
- if(HAL_SDADC_InjectedStop_DMA(mySDADCHandler) != HAL_OK)
- Error_Handler();
然后在函数内部,调用中止 HAL_DMA。
- HAL_StatusTypeDef HAL_SDADC_InjectedStop_DMA(SDADC_HandleTypeDef *hsdadc)
- {
- HAL_StatusTypeDef status;
- /* Check parameters */
- assert_param(IS_SDADC_ALL_INSTANCE(hsdadc->Instance));
- /* Check SDADC state */
- if((hsdadc->State != HAL_SDADC_STATE_INJ) &&
- (hsdadc->State != HAL_SDADC_STATE_REG_INJ))
- {
- /* Return error status */
- status = HAL_ERROR;
- }
- else
- {
- /* Clear JDMAEN bit in SDADC_CR1 register */
- hsdadc->Instance->CR1 &= ~(SDADC_CR1_JDMAEN);
- /* Stop current DMA transfer */
- if(HAL_DMA_Abort(hsdadc->hdma) != HAL_OK)
- {
- /* Set SDADC in error state */
- hsdadc->State = HAL_SDADC_STATE_ERROR;
- status = HAL_ERROR;
- }
0
|
|
1个回答
|
|
|
|