Forum: Mikrocontroller und Digitale Elektronik AT32UC30512C: ADC-Interrupt mit PWM-Signal synchronisieren


von Heiko N. (Gast)


Angehängte Dateien:

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.