Hallo zusammen
Über eine SPI Schnittstelle möchte ich 10 empfangene Bytes abspeichern.
Sie sind paarweise angeordnet, bestehend aus einem Address Byte gefolgt
von einem Data Byte die ich in Temp0 bis Temp9 zwischenspeichere.
1
voidReceive_Bytes(void)
2
{
3
while(!(SPSR&(1<<SPIF)));
4
Temp[X]=SPDR;
5
6
for(x=0;x<10;x++);
7
}
Jetzt kommt meine Frage.
Wie kann man aus einer Reihe von gespeicherten Bytes (Temp0 bis Temp9)
einen bestimmten Wert suchen und das darauf folgende Data Byte
speichern?
Beispiel: Temp3 beinhaltet das gesuchte Address Byte, folglich ist Temp4
das Data Byte das zur Weiterverarbeitung gebraucht wird:
Ich kann aus deiner Beschreibung nicht nachvollziehen, was Du möchtest.
Estelle erst mal eine PAP und wenn dieser die Funktion erfüllt, dann in
der Programmiersprache umsetzten.
Firebird schrieb:> Ist das so denkbar?
Denkbar ist vieles.
Warum probierst du nicht ein paar Alternativen aus und siehst dir an,
welcher Code
a) funktioniert
b) dir vom grundsätzlichen Aufbau her am meisten zusagt?
Du kannst wochenlang dir Vorträge über Bildkomposition ansehen und Malen
nach Zahlen betreiben und Kritiker fragen, wie sie Bilder malen würden.
Wenn du aber Bilder malen willst, dann kommst du nicht umhin Bilder zu
malen. Selbst wenn sich dann rausstellt, dass deine Idee nicht so toll
war und du was anderes probieren solltest.
Nur Mut!
Das ist wie Radfahren lernen. Es führt kein Weg daran vorbei, dass man
auch mal auf die Schnauze fällt. Das gehört zum Lernprozess genauso
dazu.
Im Augenblick findest du auch DataBytes als Adressen, wenn du mit
Einerschritten durch das Array gehst.
Ist da eine struct nicht besser?
Wenn du Variablen wie DataByte1, DataByte2, DataByte3 hast, die alle vom
selben Typ sind, nimm ein Array.
Firebird schrieb:> Vielen Dank für die Anregungen. Ich habe einiges Nachgelesen und bin auf> folgende Lösung gekommen. Ich werde den Code ausprobieren und testen.>>
1
voidreceive_bytes(void)
2
>{
3
>for(i=0;i<10;i++);
4
>
5
>while(!(SPSR&(1<<SPIF)));
6
>temp[i]=SPDR;
7
>}
Das wird aus dem Funktionsprinzip von SPI heraus nicht funktionieren.
Das andere Ende der SPI Kette kann nur übertragen, wenn der Sender ein
Byte sendet. D.h. du musst selbst an SPDR etwas Zuweisen um die
Übertragung in Gang zu setzen.
Und dann schau dir nochmal an, wie die Syntax von for-Schleifen ist und
wo das mit dem Strichpunkt zur abhängigen Anweisung in den Schleifen
ist.
>
1
voidsearch(void)
2
>{
3
>for(i=0;i<10;i++);
4
>
5
>AddrByte=temp[i]
6
>
7
>switch(AddrByte)
8
>{
9
>case36:
10
>DataByte1=temp[i+1];
11
>break;
12
>case37:
13
>DataByte2=temp[i+1];
14
>break;
15
>case38:
16
>DataByte3=temp[i+1];
17
>break;
18
>default:
19
>break;
20
>}
21
>}
Und was, wenn in den Daten selbst ein 36, 37 oder 38 steckt?
Wenn in deinen Daten immer Abwechselnd das Steuerbyte und das Datenbyte
steckt, dann genügt es, wenn du immer nur jedes 2.te Byte testest. Wobei
- genügen ist zu viel gesagt. Du willst eigentlich nur jedes 2.te
Steuerbyte testen.
Karl Heinz Buchegger schrieb:> Das wird aus dem Funktionsprinzip von SPI heraus nicht funktionieren.> Das andere Ende der SPI Kette kann nur übertragen, wenn der Sender ein> Byte sendet. D.h. du musst selbst an SPDR etwas Zuweisen um die> Übertragung in Gang zu setzen.> Und dann schau dir nochmal an, wie die Syntax von for-Schleifen ist und> wo das mit dem Strichpunkt zur abhängigen Anweisung in den Schleifen> ist.
Hier sind meine Anpassungen wobei ich nicht sicher bin ob "SPDR = 0" am
richtigen Ort ist.
1
voidreceive_bytes(void)
2
{
3
SPDR=0;
4
5
for(i=0;i<10;i++)
6
{
7
while(!(SPSR&(1<<SPIF)));
8
temp[i]=SPDR;
9
}
10
}
> Und was, wenn in den Daten selbst ein 36, 37 oder 38 steckt?> Wenn in deinen Daten immer Abwechselnd das Steuerbyte und das Datenbyte> steckt, dann genügt es, wenn du immer nur jedes 2.te Byte testest. Wobei> - genügen ist zu viel gesagt. Du willst eigentlich nur jedes 2.te> Steuerbyte testen.
Hier habe ich die for-Schleife angepasst, sodass jedes 2te Byte getestet
wird. Es ist durchaus möglich, dass bei den Daten selbst ein 36, 37 oder
38 steckt. Nach meinen Überlegungen müsste das keinen Einfluss haben,
denn wenn AddrByte ein 36 ist so wäre temp[i+1] das DataByte mit 36.
Ich denke es wird sich heraustellen ob das in der Praxis funktioniert.
Ich bewundere ja Dein Gottvertrauen, daß alles wie von Geisterhand Bit-
und Bytesynchron ist.
Als Master sollte man ja wenigstens mit /SS = 0 dem Slave Bescheid
geben, wann die Daten beginnen.
Hellseher-ICs habe ich noch in keinem Datenbuch gefunden.
Peter Dannegger schrieb:> Ich bewundere ja Dein Gottvertrauen, daß alles wie von Geisterhand Bit-> und Bytesynchron ist.
Nicht nur dieses.
Ich bewundere auch das Gottvertrauen, dass man ohne zu testen als
Anfänger haufenweise Code schreiben könnte, der funktioniert.
So wie das aussieht, ist die Übertragung überhaupt noch nie getestet
worden, und er macht sich Sorgen darüber ob er einen switch-case oder
doch ein paar if nehmen sollte.
Peter Dannegger schrieb:> Ich bewundere ja Dein Gottvertrauen, daß alles wie von Geisterhand> Bit-> und Bytesynchron ist.>> Als Master sollte man ja wenigstens mit /SS = 0 dem Slave Bescheid> geben, wann die Daten beginnen.> Hellseher-ICs habe ich noch in keinem Datenbuch gefunden.
Synchronisiert wird mit einer 8ms Pause zwischen gesendeten Bytes, d.h.
aufeinander folgende Kommandos (bestehend aus Address Byte und Data
Byte) müssen innerhalb oder ausserhalb 8ms gesendet werden. Tritt eine
Pause ein wird neu synchronisiert.
Firebird schrieb:> müssen innerhalb oder ausserhalb 8ms gesendet werden.
Was denn nun?
Aus Erfahrung kann ich Dir sagen, Zeit gesteuerte Protokolle sind weder
einfach noch zuverlässig.
Im Profibereich nimmt man daher Daten gesteuerte Protokolle. Diese
lassen sich auch leicht über andere Medien tunneln.
Zeitabhängigkeiten gehen aber über andere Medien verloren.
Bevor Du die Daten auswertest, mußt Du erstmal das Protokoll
implementieren.
Wie willst Du sonst wissen, daß die Daten korrekt sind.
Du versuchst hier, zuerst das Dach zu bauen, aber ohne die Seitenwände
fällt es immer wieder runter.
Karl Heinz Buchegger schrieb:> Peter Dannegger schrieb:>> Ich bewundere ja Dein Gottvertrauen, daß alles wie von Geisterhand Bit->> und Bytesynchron ist.>> Nicht nur dieses.> Ich bewundere auch das Gottvertrauen, dass man ohne zu testen als> Anfänger haufenweise Code schreiben könnte, der funktioniert.>> So wie das aussieht, ist die Übertragung überhaupt noch nie getestet> worden, und er macht sich Sorgen darüber ob er einen switch-case oder> doch ein paar if nehmen sollte.
Ja, ich bin Anfänger und es stimmt, ich habe den Code noch nicht
getestet. Mir fehlte (oder fehlt) der Teil "Byte Wert suchen und
Folgebyte speichern".
Peter Dannegger schrieb:> Firebird schrieb:>> müssen innerhalb oder ausserhalb 8ms gesendet werden.>> Was denn nun?>> Aus Erfahrung kann ich Dir sagen, Zeit gesteuerte Protokolle sind weder> einfach noch zuverlässig.> Im Profibereich nimmt man daher Daten gesteuerte Protokolle. Diese> lassen sich auch leicht über andere Medien tunneln.> Zeitabhängigkeiten gehen aber über andere Medien verloren.>> Bevor Du die Daten auswertest, mußt Du erstmal das Protokoll> implementieren.> Wie willst Du sonst wissen, daß die Daten korrekt sind.> Du versuchst hier, zuerst das Dach zu bauen, aber ohne die Seitenwände> fällt es immer wieder runter.
Die Daten die ich empfangen und lesen möchte kommen von der SUSI
Schnittstelle. Die Spezifikation findet man hier:
http://www.d-i-e-t-z.de/jd/plaene/SUSI_310.zip
Hier ist der Sourcecode denn ich bis jetzt erstellt habe.
Firebird schrieb:> Ja, ich bin Anfänger und es stimmt, ich habe den Code noch nicht> getestet. Mir fehlte (oder fehlt) der Teil "Byte Wert suchen und> Folgebyte speichern".
Dir fehlt zuallerst mal der Teil:
kriege ich überhaupt die Daten rüber!
Zuallererst musst du die Daten mal da haben, ehe du sie auswerten
kannst.
Und genau diesen Teil kann man völlig unabhängig von irgendwelchen
Auswertungen schon mal programmieren und testen.
Denn wenn deine 10 Bytes schon nicht korrekt sind, dann kannst du
auswerten und suchen bis du (bzw. der Prozessor) schwarz wird. Aus
falschen Daten kann auch die beste Suche nichts gescheites mehr machen.
Daher muss dieser Teil, die Übertragung von 10 Bytes, 100% zuverlässig
funktionieren. Und zwar noch bevor du dir um irgendwelche Suchstrategien
auch nur irgendwelche Gedanken machst.
> Mir fehlte (oder fehlt) der Teil "Byte Wert suchen und> Folgebyte speichern".
Den Teil brauchst du noch nicht, wenn deine erste Teilaufgabe lautet: 10
Bytes korrekt zu empfangen.
Wie überprüfe ich ob die Übertragung von 10 Bytes korrekt und 100%
zuverlässig funktioniert?
Ich sehe die Möglichkeit nach dem Empfang von 10 Bytes eine LED toggeln
zu lassen und vielleicht zusätzlich eine LED toggeln zu lassen wenn der
ISR ausgelöst wird. Wie macht man das Toggeln der LEDS sichtbar bei so
hoher Datenübertragungsrate?
Ich würde erstmal die Synchronisation implementieren und dann z.B. 100
Byte in ne FIFO einlesen und über die UART an den PC ausgeben.
Wie kann man sich nur so ein bescheuertes Protokoll ausdenken.
Peter Dannegger schrieb:> Ich würde erstmal die Synchronisation implementieren und dann z.B.> 100> Byte in ne FIFO einlesen und über die UART an den PC ausgeben.>
Verstehe ich das richtig? Es braucht ein Code um z.B. 100 Bytes zu
senden, mit ensprechender Hardware? Und der Synchronisationscode so
erweitern, dass die empfangenen Bytes über UART an den PC gesendet
werden?
Es mag Experten geben, die schreiben gleich richtigen Code.
Alle anderen müssen debuggen und da ist das einfachste die UART.
Man empfängt also einige Daten und guckt sie sich dann an, ob die was
Sinnvolles ergeben oder nur Zufallszahlen.
Sehen die Daten o.k. aus, kann man dann die Auswertung programmieren.
Hallo zusammen
Ich habe die SUSI Schnittstelle aufgebaut (mit MySmartControl), wobei
eine grüne LED leuchten soll wenn ein gültiger Wert empfangen wurde und
ausgehen soll wenn ein anderer Wert empfangen wurde:
LED an wenn addr = 0x60 und value = 0x04
LED aus wenn addr = 0x61 und value = 0x04
Die Logik habe ich mir so angedacht:
Empfange erster Byte und speichere in "addr".
Empfange zweiter Byte und speichere in "value1".
Prüfe ob "addr" ein 2 Byte Commando.
Wenn ja, dann "SUCCESS" und führe "susi_decode" aus.
Wenn nein, dann empfange dritter Byte und speichere in "value2".
Prüfe ob "addr" ein 3 Byte Commando ist.
Wenn ja, dann "SUCCESS" und führe "susi_decode" aus.
Die Timer Routine setzt TransmitState auf 0x00 zurück wenn innerhalb 7ms
nichts empfangen wird.
Leider Funktioniert der Code nur teilweise.
Wenn ich in der "main" Funktion unter "case SUCCESS" ein LED leuchten
lasse, dann leuchtet die LED auf.
Auch wenn ich in der Funktion "spi_check_data" anstelle von "return
SUCCESS" ein LED leuchten lasse scheint es zu funktionieren.
Sobald "susi_decode" einbringe, dann leuchtet nur die rote LED.
Irgendwo ist der Wurm drin und ich kann den Fehler einfach nicht
entdecken.
Ich bitte um Unterstützung.
>DDRB|=(1<<PB2)|(1<<PB3)|(1<<PB5);// Set SS, MOSI and SCK input
2
>
Input?
Das ist aber nicht Input.
Alles in allem:
zuviel Code auf einmal und das ganze ohne vernünftige Debug-Möglichkeit.
Eine einzelne LED ist da m.M. zu wenig. Ein Blick auf die konkreten
Zahlenwerte, wie man ihn mit LCD oder UART bekommt, ist hingegen Gold
wert.
Karl Heinz Buchegger schrieb:>>> DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5); // Set SS, MOSI and SCK input>>> Input?> Das ist aber nicht Input.>> Alles in allem:> zuviel Code auf einmal und das ganze ohne vernünftige Debug-Möglichkeit.> Eine einzelne LED ist da m.M. zu wenig. Ein Blick auf die konkreten> Zahlenwerte, wie man ihn mit LCD oder UART bekommt, ist hingegen Gold> wert.
Ich bekomme es nicht zum laufen. Auch der stark vereinfachte Code läuft
nicht, d.h. die LED geht willkürlich an nach einigen Sekunden, teilweise
gar nicht.
Ich befürchte, dass meine Kenntnisse auch nicht reichen um den Code
hinzubekommen um die Zahlenwerte über UART an den PC zu senden.
1. Da fehlt ein ";" hinter der while()
2. Die funktion soll was empfangen... das schließe ich aus dem Kommentar
und dem Namen der funktion. Warum gibts du da einen Wert rein? Zum
zurücksetzen des Empfangs-Registers? Lies mal das Datenblatt!
Grüße
Kaj schrieb:> 1. Da fehlt ein ";" hinter der while()
Full ACK
> 2. Die funktion soll was empfangen... das schließe ich aus dem Kommentar> und dem Namen der funktion. Warum gibts du da einen Wert rein? Zum> zurücksetzen des Empfangs-Registers? Lies mal das Datenblatt!
Das kann schon Sinn machen. SPI ist ja eigentlich weniger ein Senden und
Empfangen sondern mehr ein 'Austauschen von Bytes', wobei der Master die
Kontrolle über Zeitpunkt und Geschwindigkeit behält. Irgendwie muss ja
der Slave ja auch die Möglichkeit haben eine angeforderte Antwort an den
Master zurückzugeben.
ok, bei ihm spielt das jetzt noch keine Rolle, soweit ich das sehen
kann. Aber im allgemeinen Fall macht es schon Sinn, wenn der Slave einen
Wert ins SPDR geben kann, welches sich dann der Master mit der nächsten
Übertragung abholt.
Karl Heinz Buchegger schrieb:
> Das kann schon Sinn machen
STOP! Ich nehm alles zurück! Hab nur die hälfte gelesen, hab das spi
ignoriert. :(
Mein fehler. Bei SPI macht es natürlich sinn. war gedanklich irgendwie
mehr bei u(s)art :/
Hallo zusammen
Unterdessen habe ich mir die u(s)art Routine zu Gemüte geführt und ein
Programm aus dem Tutorial basierend zum laufen gebracht :-)
Als Terminal Programm habe ich HTerm verwendet.
Theoretisch müsste ich jetzt die Routine
1
// Zeichen empfangen
2
uint8_tuart_getc(void)
3
{
4
while(!(UCSRA&(1<<RXC)));// warten bis Zeichen verfuegbar
5
returnUDR;// Zeichen aus UDR an Aufrufer zurueckgeben
6
}
durch eine SPI Empfangsroutine ersetzen und den Code entsprechend
ergänzen.
Ich hoffe ich bin auf dem richtigen Weg ;-)
Hallo zusammen
Ich habe es fertig gebracht über die SUSI Schnittstelle Daten zu
empfangen. Im Terminal Programm kommen die Daten reingeschossen und die
grüne sowie rote LED gehen an wenn das entsprechende Byte empfangen
wurde.
Leider macht die Reihenfolge der Bytes und der grösste Teil der Werte
keinen Sinn. Mein Verdacht ist, dass die Synchronisation nicht
sinngemäss funktioniert.
Habt ihr eine Idee woran es liegen könnte?
Anbei der aktuelle Code:
1
#include<avr/io.h>
2
#include<stdlib.h>
3
#include<avr/interrupt.h>
4
5
/*
6
UART-Init:
7
Berechnung des Wertes für das Baudratenregister
8
aus Taktrate und gewünschter Baudrate
9
*/
10
11
#ifndef F_CPU
12
/*
13
In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
14
F_CPU im Makefile definiert werden, eine nochmalige Definition
15
hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
16
#ifndef/#endif
17
18
Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio
19
verwendet wird und dort eine andere, nicht zur Hardware passende
20
Taktrate eingestellt ist: Dann wird die folgende Definition
21
nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?)
22
von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
23
noch nicht definiert: */
24
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
25
#define F_CPU 3686400UL // Systemtakt in Hz - Definition als unsigned long beachten
26
// Ohne ergeben sich unten Fehler in der Berechnung
So, da hab ich doch mal wieder direkt ne verständnis frage, nicht direkt
an dich Firebird, sondern mehr so an die allgemeinheit:
Warum berechnest du/ihr die Baudrate? Im Datenblatt steht doch was man
in UBRR reinschreiben muss um die gewünschte Baudrate einzustellen?!
Wozu dann sowas?
da kommt bei mir 25,5416666.... raus.
Einmal ins Datenblat geschaut: Ohhh, welch wunder, da steht man muss
eine 25 in UBRR reinschreiben wenn man bei 4MHz fosc eine baudrate von
9600 haben möchte...
Wenn man ins Datenblatt schaut und sieht das Wert, den man in UBRR
schreiben muss, nicht größer als 255 ist, kann man sich das Shiften
1
UBRRH=UBRR_VAL>>8;
auch sparen und direkt ne 0 rein schreiben.
1
{
2
if(ReceivedByte==0x60)// Grüne LED an
3
4
PORTC|=(1<<PC2);
5
6
if(ReceivedByte==0x01)// Rote LED an
7
8
PORTC|=(1<<PC1);
9
}
Die geschweiften Klammern sind da völlig unnötig.
Ja, ich weiß, Dukatenscheißerei, aber mal ehrlich: die µC Hersteller
werden das nicht ins Datenblatt schreiben damit man das nochmal
ausrechnet, weil man es ja doch besser weiß.
Sind immerhin mind. 10 Zeilen unnötiger Code, meiner Meinung nach.
Zurück zum Thema:
Für was ist der Timer da? Ich sehe das du den Initialisierst und an
allen möglichen Stellen zurück setzt... aber für was?
Was ich ebenfalls noch nicht verstehe:
1
uart_putc();
2
3
----------------------------------------
4
uint8_tuart_putc(void)
5
{
6
while(!(UCSRA&(1<<UDRE)));// warten bis Senden moeglich
7
8
UDR=ReceivedByte;
9
returnUDR;
10
}
Vielleicht solltest du ReceivedByte auch an die Funktion übergeben.
Mit so "global/ über Funktionsgrenzen hinweg" usw, wäre ich immer
vorsichtig. nur weil es so Funktionieren mag, heißt das nicht, das es
auch richtig ist.
Und warum gibt die Funktion nach dem Senden den Wert von UDR zurück, den
du aber nirgends auffängst?!
Kaj schrieb:> So, da hab ich doch mal wieder direkt ne verständnis frage, nicht direkt> an dich Firebird, sondern mehr so an die allgemeinheit:> Warum berechnest du/ihr die Baudrate? Im Datenblatt steht doch was man> in UBRR reinschreiben muss um die gewünschte Baudrate einzustellen?!
Weil es wesentlich einfacher ist, bei einem Wechsel der Baudrate
und/oder der Taktfrequenz ganz einfach die Werte anzugeben die man hat:
die gewünschte Baudrate bzw. die tatsächliche Taktfrequenz.
Oder willst du bei jedem Wechsel bzw. bei jedem neuen Programm erneut
wieder im Datenblatt dir den Wert raussuchen, der ins Register
geschrieben werden muss? Da ist es doch viel einfacher, wenn der
Compiler den Wert ganz einfach ausrechnet.
> Wenn man ins Datenblatt schaut und sieht das Wert, den man in UBRR> schreiben muss, nicht größer als 255 ist, kann man sich das Shiften>
1
>UBRRH=UBRR_VAL>>8;
2
>
> auch sparen und direkt ne 0 rein schreiben.
UBRR_VAL ist letzten Endes eine Konstante, die der Compiler kennt. Halte
Compilerbauer nicht für blöd, so etwas wegzuoptimieren ist eine triviale
Aufgabe für jeden Studenten im ersten Semester Compilerbau.
> Die geschweiften Klammern sind da völlig unnötig.
Sie schaden aber auch nicht.
> Ja, ich weiß, Dukatenscheißerei, aber mal ehrlich: die µC Hersteller> werden das nicht ins Datenblatt schreiben damit man das nochmal> ausrechnet, weil man es ja doch besser weiß.
Es geht nicht ums besser wissen.
Die µC-Hersteller haben das auch nur ausgerechnet.
Die Tabellen haben ihre Berechtigung, wenn man eine
Baudraten/Taktfrequenz Kombination sucht, die möglichst wenig
prozentualen Fehler produziert.
> Sind immerhin mind. 10 Zeilen unnötiger Code, meiner Meinung nach.
Völliger Quatsch.
Nur weil du etwas in den Code schreibst, heißt das noch lange nicht,
dass das dann auch im fertigen Programm auftaucht. Constant Folding ist
für Compilerbauer eine Fingerübung.
Letzten Endes bleibt im Programm, welches auf den µC gebrannt wird, auch
nur eine Zuweisung eines Zahlenwertes an das Register übrig. Einziger
Unterschied: du hast dir als Programmierer das raussuchen aus dem
Datenblatt erspart, weil der Compiler die Werte ausgerechnet hat. Mit
genau den gleichen Formeln, mit der auch die Tabellen im Datenblatt
erzeugt wurden.
> Für was ist der Timer da? Ich sehe das du den Initialisierst und an> allen möglichen Stellen zurück setzt... aber für was?
Um ein Timeout zu realisieren.
Kaj schrieb:> Für was ist der Timer da? Ich sehe das du den Initialisierst und an> allen möglichen Stellen zurück setzt... aber für was?
Gemäss SUSI Spezification müssen aufeinanderfolgende Bytes schneller als
7ms gesendet werden. Eine Pause von 8ms +/- 1ms wird benutzt um zu
Synchronisieren.
http://www.d-i-e-t-z.de/jd/plaene/SUSI_310.zip
Der Timer zählt bis 7ms hoch und sollte bei jedem empfangenem Byte
zurüchgesetzt werden, vor 7ms erreicht wird. Wird 7ms erreicht so soll
Synchronisiert werden, d.h. die Byte Reihenfoge wieder in Takt sein.
Firebird schrieb:> #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit> 4000000"> #define F_CPU 3686400UL
Das Leben steckt voller selbstgestellter Fallen...
Oliver
Hallo zusammen
Ich habe die Timer2 und UART Einstellungen nochmals mit dem Atmega8
Datenblatt verglichen und kann keine Fehler erkennen. Trotzdem erhalte
ich nicht die Werte die von der Zentrale über den Decoder gesendet
werden.
Für Adresse 0x60 ist der Wert 0x01 eingestellt, für Adresse 0x61 der
Wert 0x00. Am Terminal (HTerm) kommen folgende Werte an:
Adresse 0x60, Wert 0x43 (falsch)
Adresse 0x60, Wert 0x01 (Zufällig korrekt)
Adresse 0x60, Wert 0xA5 (falsch)
Adresse 0x61, Wert 0x51 (falsch)
Adresse 0x61, Wert 0x53 (falsch)
Ich vermute, dass einige Bytes nicht erfasst werden oder irgenwie
verloren gehen. Jetzt komme ich nicht mehr weiter und bitte um einen
Hinweis damit ich einen Schritt weiter komme.
Mit freude stelle ich fest, dass der Code tatsächlich funktionieren
würde.
Per Zufall stellte ich fest, dass die Bytes schneller empfangen werden
wenn ich mit einem Finger in die Nähe von PORTB komme. Wenn ich mit
einer Pinzette PINB1 berühre kommen die Daten reingeschossen und werden
am PC korrekt angezeigt. PINB0 und PINB2 haben keinen Einfluss beim
Berühren.
Die Verdrahtung ist gemäss SUSI Spezifikation korrekt und auch im Code
ist nichts drin das PINB1 (OC1A) beinflussen könnte.
Habt ihr eine Idee wo das Problem liegt?