AVR PWM-Steuerprogramm für LEDs

OP #4598243
Hallo Leute,

eins vorweg, ich bin absoluter Einsteiger was C angeht, und plänkel 
aktuell noch in den Basics herum. Falls das Thema woanders hingehört 
bitte verschieben!

Ich will mir ein kleines Programm für mein eigenes Projekt schreiben und 
möchte dabei erreichen, dass ich zunächst erst einmal LEDs über einen 
Schalter (aktuell an PINA0) anschalten und in einer Art Abfolge laufen 
lassen kann.

Das Hauptproblem besteht darin, dass ich aktuell nicht weiß wie ich 
permanent den Schalter abfrage und meine LED-Abfolge damit starten 
lassen kann. Zudem weiß ich nicht wie ich die Abfolge unterbreche, falls 
der Schalter wieder auf "Aus" gestellt wird.

Die LEDs funktionieren in der gewünschten Abfolge bereits ohne Schalter 
über die PWM Steuerung. Aber die Integration des Schalters und damit der 
Start oder Abbruch darüber machen mir Kopfzerbrechen.

Hier mal mein bisheriges Programm:
1
/*
2
 * PWM.c
3
 *
4
 * Created: 24.10.2015 17:56:40
5
 * Author : lkrie
6
 */
7
 
8
#define F_CPU 970000UL
9
#include <avr/io.h>
10
#include <util/delay.h>
11
//#include <conio.h>
12
 
13
 
14
int wert = 3; //PWM Differenzwert - Verkürzt oder verlängert das PWM Signal
15
//int wert2 = 200;
16
int maxperf = 255; //maximale Leistung liegt bei 255
17
int minperf= 0; //minimale Leistung liegt bei 0
18
 
19
int main(void)
20
{
21
    DDRD = 0;
22
    DDRB = 0xFF;
23
    DDRA = 0x00;
24
    PORTA = 0xff;
25
    TCCR0A = (1<<WGM00)|(1<<COM0A1);
26
    TCCR1A = (1<<WGM10)|(1<<COM1A1);
27
    TCCR0B = (1 << CS01);
28
    OCR0A = 0;
29
    OCR0B = 0;
30
 
31
 
32
               
33
 
34
    while(1)
35
    {
36
                        //hier soll der Schalter rein, mitdem ich den Start der Abfolge initieren kann.
37
            for (OCR0A = minperf; OCR0A < maxperf; OCR0A = OCR0A + wert)
38
            {
39
            _delay_ms(10);
40
            }
41
            for (OCR0A = maxperf; OCR0A > minperf; OCR0A = OCR0A - wert)
42
            {
43
            _delay_ms(10);
44
            }
45
            for (OCR0A = minperf; OCR0A < maxperf; OCR0A = OCR0A +  wert)
46
            {
47
            _delay_ms(10);
48
            }
49
            for (OCR0A = maxperf; OCR0A > minperf; OCR0A = OCR0A - wert)
50
            {
51
            _delay_ms(10);
52
            }
53
            _delay_ms(600);
54
                for (OCR0A = minperf; OCR0A < maxperf; OCR0A = OCR0A + wert)
55
                {
56
                    _delay_ms(10);
57
                }
58
                for (OCR0A = maxperf; OCR0A > minperf; OCR0A = OCR0A - wert)
59
                {
60
                    _delay_ms(10);
61
                }
62
                for (OCR0A = minperf; OCR0A < maxperf; OCR0A = OCR0A +  wert)
63
                {
64
                    _delay_ms(10);
65
                }
66
                for (OCR0A = maxperf; OCR0A > minperf; OCR0A = OCR0A - wert)
67
                {
68
                    _delay_ms(10);
69
                }
70
                _delay_ms(500);
71
                                for (OCR0A = minperf; OCR0A < 180; OCR0A = OCR0A + wert)
72
                                {
73
                                    _delay_ms(12);
74
                                }
75
                                for (OCR0B = 0; OCR0B < 10; OCR0B = OCR0B + OCR0B)
76
                                {
77
                                    _delay_ms(600);
78
                                }
79
    }
80
}
Gast #4599015
Mario K. schrieb:
> eins vorweg, ich bin absoluter Einsteiger was C angeht, und plänkel
> aktuell noch in den Basics herum.

Du musst von vorne anfangen und nicht gleich mit Timern. Du kannst noch 
kein C und versuchst dich an einer PWM. Das ist so, als wolltest du 
Schreibschrift schreiben und kannst noch nicht einmal das Alphabet. Du 
kannst den Programmcode gar nicht verstehen wenn du kein C kannst. ICh 
empfehle dir ein Buch zu lesen.

Der Erlenkötter ist gut für dich.

https://www.amazon.de/C-Programmieren-Anfang-Helmut-Erlenk%C3%B6tter/dp/3499600749.

Wenn du dann ein bisschen C kannst empfehle ich dir ein Buch von Florian 
Schäffer - Hardware und C Programmierung

https://www.amazon.de/AVR-Hardware-C-Programmierung-Florian-Sch%C3%A4ffer/dp/3895762008

Erst dann verstehst du überhaupt was du da tun willst.

Der Programm Code ist Schrott!

Mario K. schrieb:
> #define F_CPU 970000UL

Wie kommst du auf 970kHz?

Mario K. schrieb:
> DDRA = 0x00;
> PORTA = 0xff;

Du sagst dem µC, dass alle Pins des PortA Eingänge sein sollen, und dann 
willst du alle Pins auf 1 schalten. Das ist völliger Blödsinn.
Gast #4599018
0x4E schrieb:
> Du sagst dem µC, dass alle Pins des PortA Eingänge sein sollen, und dann
> willst du alle Pins auf 1 schalten. Das ist völliger Blödsinn.

Ich mache das schon häufiger mal so, oder so ähnlich.
Und dann ist das gut und richtig so.

Manchmal ist es sogar wichtig, das anders rum zu machen:
1
PORTA = 0xff;
2
DDRA = 0x00;
#4599022
Hallo Mario,

das einzige was hier "Schrott und Blödsinn" ist, sind die Kommentare von 
0x4E(Gast) zu deinem Code (die Links zu den Büchern sind allerdings 
empfehlenswert). Mir geht immer der Hut hoch wenn ich so respektloses 
Geschreibsel sehe.

Ich heiße dich als Einsteiger herzlich willkommen.
Auch wenn dein Code etwas eigenartig ist, das ist egal. Während der 
Lernphase muss man alles ausprobieren, nur so lernt man was.

Da deine LEDs bereits wie gewünscht blinken, gehts also nur mehr um den 
Schalter.
Dazu stellst du zunächst den Port A0 auf Eingang, was
du mit DDRA = 0 bereits richtig gemacht hast.
Danach schreibst du PORTA = 0xFF. Damit schaltest du die internen 
Pullups ein. Wenn dein Schalter gegen Masse schaltet ist auch das 
richtig.

Jetzt muss du nur mehr den PINA0 abfragen, und je nach Wert dein 
Programm in einer while Schleife warten lassen, fertig.
z.B. so:
while((PINA & 1) == 1);
oder in Kurzform, was das gleiche ist:
while(PINA & 1);

das kommt dort rein, wo du bereits den entsprechenden Kommentar in 
deinem Programm reingeschrieben hast.

solange das Bit 0 von Port-A auf 1 ist (der Schalter ist offen und der 
Pullup zieht den Eingang auf 1) kreiselt er endlos in der while 
Schleife. Sobald du den Schalter zumachst, wird die while Schleife nicht 
mehr ausgeführt und dein Code für die LEDs wird wieder laufen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.