Просмотр исходного кода

Merge branch 'bugfix/fix_mcpwm_period_calculation_bug' into 'master'

mcpwm_example: fix  period calculation bug in high frequency

See merge request espressif/esp-idf!10152
Michael (XIAO Xufeng) 5 лет назад
Родитель
Сommit
8b1d39bf53

+ 19 - 17
examples/peripherals/mcpwm/mcpwm_basic_config/main/mcpwm_basic_config_example.c

@@ -57,6 +57,9 @@ typedef struct {
     mcpwm_capture_signal_t sel_cap_signal;
 } capture;
 
+uint32_t *current_cap_value = NULL;
+uint32_t *previous_cap_value = NULL;
+
 xQueueHandle cap_queue;
 #if MCPWM_EN_CAPTURE
 static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
@@ -137,28 +140,17 @@ static void gpio_test_signal(void *arg)
  */
 static void disp_captured_signal(void *arg)
 {
-    uint32_t *current_cap_value = (uint32_t *)malloc(CAP_SIG_NUM*sizeof(uint32_t));
-    uint32_t *previous_cap_value = (uint32_t *)malloc(CAP_SIG_NUM*sizeof(uint32_t));
     capture evt;
     while (1) {
         xQueueReceive(cap_queue, &evt, portMAX_DELAY);
         if (evt.sel_cap_signal == MCPWM_SELECT_CAP0) {
-            current_cap_value[0] = evt.capture_signal - previous_cap_value[0];
-            previous_cap_value[0] = evt.capture_signal;
-            current_cap_value[0] = (current_cap_value[0] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
-            printf("CAP0 : %d us\n", current_cap_value[0]);
+            printf("CAP0 : %d us\n", evt.capture_signal);
         }
         if (evt.sel_cap_signal == MCPWM_SELECT_CAP1) {
-            current_cap_value[1] = evt.capture_signal - previous_cap_value[1];
-            previous_cap_value[1] = evt.capture_signal;
-            current_cap_value[1] = (current_cap_value[1] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
-            printf("CAP1 : %d us\n", current_cap_value[1]);
+            printf("CAP1 : %d us\n", evt.capture_signal);
         }
         if (evt.sel_cap_signal == MCPWM_SELECT_CAP2) {
-            current_cap_value[2] = evt.capture_signal -  previous_cap_value[2];
-            previous_cap_value[2] = evt.capture_signal;
-            current_cap_value[2] = (current_cap_value[2] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
-            printf("CAP2 : %d us\n", current_cap_value[2]);
+            printf("CAP2 : %d us\n", evt.capture_signal);
         }
     }
 }
@@ -172,18 +164,26 @@ static void IRAM_ATTR isr_handler(void)
     uint32_t mcpwm_intr_status;
     capture evt;
     mcpwm_intr_status = MCPWM[MCPWM_UNIT_0]->int_st.val; //Read interrupt status
+    //calculate the interval in the ISR, 
+    //so that the interval will be always correct even when cap_queue is not handled in time and overflow.
     if (mcpwm_intr_status & CAP0_INT_EN) { //Check for interrupt on rising edge on CAP0 signal
-        evt.capture_signal = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP0); //get capture signal counter value
+        current_cap_value[0] = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP0); //get capture signal counter value
+        evt.capture_signal = (current_cap_value[0] - previous_cap_value[0]) / (rtc_clk_apb_freq_get() / 1000000);
+        previous_cap_value[0] = current_cap_value[0];
         evt.sel_cap_signal = MCPWM_SELECT_CAP0;
         xQueueSendFromISR(cap_queue, &evt, NULL);
     }
     if (mcpwm_intr_status & CAP1_INT_EN) { //Check for interrupt on rising edge on CAP0 signal
-        evt.capture_signal = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP1); //get capture signal counter value
+        current_cap_value[1] = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP1); //get capture signal counter value
+        evt.capture_signal = (current_cap_value[1] - previous_cap_value[1]) / (rtc_clk_apb_freq_get() / 1000000);
+        previous_cap_value[1] = current_cap_value[1];
         evt.sel_cap_signal = MCPWM_SELECT_CAP1;
         xQueueSendFromISR(cap_queue, &evt, NULL);
     }
     if (mcpwm_intr_status & CAP2_INT_EN) { //Check for interrupt on rising edge on CAP0 signal
-        evt.capture_signal = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP2); //get capture signal counter value
+        current_cap_value[2] = mcpwm_capture_signal_get_value(MCPWM_UNIT_0, MCPWM_SELECT_CAP2); //get capture signal counter value
+        evt.capture_signal = (current_cap_value[2] - previous_cap_value[2]) / (rtc_clk_apb_freq_get() / 1000000);
+        previous_cap_value[2] = current_cap_value[2];
         evt.sel_cap_signal = MCPWM_SELECT_CAP2;
         xQueueSendFromISR(cap_queue, &evt, NULL);
     }
@@ -286,6 +286,8 @@ void app_main(void)
 {
     printf("Testing MCPWM...\n");
     cap_queue = xQueueCreate(1, sizeof(capture)); //comment if you don't want to use capture module
+    current_cap_value = (uint32_t *)malloc(CAP_SIG_NUM*sizeof(uint32_t)); //comment if you don't want to use capture module
+    previous_cap_value = (uint32_t *)malloc(CAP_SIG_NUM*sizeof(uint32_t));  //comment if you don't want to use capture module
     xTaskCreate(disp_captured_signal, "mcpwm_config", 4096, NULL, 5, NULL);  //comment if you don't want to use capture module
     xTaskCreate(gpio_test_signal, "gpio_test_signal", 4096, NULL, 5, NULL); //comment if you don't want to use capture module
     xTaskCreate(mcpwm_example_config, "mcpwm_example_config", 4096, NULL, 5, NULL);