Hi an alle.
Ich habe einen ATmega168 mit 4 LEDs(rot, blau, grün und gelb).
Die LEDs zum leuchten oder blinken zu bringen stellt nicht die
Schwierigkeit dar. Mich stört nur ein wenig, dass der Code immer fix im
Microcontroller "eingebrannt" ist. Wenn man die Reihenfolge der
blinkenden LEDs ändern möchte, dann muss man wieder in den Quelltext und
das anpassen.
Bei so einem kleinen Projekt ist das ja nicht weiter tragisch, aber bei
größeren kam mir der Gedanke, dass es durchaus praktisch wäre, wenn ich
den Micrcontroller(mit Platine, Quarz, etc.) per USB an den PC hänge und
dort über eine selbst geschriebene Anwendung in C# in der GUI anklicke,
welche LEDs leuchten sollen. Dann sollen die Einstellung welche vom User
getroffen wurden auf den MCU geschrieben werden.
Die Anwendung soll somit jeder bedienen können der von Microcontroller
Programmierung keine Ahnung hat. Also reiner End-Anwender.
Leider habe ich keine Ahnung wie man das umsetzen kann.
Kann mir hier jemand dies etwas näher erklären oder mich an ein Tutorial
weiter leiten, welches mir zeigt wie ich diese Schnitstelle herstellen
kann und welche zusätzlichen Komponenten ich eventuell dazu brauche um
es zu realisieren.
Danke schon mal für die Hilfe.
Du könntest z.B. einfach per PC Befehle an den Controller schicken, der
die dann logischerweise auswertet und somit weiß, welche LEDs leuchten
sollen...
Was ist daran so schwierig?
Ich weiß nicht so recht wie es umzusetzen ist.
Habe so etwas noch nie gemacht.
Habt ihr vielleicht ein Codebeispiel in welcher zum Beispiel eine LED
leuchten soll?
Danke für die Hilfe.
El Nino schrieb:> Ich weiß nicht so recht wie es umzusetzen ist.> Habe so etwas noch nie gemacht.>> Habt ihr vielleicht ein Codebeispiel in welcher zum Beispiel eine LED> leuchten soll?>> Danke für die Hilfe.
Na schau Dir doch mal die AVR Tutorials an.
Blink/Leucht-Code über UART an den µC übermitteln.
Ein Speichern der Standard-Einstellungen im EEPROM (512 Bytes sind
vorhanden im Mega168) ist auch möglich.
Ein Teil des Codes muß dann natürlich Anfragen über UART auswerten.
Wenn die LEDs zur Laufzeit stetig verändert werden sollen, muss der PC
über beispielsweise einen COM-PORT, an dem ein FT232R sitzt, an dem der
Mega168 über UART angeschaltet ist, lediglich ein Byte versenden,
welches im RAM des Mega168 landet. In diesem Byte ist das jeweilige Bit
für die jeweilige LED gesetzt. Der Mega braucht dann diese Bits nur noch
auf den LED-Port zu kopieren. Ich würde mal sagen 30 Befehle in ASM :-)
Knut Ballhause schrieb:> Wenn die LEDs zur Laufzeit stetig verändert werden sollen, muss der PC> über beispielsweise einen COM-PORT, an dem ein FT232R sitzt, an dem der> Mega168 über UART angeschaltet ist, lediglich ein Byte versenden,> welches im RAM des Mega168 landet. In diesem Byte ist das jeweilige Bit> für die jeweilige LED gesetzt. Der Mega braucht dann diese Bits nur noch> auf den LED-Port zu kopieren. Ich würde mal sagen 30 Befehle in ASM :-)
Danke für die Rückmeldung. Ich sehe UART klingt nach dem richtigen
Stichwort. Da werde ich mich ein wenig einlesen.
Die Hauptfunktion die ich möchte ich folgende:
Ich baue eine kleine Platine(ATmega, Quarz, Capacitor, 4 LEDS und
Batterie)
Es wird ein Code in den ATmega geschrieben, welche nur die blaue LED
leuchten lässt.
Nun gebe ich diese Platine an einen einfachen Anwender welcher von
Programmierung keine Ahnung hat. Nun möchte ich es so lösen, dass er/sie
das Gerät per USB an den Computer anschließt und ein C# Programm
startet.
In dem Programm kann er/sie dann anklicken welche der 4 LEDs leuchten
sollen(z.b.: alle 4). Das Programm soll dann diese Information an den
MCU schicken und "reinbrennen".
Wenn das Gerät vom PC getrennt wird, muss die letzte Konfiguration aktiv
sein. In diesem Fall müssen alle 4 LEDs brennen. Auch wenn die Batterie
getrennt wurde und wieder neu angesteckt wird muss die letzte
Konfiguration durch die Software noch vorhanden sein.
Lässt dich das realsieren und was brauche ich noch für diese Umsetzung?
Bausteine?
El Nino schrieb:> Lässt dich das realsieren und was brauche ich noch für diese Umsetzung?> Bausteine?
Ich bin mir nicht sicher, ob du das Prinzip schon verstanden hast oder
nicht. Teilweise klingt es richtig und dann verwendest du wieder eine
Wortwahl, die mich das Gegenteil vermuten lässt.
Das Prinzip ist folgendes:
Das Programm wird nicht so geschrieben, dass es fix verdrahtet zb die
blaue LED brennen lässt.
Das Programm holt sich aus dem EEPROM 1 Byte, in welchem codiert ist,
welche LED einzuschalten sind und welche nicht. Und genau das macht das
Programm: Aufgrund der 'ANweisungen', die in diesem Byte stecken
schaltet es die betreffende LED.
Wie kommt diese 'Anweisung' in das EEPROM?
Indem ein anderer Teil des Programms ständig auf der UART mithört, ob
vom PC etwas kommt. Wenn ja, dann wertet es das als Steuerbyte und
schreibt dieses Byte an die entsprechende Stelle im EEPROM (und sorgt
auch gleichzeitig dafür, dass die LED entsprechend geschaltet werden).
Warum UART?
weil du vom PC aus eine Möglichkeit brauchst, um ein Kommando an den
µC zu schicken
Warum EEPROM?
Weil der EEPROM seinen Inhalt auch dann nicht verliert, wenn der
Strom abgedreht wird.
D.h. du veränderst nicht das Programm an sich. Das Programm bleibt immer
gleich. Aber das Programm ist so gebaut, dass es von Daten gesteuert
wird. Daten die im EEPROM vorliegen, und die sich das Programm von dort
holt, bzw. die das Programm von der UART dorthin schreibt.
Karl Heinz Buchegger schrieb:> D.h. du veränderst nicht das Programm an sich. Das Programm bleibt immer> gleich. Aber das Programm ist so gebaut, dass es von Daten gesteuert> wird. Daten die im EEPROM vorliegen, und die sich das Programm von dort> holt, bzw. die das Programm von der UART dorthin schreibt.
Danke vielmals für deine ausführliche Erklärung. Das war sehr
verständlich und spitzenmäßig erklärt. Ich glaube nun habe ich es
verstanden.
1) Das heißt meine nächsten Schritte werden sein, dass ich es schaffe
"etwas" über UART in den EEPROM zu schreiben.
2) Wenn das mal geglückt ist, kann ich schauen das ich etwas sinnvolles
über UART in den EEPROM schreibe.
3) Dann schreib ich mein Programm so, dass es Informationen aus dem
EEPROM(ich nehme an das ist ein Register) ausliest und anhand dieser
dann das tut was ich möchte. Dies sollte dann eigentlich gleich
funktionieren wie die Übergabe einer Variable in eine Funktion, oder?
// Pseudocode
inhalt_eeprom = abcd();
void blink_led (inhalt_eeprom)
{
switch (inhalt_eeprom)
{
case xxx:
// LED blau
case yyy:
// LED grün
case zzz:
// LED rot
}
}
Habe ich das richtig interprätiert?
El Nino schrieb:> 3) Dann schreib ich mein Programm so, dass es Informationen aus dem> EEPROM(ich nehme an das ist ein Register)
Bitte studier das AVR-GCC-Tutorial
Nein. Das EEPROM ist kein Register. Dein µC hat 3 Arten von Speicher
* Flash
In diesem Speicher liegt dein Programm.
Es wird beim Brennen des Programms beschrieben.
* SRAM
Dort legt das Programm seine Variablen an. Es wird zur Laufzeit
gelesen und beschrieben
* EEPROM
Auch dieser Speicher wird zur Laufzeit gelesen und beschrieben.
Aber: Das geht langsamer als beim SRAM. Dafür hält dieser Speicher
anders als das SRAM seinen Inhalt auch dann, wenn der Strom
abgeschaltet wird.
> Habe ich das richtig interprätiert?
So ungefähr.
Der EEPROM wird als Stromausfallsicherung benutzt und am Anfang z.B. in
den RAM geladen, von wo aus dann dein "Programm" durch das AVR-Programm
im Flash interpretiert wird z.B.
Im EEPROM hätten dann 512 Bytes interpretierbarer Code platz.
Byte 0 Rot an mit Level 128
Byte 1 Warte 1 sekunde
Byte 2 Grün an mit Level 128
....
Es ist deiner Fanatasie überlassen wie das Flash-Programm dann den
EEPROM interpretiert.
Zusätzlich dazu wäre es von Vorteil, wenn dein Flash-Programm dem PC per
UART anbietet das EEPROM-Programm anzuhalten und z.B. umzuschreiben.
Mit Level nehme ich mal die Möglichkeit von PWM vorweg.
Dein Controller hat nicht wirklich viel zu tun und SoftPWM bietet sich
dann an.
Der Flash-Code im Controller wäre dann nur einmal zu Programmieren.
Änderungen werden dann per UART befehligt und im EEPROM gespeichert.
Thomas schrieb:> Warum bietet sich SoftPWM an?> Der ATmega168 hat 6 PWM Kanäle.
Minimum bietet sich SoftPWM an.
Wenn die LED's jetzt nicht zufällig schon an den passenden I/O-Pins
hängen.
Pins wären (OC[0,1,2][A,B])
Danke für die super Antworten. So langsam kapier ichs. :-)
Das Lesen aus dem EEPROM und das Schreiben denke ich nun verstanden zu
habe:
Aus dem AVR GCC Tuorial hat mich das "&eeFooByte" im Befehl:
myByte = eeprom_read_byte (&eeFooByte);
etwas verwirrt. Ich konnte nichts damit anfangen.
Habe dann noch etwas im Netz gesucht und denke ich habe das &eeFooByte
richtig interprätiert. Hoffe ich zumindest. Das soll die ByteStelle im
EEPROM darstellen. Ist das korrekt?
uint8_t num;
num = eeprom_read_byte((uint8_t*)46)
// Der Inhalt an Stelle 46 des EEPROM wird in der Variable num
gespeichert.
eeprom_write_byte ((uint8_t*) 46, 8);
// Mit diesem Befehl wird eine 8 an die Stelle 46 des EEPROM
geschrieben.
Sollte mit #include <avr/eeprom.h> korrekt funktionieren.
Ist das so korrekt?
Heißt das nun, dass ich an die Stellen 0-511(512 Stellen) wegen des
vorhandenen 512 Byte EEPROM Speichers schreiben kann?
Wie viel wird beim Schreiben eines Wortes belegt?
Pro Buchstabe ein Bit?
Demnach müsste es möglich sein an die Stelle 46 das Wort rot zu
schreiben, da dieses nur 3 der vorhandenen 8 Plätze(1Byte) an Stelle 46
belegt.
Habe ich das richtig verstanden?
eeprom_write_word ((uint8_t*)46, rot);
El Nino schrieb:> Danke für die super Antworten. So langsam kapier ichs. :-)>> Das Lesen aus dem EEPROM und das Schreiben denke ich nun verstanden zu> habe:>> Aus dem AVR GCC Tuorial hat mich das "&eeFooByte" im Befehl:> myByte = eeprom_read_byte (&eeFooByte);> etwas verwirrt. Ich konnte nichts damit anfangen.
Im Abschnitt drüber
1
uint8_teeFooByteEEMEM=123;
eeFooByte ist eine Variable vom Typ uint8_t. Das EEMEM markiert diese
Variable als "liegt im EEPROM".
(Du wirst das natürlich nicht eeFooByte nennen sondern deiner Verwendung
entsprechend
1
#include<avr/eeprom.h>
2
3
uint8_tledStatEepromEEMEM;// gesicherter Wert im EEPROM
4
uint8_tledStat;// Arbeitsversion
5
6
intmain()
7
{
8
....
9
10
// den LED Status aus dem EEPROM lesen
11
ledStat=eeprom_read_byte(&ledStatEeprom);
12
13
// mit ledStat weiterarbeiten
14
15
....
16
while(1){
17
....
18
19
// beim UART Empfang kriegt ledStat einen neuen Wert
20
// den wieder zurück ins EEPROM schreiben, damit er
21
// beim nächsten Programmstart wieder zur Verfügung steht
Da gibt es aber ein grundlegendes Unverständnis.
> Demnach müsste es möglich sein an die Stelle 46 das Wort rot zu> schreiben, da dieses nur 3 der vorhandenen 8 Plätze(1Byte) an Stelle 46> belegt.
1 Byte = 8 Bit
Das Wort "Rot" wäre dann ein String von mindestens 3 Byte im Ascii-Code.
Schreiben kann man an jedes der 512 Bytes im EEPROM.
Pro Byte kann man aber getrost 10 mSec Schreibzeit einrechnen.
Lesen geht mit maximaler Geschwindigkeit.
El Nino schrieb:> Heißt das nun, dass ich an die Stellen 0-511(512 Stellen) wegen des> vorhandenen 512 Byte EEPROM Speichers schreiben kann?>> Wie viel wird beim Schreiben eines Wortes belegt?> Pro Buchstabe ein Bit?
In einem Bit kann man keinen Buchstaben ablegen.
1 Buchstabe <==> 1 Byte
genauso wie es auch im Speicher ist.
> Demnach müsste es möglich sein an die Stelle 46 das Wort rot zu> schreiben
Kann man.
Aber wozu willst du da einen String reinschreiben.
Ist nur Aufwand für nichts.
Du kannst ja auch Codezahlen benutzen, bzw. Kombinationen davon.
Die sind viel einfacher per UART zu übertragen, zu speichern und auch
auszuwerten.
Ein Byte kann einen Wert von 0 - 255 darstellen.
Du selbst kann ja dann die Interpretierung im Flash-Code übernehmen.
while(1)
{
eeprombyte=eeprom_read_byte(PC);
switch(eeprombyte)
{
case 0: //restart
PC=0;break;
case 1:
red=on;break;
.........
}
}
Der Fantasie sind nur die Grenzen des EEPROMs gesetzt.
Wenn du dich für interpretierte Programme aus dem EEPROM entscheidest,
solltest du dir erstmal Gedanken machen, was denn so alles passieren
soll.
Die Definition der Opcodes der State-Maschine also.
z.B.
- Farbkanal X mit Helligkeit ... einschalten.
- Farbkanal X ausschalten.
- MilliSekunden warten bis zum nächsten Programmschritt
- Goto/Reset-Befehl für Programmcounter (PC)
etc.
Hmm.
Wenn ich so revü passieren lasse, dann denke ich, du solltest erst mal
dein normales Blinkprogramm so anpassen, dass da nicht eine Abfolge von
Port-Operationen mit zwischengestreuten _delay_ms steht, sondern du dir
überlegst, wie du die Abfolge der LED erst mal durch ein Array
ausdrücken kannst. Ich schätze dann wird dir vieles klarer.
Der Schritt zu dem, was dir vorschwebt, dürfte für dich noch viel zu
groß sein.
1
// in jedem Sequence Element steckt die Information, welche LED leuchten
Die Abfolge der LED ist NICHT im Programmcode selber, sondern im Array
Sequence abgelegt. Das Programm arbeitet datengesteuert. Durch Verändern
der Werte im Array kannst du das Leuchtmuster verändern.
(Und die Details für die LED An-/Abschaltung musst du selbst ins
Programm einsetzen)
So könnte zb dein erstes Zwischenziel aussehen.
Dein nächstes Ziel könnte es zb sein, die Werte in Sequence per UART zu
übertragen bzw. zu verändern.
Danke für deine Rückmeldung Karl Heinz.
Nun bin ich aber vollends verwirrt. :-) Ich steh echt total auf der
Leitung.
Könntest du mir eventuell deinen Code erklären bzw. kommentieren?
Spitze wären noch ein bis zwei Schleifendurchläufe, damit ich verstehe
welche Werte ich in jedem Durchlauf bekomme.
Ich versuche zu erklären wie ich deinen Code interprätiere. Ist aber
sicher falsch sonst würde ich nicht fragen. Aber dann weißt du wo das
Problem liegt.
Habe ich das Array richtig verstanden?
Nehmen wir an im Array stehen nur 4 Inhalte folgendes:
1
uint8_tSequence[]=
2
{
3
ROT,
4
GELB,
5
GRUEN,
6
BLAU,
7
}
Gehe ich nun richtig in der Annahme, dass durch das #define der Farben
zu Beginn
1
#define KEINE 0x00
2
#define ROT 0x01
3
#define GRUEN 0x02
4
#define BLAU 0x04
5
#define GELB 0x08
nun folgendes im Array steht: 1,8,2,4 ?
1
command=Sequence[nextNr];// nextNr beginnt bei 0
2
nextNr++;
Nun steht beim ersten Durchlauf -> command = Sequence[1] also GELB, bzw.
8
Beim zweiten Durchlauf -> command = Sequence[2] also GRUEN, bzw. 2
Beim dritten Durchlauf -> command = Sequence[3] also BLAU, bzw. 4
Die If Bedingung "if( command & ROT )" verstehe ich nicht recht.
1. Warum vergleiche ich generell command mit Rot?
2. Die Syntax mit dem einzelnen & ist mit nicht geläufig:
Ich kenne es nur mit if( command == 1 && ROT == 1)
3. Welche Werte werden hier verglichen?
Eigentlich könnte ich ja eine Funktion schreiben welche die 4 LEDs
leuchten lässt und diese im Code aufrufen.
1
voidtest()
2
{
3
PORTB|=(1<<PB2);
4
// ...
5
}
======
Kann ich mit UART direkt das string Array im Code verändern?
Ich dachte per UART kann Daten im EEPROM lesen und schreiben, aber nicht
direkt im Quelltext.
Der &-Operator ist ein logisches Und. Wenn also command = ROT | GELB =
0b00001001 ist, steht da:
1
if((0b00001001&0b00000001)!=0)
0b00001001 & 0b00000001 ergibt 0b00000001. Das ist ungleich Null und
damit wird die LED eingeschaltet. Die Bedingung prüft also, ob das Bit
für die rote LED gesetzt ist.
El Nino schrieb:> Kann ich mit UART direkt das string Array im Code verändern?> Ich dachte per UART kann Daten im EEPROM lesen und schreiben, aber nicht> direkt im Quelltext.
Nein, natürlich nicht. Im Quelltext stehen nur die initialen Werte, die
in den Speicher geladen werden sollen, wenn das Programm startet (also
wenn Du den Mikrocontroller mit Strom versorgst). Den Inhalt des
Speichers kannst Du ändern, während das Programm läuft. Zum Beispiel,
wenn per UART Daten empfangen werden:
1
uint8_tc=uart_getc();
2
...
3
Sequence[x]=c;
Damit hast Du die den Ablauf der LEDs verändert.
Wenn das Array Sequence im SRAM ist, wird es bei jedem Start des
Mikrocontrollers wieder mit den Werten initialisiert, die im Quelltext
stehen. Wenn die Werte erhalten bleiben sollen, wenn der Mikrocontroller
keinen Strom mehr hat, musst das Array statt im SRAM im EEPROM liegen.
Dann bleiben die Werte, die Du zuletzt per UART empfangen und im EEPROM
gespeichert hast beim nächsten Start bestehen. Was als Initialisierung
im Quelltext stand spielt dann keine Rolle mehr.
Dennis Heynlein schrieb:> schreibs doch so:>>> if( nextNr == lenSequence )> {> nextNr = 0;> }>> PORTC &= ~(1<<PC1);> PORTC &= ~(1<<PC2);> PORTC &= ~(1<<PC3);> PORTC &= ~(1<<PC4);
Danke nun rühren sich die LEDs. :-)
Nun müsste doch die Abfolge vom Quellcode ausgegeben werden, oder?
1
uint8_tSequence[]=
2
{
3
ROT,
4
GELB,
5
GRUEN,
6
BLAU,
7
KEINE,
8
ROT|GELB,
9
GRUEN|BLAU,
10
KEINE,
11
GRUEN,
12
KEINE,
13
BLAU
14
};
Aber bei mir wird folgendes ca. 18 Mal ausgegeben und anschließend eine
andere Folge. ??
ROT (Eine LED leuchtet)
ROT GRUEN (2 LEDs leuchten)
ROT GRUEN BLAU (3 LEDs leuchten)
ROT GRUEN BLAU GELB (4 LEDs leuchten)
Ist das so korrekt?
Und wie bekomme ich nun das Sequence Array in den EEPROM?
Muss ich nun eine Applikation beispielsweise in C# schreiben um mittels
UART diesen zu beschreiben? Falls ja, hat hier jemand ein Codebeispiel?
Danke für die tolle Unterstützung.
Um nochmal auf die Ausgangsfrage zurückzukommen, möglich ist es schon
aber meiner Meinung nach alles andere als trivial. Als Anhang mal ein
Screenshot von meinem aktuellen Projekt (allerdings für Linux und in C),
mit dem das Erstellen von solchen (Ablauf-)Programmen sozusagen zum
"Kinderspiel" wird.
Mit der Schaltfläche "Schreiben" wird ein Hexfile bestehend aus einem
Interpreter und dem dazugehörigen Datenblock erzeugt und mittels
anpassbarem Script automatisch in den Controller programmiert.
Jörg
Joerg Wolfram schrieb:> Mit der Schaltfläche "Schreiben" wird ein Hexfile bestehend aus einem> Interpreter und dem dazugehörigen Datenblock erzeugt und mittels> anpassbarem Script automatisch in den Controller programmiert.
Fang jetzt bitte keine 2.te Baustelle an.
Er soll jetzt erst mal grundlegend Programmieren lernen.
Danach 1 Byte per UART übertragen (SEnder ist zb hTerm)
Danach mehrere Bytes.
Dann ein Protokoll mit welchem er eine Bytesequenz ins SRAM übertragen
kann.
Dann meinetwegen erst mal ein PC-Programm mit einer GUI, das ihm erlaubt
die Steuersequenz zusammenzustellen.
Dann das ganze ins EEPROM und beim Programmstart aus dem EEPROM holen.
Alleine damit dürfte er gut und gerne ein halbes Jahr beschäftigt sein.
Nino K. schrieb:> Aber bei mir wird folgendes ca. 18 Mal ausgegeben und anschließend eine> andere Folge. ??>> ROT (Eine LED leuchtet)> ROT GRUEN (2 LEDs leuchten)> ROT GRUEN BLAU (3 LEDs leuchten)> ROT GRUEN BLAU GELB (4 LEDs leuchten)>> Ist das so korrekt?
Nein. Ist nicht korrekt. Sieh dir die Abfolge im Array an. Die ist
komplett anders.
> Und wie bekomme ich nun das Sequence Array in den EEPROM?
Eines nach dem anderen.
Das Schlechteste was du jetzt tun kannst, ist weitere Baustellen
aufzumachen. Bring erst mal das was du hast zum Laufen.
Fang halt erst mal mit einer einfacheren Sequenz an.
Haste mal nen Schaltplan ?
Nicht das es bei dir Invers läuft.
Pin(Out) ---|<|--- [VCC]
Pin(Out) ---|<|--- [GND]
Pin(Out) ---|>|--- [VCC]
Pin(Out) ---|>|--- [GND]
sind so die ersten Möglichkeiten.
Habe mich nun ausführlich mit meinem Programm beschäftigt deswegen komme
ich erst jetzt zum Schreiben. Habe mir ein Display an den ATmega168
rangehängt um ein paar Werte zu kontrollieren, da ich keinen JTAG zum
debuggen habe. Damit konnte ich schon mal etwas Fehlersuchen.
Ich habe nun das Programm zum Laufen bekommen. Aber nur teilweise.
Vielleicht kann mir jemand helfen, das gewollte umzusetzen.
Ich musste das Array in die Main Funktion holen, sonst leuchten einfach
alle LEDs permanent. Wenn ich im Array noch einen Wert hinzufüge, dann
leuchten wieder alle LEDs permanent. Mit 4 Werten im Array läuft die
eingestellte Blinkfolge ROT,GELB,GRUEN,BLAU wie gewünscht in einer
Endlosschleife. Aber ein größeres Array geht nicht.
(z.b.:ROT,GELB,GRUEN,BLAU,GELB)
Hier der Code welcher mit einem 4er Array super funktioniert:
1
#define KEINE 0x00
2
#define ROT 0x01
3
#define GRUEN 0x02
4
#define BLAU 0x04
5
#define GELB 0x08
6
7
#define F_CPU 14745600
8
9
#include<stdio.h>
10
#include<math.h>
11
12
#include<avr/io.h>
13
#include<avr/interrupt.h>
14
#include<avr/pgmspace.h>
15
#include<inttypes.h>
16
#include<util/delay.h>
17
18
19
// PIN DEFINITIONS:
20
21
// ### Other LEDs ###
22
// ------------------
23
// PC1 -- LED Green
24
// PC2 -- LED Yellow
25
// PC3 -- LED Blue
26
// PC4 -- LED Red
27
28
// Global Variables
29
30
uint8_tnextNr;
31
uint8_tcommand;
32
33
34
intmain(void){
35
36
// start up the LCD
37
lcd_init();
38
lcd_home();
39
40
DDRC=0b00011110;// Pinc.1,2,3,4 as Output, the Rest as Input
Lass außerdem alle Includes weg, die Du nicht brauchst: math.h,
interrupt.h und pgmspace.h werden im Code nicht gebraucht. Dafür fehlt
vermutlich eine lcd.h oder ähnliches. Am besten lässt Du die
LCD-Routinen erstmal weg.
Dein F_CPU sieht auch nicht ganz koscher aus. Da muss die tatsächliche
Taktfrequenz des Mikrocontrollers stehen.
Und schalte die Compilerwarnungen an (-Wall) bzw. beachte sie!