Hi,
Ich habe mir heute auf einem Steckbrett eine Experimentierschaltung mit
einem Mega32 aufgebaut. Als Programmer benutze ich einen einfachen
Parallelport Programmer und Ponyprog. Das scheint soweit auch zu
funktioniere. Kann den Flash schreiben, auslesen und auch FuseBits
einstellen. Leider bekomme ich es nicht hin eine einfache LED ans
leuchten zu bekommen.
Hier mein Prog.Code:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/eeprom.h>
4
5
//CPU Frequenz für Programm auf 1MHz einstellen(interner Takt)
6
#define F_CPU 4000000
7
8
//Bautrateneinstellung
9
#define BAUD 4800L // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
14
15
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
16
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
17
#endif
18
19
//***********************
20
typedefunsignedcharbyte;
21
typedefunsignedintword;
22
23
typedefstructbyte_str{
24
unsignedb0:1;
25
unsignedb1:1;
26
unsignedb2:1;
27
unsignedb3:1;
28
unsignedb4:1;
29
unsignedb5:1;
30
unsignedb6:1;
31
unsignedb7:1;
32
};
33
34
35
//***********************
36
voidioinit(void);
37
voiddelay_ms(unsignedintms);
38
39
40
//***********************
41
// Initialisierung der IO
42
voidioinit(void)
43
{
44
45
DDRA=0xff;// PortB als Ausgang deklarieren
46
//PORTB = 0x00; // Ports auf HIGH schalten
47
48
DDRC=0xff;
49
PORTC=0x2A;
50
51
DDRD=0xff;
52
PORTD=0x00;
53
54
sei();//Interrupts an
55
//cli(); Interrupts aus
56
57
}
58
/***********************/
59
//UART Funktionen
60
61
voidaktiviereUART(void)
62
{
63
UCSRB|=(1<<TXEN);// UART TX einschalten
64
UCSRB|=(1<<RXEN);//UART RX einschalten
65
UCSRC|=(1<<URSEL)|(3<<UCSZ0);// Asynchron 8N1
66
}
67
voiduart_write_char(charc)
68
{
69
while(!(UCSRA&(1<<UDRE)))/* warten bis Senden moeglich */
70
{
71
}
72
73
UDR=c;/* schreibt das Zeichen x auf die Schnittstelle */
74
}
75
voiduart_write_String(char*s)
76
{
77
while(*s)
78
{/* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
79
uart_write_char(*s);
80
s++;
81
}
82
}
83
84
85
86
87
//********************
88
//Methoden
89
90
// Warteschleife
91
voiddelay_ms(unsignedintms)
92
{
93
unsignedintzaehler;
94
95
while(ms){
96
zaehler=F_CPU/5000;
97
98
while(zaehler){
99
asmvolatile("nop");
100
zaehler--;
101
}
102
ms--;
103
}
104
}
105
106
// Hauptprogramm
107
intmain(void){
108
unsignedchari;
109
110
ioinit();
111
112
113
// Endlosschleife
114
while(1){
115
116
PORTD=0xff;
117
PORTA=0x00;
118
119
}
120
121
return0;
122
}
Ich habe eine LED mit minus an PD6 über 330Ohm an Vss(5V). Die LED will
aber nicht leuchten.
Ich habe einen Externen Quarz mit 4Mhz angeschlossen. Muss ich das in
den FuseBits irgendwie einstellen das der ext. Quarz genutzt wird?
Welche Bits muss ich in PonyProg setzen? Wie kann ich mir sicher sein,
das der ext. Quarz korrekt arbeitet?
Sebi
> Ich habe eine LED mit minus an PD6 über 330Ohm an Vss(5V). Die LED will> aber nicht leuchten.
Warum sollte sie auch. Wenn der Minuspol an PD6 liegt, dann folglich der
Plus an Vss (das Kürzel für Masse), also ist die LED grad verkehrt herum
dran.
Wenn du andererseits mit Vss(5V) in Wahrheit Vcc meinst, dann ist zwar
die LED richtig rum, aber mit PORTD=0xFF liegt der Ausgang auch auf 5V
und die LED kriegt nix.
Die Led ist mit dem kurzen beinchen an dem Port und mit dem anderen über
330Ohm an 5V. Ich nutze Port PD6. Aber es geht nicht. Muss ich noch
irgendwas anderes im Controller einstellen?
Wie nutze ich den externen Quarz?
Sebastian wrote:
> Die Led ist mit dem kurzen beinchen an dem Port und mit dem anderen über> 330Ohm an 5V. Ich nutze Port PD6. Aber es geht nicht. Muss ich noch> irgendwas anderes im Controller einstellen?>> Wie nutze ich den externen Quarz?
Eins nach dem anderen. Jetzt muss erstmal deine LED leuchten
und dazu ist es unerheblich ob dein Quarz jetzt aktiv ist
oder nicht. Dein Mega32 arbeitet, wenn du an den Fuses noch nichts
verstellt hast, mit dem internen Oszillator auf ca. 1Mhz.
Wichtig ist nur: Er arbeitet.
Gib doch einfach mal ein anderes Bitmuster am Port aus:
0xAA
Das ist binär 10101010, dh. immer abwechselnd eine 1 und
eine 0. Wenn deine LED also am Pin PD6 nicht leuchtet
dann versuche mal den Pin PD5. An einem der beiden muss
es gehen, ansonsten ist was an der Hardware faul.
Sebastian wrote:
> Ah,Ich habs hinbekommen. Sie blinkt jetzt....*Freu*
Gut
>> Und wie gehts jetzt weiter?
Keine Ahnung. Was willst du denn machen?
Wegen der Umstellung auf Quarz:
http://www.mikrocontroller.net/articles/AVR_Fuses
Erstmal würde ich gerne verstehen wie ich das mit der Zeit und der
Taktfrequenz geregelt bekomme.
Ich habe ja F_CPU 4000000 wegen dem ext. Quarz. Dann ist in der delay_ms
eine wartezeit in ms eingegeben. Wie errechnet man die exakte wartezeit
in ms, so das die wartezeit wirklich in ms angegeben werden kann?
Sebastian wrote:
> Erstmal würde ich gerne verstehen wie ich das mit der Zeit und der> Taktfrequenz geregelt bekomme.>> Ich habe ja F_CPU 4000000 wegen dem ext. Quarz.
Dann solltest du dem obigen Link folgen, die Seite komplett
lesen und den Mega32 mal auf Quarz-Betrieb umstellen
> Dann ist in der delay_ms> eine wartezeit in ms eingegeben. Wie errechnet man die exakte wartezeit> in ms, so das die wartezeit wirklich in ms angegeben werden kann?
Gar nicht.
Du gibst einfach an, wieviele ms du haben willst und _delay_ms
macht das dann.
Aber beachte:
Die delay Funktion die du da hast, die schmeist du gleich
wieder weg und verwendest die, die mit dem Compiler mitgeliefert
wird. Kein Grund das Rad neu zu erfinden.
#define F_CPU 4000000
#include <avr/io.h>
#include <util/delay.h>
int main()
{
....
_delay_ms( 10.0 ); // Warte 10 Millisekunden
....
}
Aber Achtung: Diese mitgelieferte Funktion hat eine Obergrenze.
Du kannst nicht beliebige Millisekunden anfordern. Die Obergrenze
ist von deiner Taktfrequenz abhängig und ist als Formel in delay.h
angegeben.
10 Millisekunden sind aber kein Problem. Wenn du daraus eine
ganze Sekunde machen willst (sowas macht man allerdings in einem
relaen Programm nicht), dann musst du halt 100 mal 10 Millisekunden
abwarten:
for( i = 0; i < 100; ++i )
_delay_ms( 10.0 );
(Den Optimizer des Compilers einschalten nicht vergessen, sonst
stimmen die Zeiten nicht)
Wie würde man das denn in einem realen prog. machen? Sagen wir mal man
möchte 1000ms warten. Würde man eine solche Schleife nutzen?
Gibt es irgendwo eine übersicht über die vom Compiler oder von WinAVR
zur verfügung gestellten methoden?
Habe mal in PonyProg die FUSEBits ausgelesen. CKSEL 3-1 haben ein
häkchen, 0 nicht. Da das anscheinend invertierte logik ist, bedeutet das
0001 wenn ich das nach der FUSEBIT seite deute bedeutet das internal
QuarzOsz. wie zu erwarten.
> Wie würde man das denn in einem realen prog. machen? Sagen wir mal man> möchte 1000ms warten. Würde man eine solche Schleife nutzen?
Lässt sich so allgemein nicht beantworten. In einfachen Programmen ja,
in komplexen Programmen arbeitet man eher mit Timer-Interrupts und
dadurch gesetzten Erinnerungen.
> Gibt es irgendwo eine übersicht über die vom Compiler oder von WinAVR> zur verfügung gestellten methoden?
Mit ein bischen Suche nach dem passenden Icon bei dir auf der Platte.
Oder http://www.nongnu.org/avr-libc/user-manual/index.html.
Kann ich mit dem Internen Osz. auch höhere Frequenzen machen? Habe
gerade gesehen das man beim AVR Fuse Calc
http://palmavr.sourceforge.net/cgi-bin/fc.cgi
auch 8MHz wählen kann. Geht das dann ohne ext. Quarz?
> Kann ich mit dem Internen Osz. auch höhere Frequenzen machen?
Wie wär's mit einem Blick ins Datasheet? Dein Text über die Fuses deutet
an, dass du immerhin mal reingesehen hast. Sowas steht da drin.
Jagut, also scheint der sogar 8MHz intern zu können. Man kann das ja
sogar noch irgendwie kllibrieren wenn ichs richtig verstehe. Dann muss
ich die bits jetzt auf 0100 für 8MHz setzen. Das wäre in Ponyprog X0XX
bei CKSEL3-0 (X=Häkchen).
was hast du denn an material benutzt um das obige progeamm zu schreiben?
bin nämlich auch noch anfänger und muss mich erstmal reinfitzen deshlab
bin ich für jeden vorschlag dankbar. hab schon tutorial gelesen aber der
prinzipiele programmaufbau und wie ich an sowas rangeh ist mir noch
nicht wirklich klar
Ich habe WinAVR installiert. Damit kannst du die make-Files und den
Programmcode erstellen und dann auch kompilieren. Zum programmieren
nutze ich PonyProg und einen einfachen ParallelPort Programmer. Das
findest du alles kostenlos im Internet, bzw beim Programmer die
Bauanleitung. Der Parallelport Programmer geht sogar nur mit 2
Widerständen.
Programmcode habe ich mir einfach aus dem avr-gcc tutorial hier auf der
seite zusammengesucht. Mein Code enthält viel was man erstmal nicht
braucht, ich hab einfach nur alles, was ich interessant fand mit rein
kopiert.
Christoph Erstmalegal wrote:
> wie lange hast du gesessen für alles?
Die Frage klingt so nach: Ich muss auf die Schnelle programmieren
lernen und möchte das so schnell wie möglich hinter mich bringen.
Ins Stammbuch geschrieben:
Für die ersten Schritte kann man schon ein paar Tage rechnen,
je nach persönlicher Eignung. Einen etwas fotgeschritteneren
Anfängerstatus erreicht man erst nach ein paar Wochen. So
einigermassen la-la wird man in der Programmierung erst nach
ein paar Monaten. Um mal eine Zahl zu nennen: sagen wir mal
6 - 9 Monate. Gut wird man nicht unter einem Jahr und wenn man
zu einem Experten aufsteigen will, dann reden wir von Jahren
(nicht unter 3).
Die Zahlen mögen je nach persönlicher Eigung und dem Willen
sich zu quälen variieren aber die Proportionen bleiben
erhalten.
Das soll jetzt aber niemanden abhalten, Softwareentwicklung
zu betreiben. Nur so, wie Lieschen Müller sich die Programmierung
vorstellt, so ist das nicht. Das mussten auch die Arbeitsämter
lernen, als sie vor Jahren Unsummen in 2 Monats Schnellsiederkurse
zur Umschulung auf Programmierer investierten. Rausgeschmissenes
Geld.
Christoph Erstmalegal wrote:
> wie lange hast du gesessen für alles?
Wie, kommt man jetzt sogar in den Knast dafür;-? Vorbestraft wegen
AVR-Vergewaltigung?