Forum: Mikrocontroller und Digitale Elektronik atmega8 COMPA und COMPB zugleich verwenden


von sesam (Gast)


Lesenswert?

Hallo zusammen,

ich habe das erste Beispiel der Soft-PWM verwendet von der Seite: 
http://www.mikrocontroller.net/articles/Soft-PWM

ich würde gerne eine kleine Änderung durchführen:

ich möchte ein Paar weitere Ports mit der gleichen PWM-Frequenz 
ansteuert nur mit einem anderen PWM-Verhältnis (z.b. dunklere LEDs).



Im folgenden ist mein Ansatz zu sehen:
1
/*
2
    Eine 8-kanalige PWM mit einfachem Lösungsansatz
3
 
4
    ATmega32 @ 8 MHz
5
 
6
*/
7
 
8
// Defines an den Controller und die Anwendung anpassen
9
 
10
#define F_CPU 8000000L                  // Systemtakt in Hz
11
#define F_PWM 100                       // PWM-Frequenz in Hz
12
#define PWM_STEPS_A 145                   // PWM-Schritte pro Zyklus(1..255)
13
#define PWM_STEPS_B 45                   // PWM-Schritte pro Zyklus(1..255)
14
#define PWM_PORT_D PORTD                  // Port für PWM
15
#define PWM_DDR_D DDRD                    // Datenrichtungsregister für PWM
16
#define PWM_PORT_C PORTC                  // Port für PWM
17
#define PWM_DDR_C DDRC                    // Datenrichtungsregister für PWM
18
// ab hier nichts ändern, wird alles berechnet
19
 
20
#define T_PWM_A (F_CPU/(F_PWM*PWM_STEPS_A)) // Systemtakte pro PWM-Takt
21
#define T_PWM_B (F_CPU/(F_PWM*PWM_STEPS_B)) // Systemtakte pro PWM-Takt
22
#if (T_PWM_A<(152+5))
23
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden
24
#endif
25
#if (T_PWM_B<(152+5))
26
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden
27
#endif 
28
29
30
#if PWM_STEPS > 255
31
    #error PWM_STEPS zu gross
32
#endif
33
 
34
// includes
35
 
36
#include <stdint.h>
37
#include <string.h>
38
#include <avr/io.h>
39
#include <avr/interrupt.h>
40
 
41
// globale Variablen
42
 
43
volatile uint8_t pwm_setting_A[8];                    // Einstellungen für die einzelnen PWM-Kanäle
44
volatile uint8_t pwm_setting_B[8];                    // Einstellungen für die einzelnen PWM-Kanäle
45
 
46
// Timer 1 Output COMPARE A Interrupt
47
 
48
ISR(TIMER1_COMPA_vect) {
49
    static uint8_t pwm_cnt=0;
50
    uint8_t tmp=0, i=0, j=1;
51
 
52
    OCR1A += (uint16_t)T_PWM_A;
53
 
54
    for (; i<8; i++) {    
55
      if (pwm_setting_A[i] > pwm_cnt) tmp |= j;
56
            j<<=1;
57
  }
58
    PWM_PORT_D = tmp;                         // PWMs aktualisieren
59
    if (pwm_cnt==(uint8_t)(PWM_STEPS_A-1))
60
        pwm_cnt=0;
61
    else
62
        pwm_cnt++;
63
}
64
65
ISR(TIMER1_COMPB_vect) 
66
{
67
    static uint8_t pwm_cnt=0;
68
    uint8_t tmp=0, i=0, j=1;
69
 
70
    OCR1B += (uint16_t)T_PWM_B;
71
 
72
    for (; i<8; i++) {    
73
      if (pwm_setting_B[i] > pwm_cnt) tmp |= j;
74
            j<<=1;
75
  }
76
    PWM_PORT_C = tmp;                         // PWMs aktualisieren
77
    if (pwm_cnt==(uint8_t)(PWM_STEPS_B-1))
78
        pwm_cnt=0;
79
    else
80
        pwm_cnt++;
81
}
82
83
int main(void) {
84
 
85
    // PWM einstellen
86
 
87
    PWM_DDR_D = 0xFF;         // Port als Ausgang
88
  PWM_DDR_C = 0xFF;         // Port als Ausgang
89
 
90
    // Timer 1 OCRA1, als variablem Timer nutzen
91
 
92
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt
93
    TIMSK |= (1<<OCIE1B) | (1<<OCIE1A);   // Interrupt freischalten
94
95
  
96
 
97
    sei();                  // Interrupts global einschalten
98
 
99
/*********************************************************************/
100
// nur zum Testen, im Anwendungsfall löschen
101
 
102
    volatile uint8_t tmp;
103
const uint8_t t1[8]={270, 400, 30, 1007, 150, 99, 5, 9};
104
const uint8_t t2[8]={270, 400, 30, 0, 150, 99, 5, 9};
105
const uint8_t t3[8]={270, 400, 30, 1007, 3, 99, 3, 0};
106
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};
107
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};
108
const uint8_t t6[8]={330, 330, 330, 3003, 33, 33, 33, 33};
109
 
110
// Messung der Interruptdauer
111
    tmp =0;
112
    tmp =0;
113
    tmp =0;
114
 
115
// Debug 
116
 
117
    memcpy(pwm_setting_A, t1, 8);
118
    memcpy(pwm_setting_A, t2, 8);
119
    memcpy(pwm_setting_A, t3, 8);
120
    memcpy(pwm_setting_A, t4, 8);
121
    memcpy(pwm_setting_A, t5, 8);
122
    memcpy(pwm_setting_A, t6, 8);
123
124
  memcpy(pwm_setting_B, t1, 8);
125
    memcpy(pwm_setting_B, t2, 8);
126
    memcpy(pwm_setting_B, t3, 8);
127
    memcpy(pwm_setting_B, t4, 8);
128
    memcpy(pwm_setting_B, t5, 8);
129
    memcpy(pwm_setting_B, t6, 8);
130
 
131
/*********************************************************************/
132
133
    while (1)
134
    {
135
    }
136
 
137
    return 0;
138
}

Mein Problem:  Am Port C kommt nichts an... keine schöne PWM wie an Port 
D... ich hoffe jemand kann das geheimnis lüften

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.