AT32UC30512C: ADC-Interrupt mit PWM-Signal synchronisieren

Gast #3429709
Lesenswert?

Hallo,

ich habe ein AT32UC3C-EK und möchte damit einen Sensor auslesen. Es 
werden zwei Clk-Signale benötigt, die ich per PWM erzeuge. Zeitlich 
parallel und synchron zu der PWM muss ich das Ausgangssignal des Sensors 
samplen. Nach jedem 4. Clk.-Zyklus muss ich einen Interrupt samt 
AD-Wandlung ausführen.

Ich habe dabei folgendes Problem:

1) 2x PWM erzeugen
   --> funktioniert, Signale liegen an J33 an, die PWM sind 
synchronisiert!

2) In gleichen Zeitabständen einen Interrupt auslösen und einen Messwert 
samplen
   --> Interrupt-Aufruf funktioniert, ADC wird später in den Interrupt 
implementiert

3) Die PWM-Signale mit den ADC-Interrupt-Aufrufen synchronisieren.
--> da, hab ich keine Idee wie ich das machen soll. Eigentlich müsste es 
doch möglich sein, das PWM-Signal zu nutzen um einen Interrupt 
auszulösen. Aber wie?

Ich nutze das ASF-3.7.3 und mein Hauptteil sieht bislang wie folgt aus:
1
 pwm_opt_t pwm_opt;                // PWM option config.
2
        avr32_pwm_channel_t pwm_channel = {{0}, // cmr
3
                                           {0}, // cdty
4
                                           {0}, // cdtyupd
5
                                           {0}, // cprd
6
                                           {0}, // cprdupd
7
                                           {0}, // ccnt
8
                                           {0}, // dt
9
                                           {0}};// dtupd  ;  One channel config.
10

11
        avr32_pwm_channel_t pwm_channel1 = {{0}, // cmr
12
                                           {0}, // cdty
13
                                           {0}, // cdtyupd
14
                                           {0}, // cprd
15
                                           {0}, // cprdupd
16
                                           {0}, // ccnt
17
                                           {0}, // dt
18
                                           {0}};// dtupd  ;  One channel config.
19

20
        unsigned int channel_id,channel_id1;
21

22
        // Start Main Clock On external 16MHz Oscillator
23
        // Start PLL for PWM
24
        local_start_highfreq_clock();
25
        // Start Enable Generic Clock with PLL as source clock
26

27
        pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);
28

29
        pwm_start_gc();
30

31
        channel_id = EXAMPLE_PWM_CHANNEL_ID;
32
        gpio_enable_module_pin(EXAMPLE_PWM_L_PIN, EXAMPLE_PWM_L_FUNCTION);
33
        gpio_enable_module_pin(EXAMPLE_PWM_H_PIN, EXAMPLE_PWM_H_FUNCTION);
34

35
        channel_id1 = EXAMPLE1_PWM_CHANNEL_ID;
36
          gpio_enable_module_pin(EXAMPLE1_PWM_L_PIN, EXAMPLE1_PWM_L_FUNCTION);
37
          gpio_enable_module_pin(EXAMPLE1_PWM_H_PIN, EXAMPLE1_PWM_H_FUNCTION);
38

39

40
        // PWM controller configuration.
41
        pwm_opt.diva = AVR32_PWM_DIVA_CLK_OFF;
42
        pwm_opt.divb = AVR32_PWM_DIVB_CLK_OFF;
43
        pwm_opt.prea = AVR32_PWM_PREA_CCK;
44
        pwm_opt.preb = AVR32_PWM_PREB_CCK;
45

46
        pwm_opt.fault_detection_activated = false;
47
        pwm_opt.sync_channel_activated    = true;
48
        pwm_opt.sync_update_channel_mode  = PWM_SYNC_UPDATE_MANUAL_WRITE_MANUAL_UPDATE;
49
        pwm_opt.sync_channel_select[0]    = true;
50
        pwm_opt.sync_channel_select[1]    = true;
51
        pwm_opt.sync_channel_select[2]    = false;
