Przeglądaj źródła

Выходы в режиме PWM. В процессе.

TelenkovDmitry 1 rok temu
rodzic
commit
f860612752

+ 8 - 1
fw/modules/io/io.c

@@ -14,6 +14,7 @@ uint16_t input_state_bit;
 
 //uint16_t output_state[DO_NUMBER];     // состояние входа
 uint16_t output_state_bit;
+uint16_t output_mode_bit;
 
 // -------------------------------------------------------------------------- //
 // Текущие параметры
@@ -37,7 +38,7 @@ void io_port_init(void)
     crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
     pwc_battery_powered_domain_access(TRUE);
     
-    io_tim_init();
+    //io_tim_init();
 }
 
 //
@@ -49,6 +50,10 @@ void io_init(void)
     }
 
     output_state_bit = settings.do_bits;
+    output_mode_bit = settings.do_mode_bits;
+    
+    // Таймер для выходов в режиме PWM
+    out_pwm_tim_init();
     
     for (int i = 0; i < DO_NUMBER; i++)
     {
@@ -81,6 +86,7 @@ void io_tim_init(void)
     tmr_counter_enable(TMR12, TRUE);  
 }
 
+
 void TMR8_BRK_TMR12_IRQHandler(void)
 {
     //static int i = 0;
@@ -100,3 +106,4 @@ void TMR8_BRK_TMR12_IRQHandler(void)
 #endif        
     }
 }
+

+ 3 - 0
fw/modules/io/io.h

@@ -64,6 +64,8 @@ typedef struct
     gpio_type *port;
     uint16_t pin;
     uint16_t mode;  // 0 - обычный выход, 1 - режим ШИМ
+    uint16_t pwm_period_cnt;
+    uint16_t pwm_duty_cnt;
     
 } out_t;
 
@@ -79,6 +81,7 @@ extern uint16_t input_state_bit;             // битовое поле
 extern uint32_t input_cnt[DI_NUMBER];       // счетчики входов
 
 extern uint16_t output_state_bit;
+extern uint16_t output_mode_bit;
 
 //uint16_t output_state[DI_NUMBER];    // состояние выхода, 0 - норма, 1 - обрыв, 2 - КЗ
 

+ 102 - 9
fw/modules/io/output.c

@@ -8,14 +8,14 @@
 
 
 out_t outputs[DO_NUMBER] = {
-    {GPIOC, GPIO_PINS_12, 0},   // -
-    {GPIOD, GPIO_PINS_2,  0},   // -
-    {GPIOE, GPIO_PINS_6,  0},   // TMR9_CH2 (remap)
-    {GPIOC, GPIO_PINS_1,  0},   // -
-    {GPIOC, GPIO_PINS_11, 0},   // -
-    {GPIOD, GPIO_PINS_3,  0},   // -
-    {GPIOE, GPIO_PINS_5,  0},   // TMR9_CH1 (remap)
-    {GPIOC, GPIO_PINS_2,  0}    // -
+    {GPIOC, GPIO_PINS_12, 0, 0, 0},   // -
+    {GPIOD, GPIO_PINS_2,  0, 0, 0},   // -
+    {GPIOE, GPIO_PINS_6,  0, 0, 0},   // TMR9_CH2 (remap)
+    {GPIOC, GPIO_PINS_1,  0, 0, 0},   // -
+    {GPIOC, GPIO_PINS_11, 0, 0, 0},   // -
+    {GPIOD, GPIO_PINS_3,  0, 0, 0},   // -
+    {GPIOE, GPIO_PINS_5,  0, 0, 0},   // TMR9_CH1 (remap)
+    {GPIOC, GPIO_PINS_2,  0, 0, 0}    // -
 };
 
 
@@ -101,9 +101,32 @@ void do_update(out_t *out, uint8_t index)
 }
 
 //
+void do_set_mode(void)
+{
+    if (output_mode_bit == settings.do_mode_bits)
+        return;
+  
+    // Состояние выхода/выходов изменилось
+    for (int i = 0; i < DO_NUMBER; i++)
+    {
+        if ((settings.do_mode_bits & (1 << i)) != (output_mode_bit & (1 << i)))
+        {
+            settings.do_mode_bits |= (1 << i);
+            do_update(&outputs[i], i);
+        }
+    }
+  
+    settings.do_mode_bits = output_mode_bit;
+}
+
+//#define PWM_PERIOD_TEST     20
+//#define PWM_DUTY_TEST       10
 void do_set_pwm(uint16_t pwm, uint8_t index)
 {
-    // pass
+    //outputs[index].pwm_duty_cnt = (uint16_t)(outputs[index].pwm_period_cnt*pwm/100.0);
+    outputs[index].pwm_duty_cnt = (uint16_t)(PWM_PERIOD_TEST*pwm/100.0);
+    outputs[index].mode = 1;
+    
 }
 
 //
@@ -154,6 +177,64 @@ void out_as_pwm(void)
     tmr_counter_enable(TMR9, TRUE);
 }
 
+// Таймер для выходов в режиме PWM. Частота 10Гц.
+void out_pwm_tim_init(void)
+{
+    uint16_t prescaler_value = 0;
+    uint16_t timer_period = 1000 - 1;
+    gpio_init_type gpio_init_struct;
+    
+    gpio_default_para_init(&gpio_init_struct);
+        
+    gpio_init_struct.gpio_pins = GPIO_PINS_15;
+    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+    gpio_init(GPIOB, &gpio_init_struct);
+
+    crm_periph_clock_enable(CRM_TMR9_PERIPH_CLOCK, TRUE);
+    
+    prescaler_value = (uint16_t)(system_core_clock / 10000) - 1;
+    tmr_base_init(TMR9, timer_period, prescaler_value);
+    
+    tmr_cnt_dir_set(TMR9, TMR_COUNT_UP);
+    tmr_clock_source_div_set(TMR9, TMR_CLOCK_DIV1);
+    
+    nvic_irq_enable(TMR1_BRK_TMR9_IRQn, 5, 0);
+
+    tmr_interrupt_enable(TMR9, TMR_OVF_INT, TRUE);
+    
+    tmr_counter_enable(TMR9, TRUE);
+}
+
+
+
+inline void pwm_proc(void)
+{
+    for (int i = 0; i < DO_NUMBER; i++)
+    {
+        if (outputs[i].mode)    // режим PWM
+        {
+            outputs[i].pwm_period_cnt++;
+            outputs[i].pwm_duty_cnt++;
+            
+            if (outputs[i].pwm_period_cnt == PWM_PERIOD_TEST) 
+            {
+                outputs[i].pwm_period_cnt = 0;
+                gpio_bits_set(GPIOB, GPIO_PINS_15);
+            }
+            else if (outputs[i].pwm_duty_cnt == PWM_DUTY_TEST) 
+            {
+                outputs[i].pwm_duty_cnt = 0;
+                gpio_bits_reset(GPIOB, GPIO_PINS_15);
+            }
+        }
+    }
+  
+  
+}
+
 //
 void load_sens_init(simple_gpio_t *sens)
 {
@@ -190,7 +271,18 @@ void out_test(void)
     }  
 }
 
+//
+void TMR1_BRK_TMR9_IRQHandler(void)
+{
+    if(tmr_flag_get(TMR9, TMR_OVF_FLAG) != RESET)
+    {
+        tmr_flag_clear(TMR9, TMR_OVF_FLAG);
+        //GPIOB->odt ^= GPIO_PINS_15;
+        pwm_proc();
+    }
+}
 
+#if 0
 void TMR1_BRK_TMR9_IRQHandler(void)
 {
     static uint32_t cnt1 = 0;
@@ -209,3 +301,4 @@ void TMR1_BRK_TMR9_IRQHandler(void)
         printf("Cnt2 %u\r\n", cnt2);
     }
 }
+#endif

+ 13 - 0
fw/modules/io/output.h

@@ -5,6 +5,10 @@
 #include "io.h"
 
 
+#define PWM_PERIOD_TEST     20
+#define PWM_DUTY_TEST       10
+
+
 extern out_t outputs[];
 
 extern simple_gpio_t load_sens[];
@@ -19,15 +23,24 @@ void do_set(void);
 // Установка значения на выходе 
 void do_update(out_t *out, uint8_t index);
 
+//
+void do_set_mode(void);
+
 //
 void do_set_pwm(uint16_t pwm, uint8_t index);
 
 //
 void do_set_out(out_t *out, uint8_t val);
 
+// 
+void out_pwm_tim_init(void);
+
 //
 void out_as_pwm(void);
 
+//
+void pwm_proc(void);
+
 //
 void load_sens_init(simple_gpio_t *sens);
 

+ 88 - 0
fw/modules/misc/misc.c

@@ -130,7 +130,95 @@ void mb_test_gpio_init(void)
     
 }
 
