atmega8 COMPA und COMPB zugleich verwenden

Gast #4022085
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.