Hallo, Leider funktioniert mein Timer immer noch nicht. Pure Verzweiflung! Alle Komponenten meines Programms außer Timer 1 funktionieren. Darum habe ich nur ein kleines Timer-Programm zugeschickt. Den Timer hier habe ich mit Code Vizard (SiSy-AVR) generiert. Das Programm sollte eine Markise steuern: Wenn der Wind schwach ist, das heißt wenige als 10 Impulse am Interrupt D3 innerhalb von 5 Sekunden -> öffnet die Markise. Bei starken Wind Markise schließt und die Windanzeige geht an. Bitte um Hilfe! Mit freundlichen Grüßen
Pimi schrieb: > Hallo, > Leider funktioniert mein Timer immer noch nicht. Pure Verzweiflung! > Alle Komponenten meines Programms außer Timer 1 funktionieren. > Darum habe ich nur ein kleines Timer-Programm zugeschickt. Den Timer > hier habe ich mit Code Vizard (SiSy-AVR) generiert. Vergiss doch einfach mal dieses ganze SiSy Zeugs und diverse Code-Wizards. Verstehen wie die Dinge tatsächlich funktionieren kann durch keinen Wizard ersetzt werden! Wenn ich sowas ....
1 | TCCR1B=0x05; // Teiler 1/1024 |
2 | TCCR1B|=0x02; // Modus: Zählen bis Vergleichswert |
schon sehe, krieg ich die Krise und meine Bereitschaft da irgendwelchen Code zu analysieren tendiert rapide gegen 0. Was ist denn nun?
1 | #define F_CPU 3686400
|
2 | #include <avr\io.h> |
3 | #include <util\delay.h> |
4 | |
5 | int main() |
6 | {
|
7 | Port auf Ausgang schalten |
8 | |
9 | while( 1 ) |
10 | {
|
11 | LED einschalten |
12 | _delay_ms( 1000 ); |
13 | LED ausschalten |
14 | _delay_ms( 1000 ); |
15 | }
|
16 | }
|
blinkt deine LED mit 1 Sekunde an/aus oder blinkt sie nicht in diesem Zeitraster? Ehe das nicht stimmt hat es doch keinen Sinn irgendwelche weiteren Berechnungen oder Versuche mit Timerzeiten zu machen, weil dann etwas ganz Grundlegendes nicht stimmt! Dein µC taktet dann eben nicht so schnell, wie der Wert, mit dem alles andere berechnet wurde, aussagt. (Entweder das, oder der Optimizer ist nicht eingeschaltet) Du kannst stundenlang irgendwelche Berechnungen darüber anstellen, wie weit du mit 250km/h fahren kannst bzw. wo du da am Sonntag Nachmittag überall hin einen Ausflug machen kannst. Wenn aber dein VW-Käfer (das Original) nun mal nicht mehr als 100km/h schafft, dann ist die ganze Rechnerei sinnlos und deine Ergebnisse werden gnadenlos falsch sein.
Liefert der Sensor überhaupt prellfreie Impulse oder ist das ein Kontakt? Laß Dir doch erstmal den Meßwert über UART oder ein LCD ausgeben. Peter
Hallo, Karl Heinz Buchegger schrieb: > TCCR1B=0x05; // Teiler 1/1024 > TCCR1B|=0x02; // Modus: Zählen bis Vergleichswert > schon sehe, krieg ich die Krise und meine Bereitschaft da irgendwelchen > Code zu analysieren tendiert rapide gegen 0. Danke für Ihre Hilfsbereitschaft! Ich weiß dass bei mir fehlen die Grundkenntnisse. Bis jetzt war für mich das „Sisy Zeug“ sehr hilfreich. Ich weiß nicht mal wie ich das ganze Zeug lernen kann, bis jetzt fand ich keine entsprechende Literatur (C-Sprache), wo alles auf einfache art und weiße erklärt wird. Wenn du mir mit einem Tipp dabei helfen willst wäre ich sehr dankbar! Den Fehler habe ich mit Hilfe behoben: 1. Falsche Fuses 2. Falsche Timerkonfiguration: Ist: TCCR1B=0x05; // Teiler 1/1024 TCCR1B|=0x02; // Modus: Zählen bis Vergleichswert korrekt heißt es TCCR1B=0x05; // Teiler 1/1024 TCCR1B|=0x08; // Modus: Zählen bis Vergleichswert An Alle die mir Helfen wollten. Besten Dank!
Hallo Pimi, hast es schneller hin bekommen als ich dazu kam dir nen Lösungsvorschlag leider nur für den ATmega8 zusammenzuschustern :-( ich poste den trotzdem mal, vielleicht kommst ja dazu das mal auszuprobieren brauchst aber dafür schon das aktuellste Sisy ... interessiert mich unheimlich ob das geht oder ob die Klasse Button zu träge für deinen Windsensor ist.
1 | //----------------------------------------------------------------------
|
2 | // Titel : Automatische Markisensteuerung, kleines Programm AVR C++
|
3 | //----------------------------------------------------------------------
|
4 | //----------------------------------------------------------------------
|
5 | // Schaltung : Windsensor liefert einen Impuls je Umdrehung -> an PortD3 -> Zählen mit Interrupt
|
6 | // Schalter an PortC5 öffnet/schießt die Markise (es wird der soll-Zustand [High=offen; Low=geschlossen] ausgegeben)
|
7 | // Funktion : Markise ist offen:
|
8 | // Wenn innerhalb eines Intervalls 1 der Schwellwert überschrittenwird,
|
9 | // soll die Markise geschlossen werden.
|
10 | // Markise ist geschlossen:
|
11 | // Wenn innerhalb von 120xIntervall 1 der Schwellwert nicht überschritten wurde
|
12 | // soll die Markise geöffnet werden.
|
13 | // Prozessor : ATmega328P
|
14 | // Takt : 3686400 Hz
|
15 | // Sprache : C++
|
16 | //-------------------------------------------------------------------------
|
17 | #define MAX_IMPULSE 10
|
18 | #define MAX_INTERVALL 120
|
19 | |
20 | class Markise |
21 | {
|
22 | public: void init() {ddrC.bit0=1;} |
23 | public: void close() {portC.bit0=0;} |
24 | public: void open() {portC.bit0=1;} |
25 | public: bool isOpen() {return portC.bit0;} |
26 | };
|
27 | |
28 | class Anzeige |
29 | {
|
30 | public: void init() {ddrB.bit0=1;} |
31 | public: void on() {portB.bit0=0;} |
32 | public: void off() {portB.bit0=1;} |
33 | };
|
34 | |
35 | |
36 | class Application : public Controller |
37 | {
|
38 | protected: Button windsensor; |
39 | protected: uint8_t impulsCounter; |
40 | protected: uint8_t intervallCounter; |
41 | protected: Markise markise; |
42 | protected: Anzeige windAnzeige; |
43 | |
44 | public: void onStart() |
45 | {
|
46 | windsensor.config(portD,bit3); |
47 | impulsCounter=0; |
48 | markise.init(); |
49 | windAnzeige.init(); |
50 | }
|
51 | |
52 | public: void onWork() |
53 | {
|
54 | // leer
|
55 | }
|
56 | |
57 | public: void onTimer1s() |
58 | {
|
59 | if(markise.isOpen()) |
60 | {
|
61 | if(impulsCounter >= MAX_IMPULSE) |
62 | {
|
63 | markise.close(); |
64 | windAnzeige.on(); |
65 | }
|
66 | intervallCounter=0; // wenn offen werden die Intervalle nicht gezählt. |
67 | }
|
68 | // wenn geschlossen
|
69 | else
|
70 | {
|
71 | intervallCounter++; |
72 | // wenn zu windig
|
73 | if(impulsCounter >= MAX_IMPULSE) |
74 | {
|
75 | intervallCounter=0; |
76 | }
|
77 | |
78 | if(intervallCounter >= MAX_INTERVALL) |
79 | {
|
80 | markise.close(); |
81 | windAnzeige.off(); |
82 | }
|
83 | }
|
84 | impulsCounter = 0; // Impulszähler für nächses Intervall zurücksetzen |
85 | }
|
86 | |
87 | public: void onEvent(const Object& sender, uint8 data) |
88 | {
|
89 | // Windsensor sollte wie ein Button arbeiten und jeder Impuls als Click ankommen,
|
90 | // Button ist bereits entprellt aber vielleicht zu langsam
|
91 | if ( sender == windsensor && data == Button::Click ) |
92 | impulsCounter++; |
93 | }
|
94 | |
95 | } app; |
Pimi schrieb: > korrekt heißt es > TCCR1B=0x05; // Teiler 1/1024 > TCCR1B|=0x08; // Modus: Zählen bis Vergleichswert Nein. Korrekt heisst es: TCCR1B = ( 1 << CS12 ) | ( 1 << CS10 ); TCCR1B |= ( 1 << WGM12 ); Ob das WGM12 Bit nun das Bit 2 oder das Bit 4 ist, ist etwas was mich nicht interessieren braucht. Das Bit hat einen Namen! Und über den setze ich es. Dann passieren dir auch nicht solche Bit-Unfälle. Du hast jetzt am eigenen Leib erfahren, wie mühsam es ist, Hex-Konstanten wie 0x02 oder 0x05 mit dem Datenblatt in Übereinstimmung zu bringen und rauszukriegen, was da wirklich passiert. Benutze die Bitnamen und du schaltest zumindest eine Fehlerquelle erst mal aus.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.