+//
+void pwm_test(void)
+{
+    tmr_output_config_type tmr_oc_init_structure;
+    
+    pwm_gpio_config();
+    
+    uint16_t prescaler_value = 0;
+    uint16_t pulse = 0;
+    uint16_t timer_period = 10000 - 1;
+
+    // Режим PWM
+    crm_periph_clock_enable(CRM_TMR9_PERIPH_CLOCK, TRUE);
+    
+    prescaler_value = (uint16_t)(system_core_clock / 10000) - 1;
+    tmr_base_init(TMR9, timer_period, prescaler_value);
+    pulse = (uint16_t)(((uint32_t) 70 * (timer_period - 1)) / 100);   // 70%
+    
+    tmr_cnt_dir_set(TMR9, TMR_COUNT_UP);
+    tmr_clock_source_div_set(TMR9, TMR_CLOCK_DIV1);
+    
+    tmr_output_default_para_init(&tmr_oc_init_structure);
+    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
+    tmr_oc_init_structure.oc_idle_state = FALSE;
+    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
+    tmr_oc_init_structure.oc_output_state = TRUE;
+    tmr_output_channel_config(TMR9, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
+    tmr_channel_value_set(TMR9, TMR_SELECT_CHANNEL_2, pulse);
+    tmr_output_channel_buffer_enable(TMR9, TMR_SELECT_CHANNEL_2, TRUE);
+    
+    tmr_period_buffer_enable(TMR12, TRUE);
+    
+    nvic_irq_enable(TMR1_BRK_TMR9_IRQn, 5, 0);
+
+    tmr_interrupt_enable(TMR9, TMR_C2_INT, TRUE);
+    
+    tmr_counter_enable(TMR9, TRUE);
+}
+
+//
+void pwm_gpio_config(void)
+{
+    gpio_init_type gpio_init_struct;
+
+    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
+    
+    gpio_default_para_init(&gpio_init_struct);
+    
+#if 0    
+    // Пин в режиме PWM таймера
+    gpio_init_struct.gpio_pins = GPIO_PINS_15;
+    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+    gpio_init(GPIOB, &gpio_init_struct);
+#endif    
+    
+    gpio_init_struct.gpio_pins = GPIO_PINS_15;
+    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+    gpio_init(GPIOB, &gpio_init_struct);
+    
+    // Простой выход
+    gpio_init_struct.gpio_pins = GPIO_PINS_13;
+    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
+    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+    gpio_init(GPIOB, &gpio_init_struct);
+}
+
+
+#if 0
+// Для отладки PWM режимов TMR_12
+void TMR8_BRK_TMR12_IRQHandler(void)
+{
+    if(tmr_flag_get(TMR12, TMR_C2_FLAG) != RESET)
+    {
+        tmr_flag_clear(TMR12, TMR_C2_FLAG);
 
+        GPIOB->odt ^= GPIO_PINS_13;
+    }
+}
+#endif
+
+    
 #if 0
 void USART3_IRQHandler(void)
 {

+ 5 - 0
fw/modules/misc/misc.h

@@ -21,6 +21,11 @@ void mb_tim_test(void);
 //
 void mb_test_gpio_init(void);
 
+//
+void pwm_test(void);
+
+//
+void pwm_gpio_config(void);
 
 #endif  // __MISC_H
 

+ 19 - 1
fw/modules/modbus/modbus_params.c

@@ -5,6 +5,7 @@
 #include "uptime.h"
 #include "rtc.h"
 #include "input.h"
+#include "output.h"
 #include <string.h>
 
 
@@ -81,7 +82,7 @@ void mb_init_params(void)
         index++;
     }
     
-    // Нормальное состояние входов
+    // Текущее состояние выходов
     mb_param[index].reg = 0x0200;
 	mb_param[index].size = 1;
 	mb_param[index].param = (uint8_t*)&output_state_bit;  
@@ -90,6 +91,16 @@ void mb_init_params(void)
     mb_param[index].check_handler = mb_check_dummy;
     
     index++;
+    
+    // Режим работы выходов
+    mb_param[index].reg = 0x0202;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&output_mode_bit;  
+	mb_param[index].set = mb_set_do_mode;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
 }
 
 
@@ -210,6 +221,13 @@ mb_delay_action_t mb_set_do(void)
     return MB_NO_ACTION;
 }
 
+//
+mb_delay_action_t mb_set_do_mode(void)
+{
+    do_set_mode();
+    return MB_NO_ACTION;
+}
+
 //
 mb_delay_action_t mb_set_time(void)
 {

+ 3 - 1
fw/modules/modbus/modbus_params.h

@@ -9,7 +9,7 @@
 #include <stdbool.h>
 
 
-#define MB_PARAM_MAX			20
+#define MB_PARAM_MAX			21
 
 
 //
@@ -62,6 +62,8 @@ mb_delay_action_t mb_set_din_mode(void);
 //
 mb_delay_action_t mb_set_do(void);
 
+//
+mb_delay_action_t mb_set_do_mode(void);
 
 // -------------------------------------------------------------------------- //
 //                      Проверка параметров                                   //

+ 4 - 1
fw/user/main.c

@@ -126,6 +126,9 @@ void init_task(void *argument)
     
     update_reset_boot_try();    
     
+// -------------------------------------------------------------------------- //    
+// Тесты
+    //pwm_test(); // тесы PWM
     
 // -------------------------------------------------------------------------- //    
 // RNDIS
@@ -178,7 +181,7 @@ void soft_wdt(void *params)
     for (;;)
     {
         extern_wdt_togle(); // extern WDT
-        vTaskDelay(500);
+        vTaskDelay(100);
     }
 }
 

BIN
output/fw.bin


Plik diff jest za duży
+ 412 - 429
project/ewarm/iap/iap.dep


Plik diff jest za duży
+ 615 - 645
project/ewarm/module_universal_io.dep


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików