Hallo,
ich will meinen Atmega 328 programmieren. Nur leider funktioniert meine
delay() Funktion nicht. Ich weiß nach 3 Stunden einfach nicht mehr
weiter und denke schön langsam ich bin zu blöd zum Programmieren. Wäre
jemand so nett, sich meinen Code mal anzusehen? Der Fehler müsste doch
in dem delay() drin sein?! Ich poste trotzdem mal den ganzen Code.
PORTD,(1<<RESERVE) ist mein Debug-Pin, an dem ich mit dem Oszi hänge.
1
///preprocessing
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
5
///define port pins
6
//PortB
7
#define LCD_CS1 PIN0
8
#define LCD_CS2 PIN1
9
#define LCD_WRITE PIN2
10
#define SIPO_STR PIN3
11
#define SIPO_CLK PIN4
12
#define PISO_CLK PIN4
13
#define SIPO_DS PIN5
14
#define PISO_Q7 PIN5
15
#define XTAL1 PIN6
16
#define XTAL2 PIN7
17
//PortC
18
#define BatNotLoad PIN0
19
#define Uline PIN1
20
#define LED_3 PIN2
21
#define LED_2 PIN3
22
#define ResADC PIN4
23
#define UBat PIN5
24
//PC6 only ISP! >>reserve
25
//PortD
26
#define SIM_TxD PIN0 //avr input
27
#define SIM_RxD PIN1 //avr output
28
#define RESERVE PIN2
29
#define SIM_ON PIN3
30
#define SIM_Status PIN4
31
#define LED_1 PIN5
32
#define PISO_PL PIN6
33
#define LCD_Data PIN7
34
35
///define clock variables
36
structtime{
37
uint16_t_100us;
38
uint8_t_s;
39
uint8_t_min;
40
uint8_t_h;
41
uint8_t_date;
42
uint8_t_month;
43
uint8_t_year;
44
};
45
structtimesystime;
46
47
//update system clock ########## datum-monat, schaltjahr
volatile? Ich dachte es wäre C-Standard wenn ich eine Variable am
Anfang, außerhalb der main{}-Schleife initialisiere, dass die dann
global gültig ist. Auf jedenfall danke für die Antwort, ich werde es
gleich mal ausprobieren.
Bei Zugriff auf volatile Variablen werden Interrupts gesperrt, damit die
Variable nicht während des Zugriffs verändert wird.
Das ist nötig, wenn man Variable mit mehr als 8 Bit auf einem 8 Bit µC
verabreitet.
Du hast eventuell noch ein zweites Problem: Ich fürchte, dass deine
Interrupt-Routine manchmal länger als 100µS dauert.
Wenn du noch mehr Hilfe brauchst, dann beschreibe das Problem, dass du
siehst. "Funktioniert nicht" ist zu wenig Text.
Stefan U. schrieb:> Bei Zugriff auf volatile Variablen werden Interrupts gesperrt, damit die> Variable nicht während des Zugriffs verändert wird.
Äh. Nein
INterrupts werden da an keiner Stelle gesperrt. Das ist nicht der Sinn
von volatile
FAQ: Was hat es mit volatile auf sich> Das ist nötig, wenn man Variable mit mehr als 8 Bit auf einem 8 Bit µC> verabreitet.
Auch das ist im Zusammenhang mit volatile Unsinn. Du redest hier von
einem sog. atomaren Zugriff. Den wird er zwar auch brauchen, hat aber
nichts mit volatile zu tun.
Hallo M. M.,
lies dir den obigen Link durch und du wirst verstehen was da abgeht.
>> FAQ: Was hat es mit volatile auf sich
Der Compiler muß wissen, dass er an dieser Variablen nicht herum zu
optimieren hat. Und nur dann wird das was Du programmiert hast auch so
umgesetzt ohne irgendwelche Zusammenfassungen etc. auch wenn die
Deklaration der Variable grundsätzlich richtig ist.
Grüße
Bernhard
M. M. schrieb:> volatile? Ich dachte es wäre C-Standard wenn ich eine Variable am> Anfang, außerhalb der main{}-Schleife initialisiere, dass die dann> global gültig ist. Auf jedenfall danke für die Antwort, ich werde es> gleich mal ausprobieren.
Ich habe keine Ahnung, wovon zum Henker du da eigentlich sprichst.
volatile hat absolut nichts mit dem Scope von Variablen zu tun.
Ich sehe gerade noch einen Fehler:
Stell Dir vor, systime._100us hat gerade den Wert 9999 und du rufst dann
delay(1) auf.
Dann ergibt sich folgende Brechnung:
Zuerst: (9999 - 9999) = 0 und das ist < 1
Dann ein Interrupt später: (0 - 9999) = -9999 und das ist immer noch <1
Du wirst in einer ENdlosschleife hängen bleiben.
Der gleiche Fehler tritt auch mit anderen delay-Werten auf.
Stefan U. schrieb:> Du hast eventuell noch ein zweites Problem: Ich fürchte, dass deine> Interrupt-Routine manchmal länger als 100µS dauert.
Mach die Pferde nicht scheu.
Wenn ich seine Timer Innitialisierung zurück rechne, dann läuft sein µC
mit 20Mhz. Zumindest ist der Timer so eingestellt, dass er alle 2000 CPU
Takte einen Interrupt auslöst. 2000 CPU Takte sind mehr als genug für
das bischen Rechnerei.
Stefan U. schrieb:> Dann ein Interrupt später: (0 - 9999) = -9999 und das ist immer noch <1
Stefan!
Lehn dich zurück!
Was sagt dir 'unsigned'?
Es sagt dir, dass das Ergebnis per Definition nicht negativ sein kann
> Interrupts werden da an keiner Stelle gesperrt.> Das ist nicht der Sinn von volatile.
Ich hätte drauf geschworen. Aber aufgrund deines Hinweises habe ich mal
einen konkretes Listing überprüft und kann nun deine AUssage bestätigen.
So ein Käse, das hätte ich richtig wissen sollen.
Bernhard S. schrieb:> Der Compiler muß wissen, dass er an dieser Variablen nicht herum zu> optimieren hat. Und nur dann wird das was Du programmiert hast auch so> umgesetzt ohne irgendwelche Zusammenfassungen etc. auch wenn die> Deklaration der Variable grundsätzlich richtig ist.
Das ist ein guter Punkt. Wie läuft das in C? Wie geht man bei sowas vor?
Ich komme halt aus der Assembler-Ecke und bin in AVR-C ein Anfänger.
Karl H. schrieb:> Mach die Pferde nicht scheu.> Wenn ich seine Timer Innitialisierung zurück rechne, dann läuft sein µC> mit 20Mhz. Zumindest ist der Timer so eingestellt, dass er alle 2000 CPU> Takte einen Interrupt auslöst. 2000 CPU Takte sind mehr als genug für> das bischen Rechnerei.
Ja richtig 20MHz. Also im schlimmsten Fall gibt es einen Arithmetischen
Überlauf bei der Subtraktion. Aber da das unsigned ist, gibts keine
Endlosschleife. Die delay-Funktion ist halt nicht genau 100us genau,
aber 100us hin oder her ist mir hier egal.
Stefan U. schrieb:>> Interrupts werden da an keiner Stelle gesperrt.>> Das ist nicht der Sinn von volatile.>> Ich hätte drauf geschworen. Aber aufgrund deines Hinweises habe ich mal> einen konkretes Listing überprüft und kann nun deine AUssage bestätigen.
volatile ist Standard-C
In Standard-C gibt es den Begriff 'Interrupt' sowie so gut wie alles
sonstige hardware-abhängige nicht. Im C-Standard wird eine idealisierte
Maschine vorausgesetzt. Ob die Interrupts kennt oder nicht, ob die eine
Stack hat oder nicht, wie sie dynamischen Speicher zur Verfügung stellt
(das was wir Heap nennen), ob es ein Terminal oder Keyboard gibt oder
nicht, das alles und noch viel mehr interessiert im C Standard nicht.
M. M. schrieb:> Bernhard S. schrieb:>> Der Compiler muß wissen, dass er an dieser Variablen nicht herum zu>> optimieren hat. Und nur dann wird das was Du programmiert hast auch so>> umgesetzt ohne irgendwelche Zusammenfassungen etc. auch wenn die>> Deklaration der Variable grundsätzlich richtig ist.>> Das ist ein guter Punkt. Wie läuft das in C? Wie geht man bei sowas vor?
Wie oft soll ich denn noch den Link posten, bis du endlich mal
draufklickst und nachliest, was Sache ist
FAQ: Was hat es mit volatile auf sich
Karl H. schrieb:> Stefan U. schrieb:>> Dann ein Interrupt später: (0 - 9999) = -9999 und das ist immer noch <1>> Stefan!>> Lehn dich zurück!> Was sagt dir 'unsigned'?>> Es sagt dir, dass das Ergebnis per Definition nicht negativ sein *kann*
Nichtdestotrotz wird das so nicht funktionieren: 65536-9999 == 55537.
Und jetzt bitte weiterrechnen ;-)