52
        pwm_opt.sync_channel_select[3]    = false;
53
        pwm_opt.cksel                     = PWM_CKSEL_GCLK;
54
        pwm_init(&pwm_opt);
55

56
        // Update the period
57
        pwm_update_period_value(100);
58

59
        // Channel configuration
60
        pwm_channel.CMR.dte   = 1;        // Enable Deadtime for complementary Mode
61
        pwm_channel.CMR.dthi  = 1;        // Deadtime Inverted on PWMH
62
        pwm_channel.CMR.dtli  = 0;        // Deadtime Not Inverted on PWML
63
        pwm_channel.CMR.ces   = 0;        // 0/1 Channel Event at the End of PWM Period
64
        pwm_channel.CMR.calg  = PWM_MODE_LEFT_ALIGNED;       // Channel mode.
65
        pwm_channel.CMR.cpol  = PWM_POLARITY_LOW;            // Channel polarity.
66
        pwm_channel.CMR.cpre  = AVR32_PWM_CPRE_CCK;           // Channel prescaler.
67
        pwm_channel.cdty      = 35;       // Channel duty cycle, should be < CPRD.
68
        pwm_channel.cprd      = 70;       // Channel period.
69

70
        pwm_channel1.CMR.dte   = 1;        // Enable Deadtime for complementary Mode
71
        pwm_channel1.CMR.dthi  = 1;        // Deadtime Inverted on PWMH
72
        pwm_channel1.CMR.dtli  = 0;        // Deadtime Not Inverted on PWML
73
        pwm_channel1.CMR.ces   = 0;        // 0/1 Channel Event at the End of PWM Period
74
        pwm_channel1.CMR.calg  = PWM_MODE_LEFT_ALIGNED;       // Channel mode.
75
        pwm_channel1.CMR.cpol  = PWM_POLARITY_LOW;            // Channel polarity.
76
        pwm_channel1.CMR.cpre  = AVR32_PWM_CPRE_CCK;           // Channel prescaler.
77
        pwm_channel1.cdty      = 70;       // Channel duty cycle, should be < CPRD.
78
        pwm_channel1.cprd      = 140;       // Channel period.
79

80

81
        // With these settings, the output waveform period will be :
82
        // (56MHz)/20 == 2.8MHz == (MCK/prescaler)/period, with MCK == 56MHz,
83
        // prescaler == 1, period == 20.
84

85
        pwm_channel_init(channel_id, &pwm_channel); // Set channel configuration to channel 0
86

87
        pwm_channel_init(channel_id1, &pwm_channel1); // Set channel configuration to channel 0
88

89
        pwm_start_channels((1 << channel_id));  // Start channel 0 & 1.
90
        pwm_start_channels((1 << channel_id1));  // Start channel 0 & 1.
91

92

93
        /**
94
         * \note the call to sysclk_init() will disable all non-vital
95
         * peripheral clocks, except for the peripheral clocks explicitly
96
         * enabled in conf_clock.h.
97
         */
98
        sysclk_init();
99
        // Enable the clock to the selected example Timer/counter peripheral module.
100
        sysclk_enable_peripheral_clock(EXAMPLE_TC);
101
        // Initialize the USART module for trace messages
102
        init_dbg_rs232(sysclk_get_pba_hz());
103
        // Disable the interrupts
104
        cpu_irq_disable();
105

106
#if defined (__GNUC__)
107
        // Initialize interrupt vectors.
108
        INTC_init_interrupts();
109
        // Register the RTC interrupt handler to the interrupt controller.
110
        INTC_register_interrupt(&tc_irq, EXAMPLE_TC_IRQ, EXAMPLE_TC_IRQ_PRIORITY);
111
#endif
112

113
        print_dbg("haha");
114

115
        //Enable the interrupts
116
        cpu_irq_enable();
117
        // Initialize the timer module
118
        tc_init(tc);

Im Anhang habe ich die zeitlichen Verläufe der Signale dargestellt.

Grüße,

hkn
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren