K-BUS TRanciever Melexis TH3122

Code:
Empfangszaehler = 35

Config Timer0 = Timer , Prescale = 256
Enable Timer0
Stop Timer0
Timer0 = 131
On Timer0 Timer0_isr
On Urxc Uart_isr                                            ' Keine automatische Register-Rettung
Enable Urxc                                                 ' Interrupt (Byte über USART erhalten) enabled

Enable Interrupts


Do

Loop
End

Uart_isr:
   Recieved(empfangszaehler) = Inkey()
   If Delta_timer0ms <= 17 Then                         'gehoert noch zu dieser nachricht
      Decr Empfangszaehler                                  'zaehler um 1 erniedrigen
   End If

   Delta_timer0ms = Timer0_ms + Zeit_vorher
   If Delta_timer0ms > 34 Then                              'abstand war groesser 1,7ms
      Empfangszaehler = 35
   End If
   Zeit_vorher = Timer0_ms
   Timer0 = 131
   Timer0_ms = 0
   Start Timer0
Return

Timer0_isr:                                                 '7812 uebrlaefe sind 1s
   Incr Timer0_ms
   If Timer0_ms > 20 Then
      Timer0_ms = 0
   End If
Return
 
ok ganz kurz, mwenn ich den timer so konfigueire, das er alle 1,7ms einen ueberlauf macht und den empfangszaehler resettet
Code:
Empfangszaehler = 35

Config Timer0 = Timer , Prescale = 256
Enable Timer0
Stop Timer0
Timer0 = 203
On Timer0 Timer0_isr
On Urxc Uart_isr                                            ' Keine automatische Register-Rettung
Enable Urxc                                                 ' Interrupt (Byte über USART erhalten) enabled
Enable Interrupts


Do

Loop
End

Uart_isr:
   Recieved(empfangszaehler) = Inkey()                      'empfangenes abholen
   Decr Empfangszaehler
   Gosub Calc_checksum
Return

Timer0_isr:                                                 'Nach 1,7ms den empfangszaehler wieder nullen= neue nachricht empfangen
   Empfangszaehler = 35                                     '
Return
 
... Watchdog ... äh ... kann man den nicht auf 1,7ms einstellen, und ihn den Bytezähler anbellen lassen (ohne Reset) -> Datenblatt such
Nö, kannste knicken. So richtig schlau werd ich da aus dem Datenblatt nicht - ich vermute, daß der Hund ein 8bit-Zähler/Timer ist dessen Vorteiler diskrete Werte als vielfache von 8 annehmen kann. Mit der WD-Frequenz von 128kHz kommt man dann auf feste Zeiten (ab 16ms aufwärts)
(hmm... wenn man die Bits WDP3..0 in WDTCSR so betrachtet, könnte es theoretisch auch ein 10bit-Timer sein - ändert aber nichts am Resultat, man hat keinen Zugriff auf den eigentlichen Zähler, und 16ms aufwärts sind uns zuviel...)

ok ganz kurz, mwenn ich den timer so konfigueire, das er alle 1,7ms einen ueberlauf macht und den empfangszaehler resettet...
Ja, so in etwa meinte ich das. Allerdings würde ich den Empfangszähler/Bytezähler wahrscheinlich anders gestalten/bewerten - vielleicht mach ich morgen mal ein Struktogramm dazu.
Allerdings ist noch eines zu beachten:
Ein kompletter Durchlauf des Timer0 dauert (Dein Prescaler und so) ca 8.2ms. Beim ersten mal schneidest Du die ersten 203 Schritte ab - dahin müßtest Du bei jedem empfangenen Byte wieder zurücksetzen (vielleicht hast Du das in der checksum-sub getan?) - es macht zwar jetzt keinen großen Unterschied mehr, aber ich würde den Timer im CTC laufen lassen so, daß er bei OCR0A automatisch überläuft. Dementsprechend müßte ich OCR0A mit 52 beladen (genaugenommen irgendwas zwischen 1.4??? und 1.7??? ms), und den Timer bei jedem Empfang auf 0 setzen (so schneide ich eben die oberen 203 Schritte ab)
Hier mal ein Screenshoot von meiner App:
Screenshot_2013-01-19-23-52-28-1.png
Wie dann mit den empfangenen Bytes zu verfahren ist, ist auch noch nicht implementiert - insbesondere fließt ja auch nicht jedes Byte in den Redundanz-Check mit ein...

Grüße
LotadaC

P.S.: Bähh... genug XML unter VisualBasic für heute...
 
bei jedem byte empfang setze ich den timer auf den Start wert zurueck,
=> in der Uart Isr
bei jedem Timer ueberlauf setz ich den empfangszaehler zurueck
=> empfangszaehler = 0

ich bekomm nur die paritaetsprüfung nicht hin
alles wa ich ausprobiere will er nich.. checksum() muesste genau das liefern was ich wil, jedoch muss ich dann mein byte array in einen string umwandeln,.
mit ner
Code:
for i= 0 to 35
string = string + str(recieved(i))
next

macht ers nich ,.
 
Du hast doch in der RxC-ISR Zugriff auf jedes, grad empfangene Byte - Du brauchst also eigentlich nur noch ein (global definiertes) Byte, was Deine Checksumme beim Empfang mitführt. Als Initialwert, und nach Auswertung der Checksumme wird es auf 0 gesetzt, ansonsten wird der Inhalt mit dem frischen Byte verXORt (das Checksum-Byte selbst natürlich nicht). Ob es dafür einen ordentlichen Bascom-Befehl gibt, weiß ich nicht - in ASM heißt er EOR (Exclusive OR). Sei das bisherige CRC-Byte in Rechenregister Rd, das das neue Byte in Rr, dann berechnet "EOR Rd,Rr" die neue Checksumme und schreibt sie nach Rd. Ließe sich in ASM problemlos miteinbauen (das Byte muß ja eh über ein Rechenregister aus dem UDR (UART Data Register) gelesen, und in den Speicher (SRAM-Register) geschrieben werden.
Kannst Du mal eine Auflistung aller (derzeit gewünschten) Telegramme zusammenstellen, die erkannt werden können sollen? Dann kann man sich eher ein Bild davon machen, wie das zum vergleichen im Eeprom abzulegen ist, also ob man das in eine Baumartige Struktur packen sollte, oder einfach alle Telegramme komplett Byteweise hintereinander oder so. Dein Eeprom enthält 128 Register - jedes Telegramm besteht aus 3Bytes-Header (Quelle/Ziel/Länge) und eben den Datenbytes. Außerdem dann jeweils der zu sendende NEC-Code. Wenns nur wenige "gültige" Header-Bytes gibt (relativ zur Gesamtheit aller "gültigen" Telegramme), macht eine "baumartige" Struktur eher Sinn.

Da wir das jetzt sowieso nicht das Telegramm in einen String packen können (und Bascom dann den Vergleich aufhalsen), ist es wahrscheinlich doch sinniger, in der RxC-ISR nur einzelnen Bytes zu empfangen, alles andere in's Hp zu verlagern. Dann ist aber zu beachten, daß zwischen dem Abfragen des Bytezählers und der, sich daraus ergebenden Reaktion(theoretisch) ein weiterer RxC-IRQ ereignet haben könnte - Du also das falsche Byte bearbeiten würdest. Üblicherweise vermedet man sowas, indem man solange die Interrupts unterbindet. Allerdings willst Du hier die NEC-sende-Geschichte am laufen halten. Bliebe also RXCIE. Geht das so? Folgende Situation:
-Interrupts global scharf (I=1)
-RXCIE=0 wegen atomarer Operation
-jetzt wurde ein Byte komplett empfangen (also RXC=1)
-da RXCIE=0 kein IRQ
-nach der atomaren Operation wird der RXC-IRQ wieder freigegeben (RXCIO=1)
-da "I" und RXC ja weiterhin gesetzt sind, sollte doch jetzt die RXC-ISR ausgeführt werden, oder?? (auch, wenn der UART bereits die ersten Bits des nächsten Bytes intus hat (der Zugriff aufs UDR erfolgt ja gepuffert))
 
mh, da die nachrichten ja von nur 2-3 absendern kommen, muesste man ja nur auf die ersten 2-3 prüfen, dann kann man die nachricht ja schon verwerfen!
Code:
'          Quellid|Länge|Zielid|Daten      |XOR
'           1Byte |1Byte|1Byte|bis zu 5Byte| 1 Byte
'vol +         |[B]50[/B]| 04 | 68   | 32    | 11 | 1F
'vol -         |50| 04 | 68   | 32    | 10 | 1E
'Next pressed  |50| 04 | 68   | 3B    | 01 | 06
'next 1s       |50| 04 | 68   | 3B    | 11 | 16
'next re       |50| 04 | 68   | 3B    | 21 | 26
'Prev pressed  |50| 04 | 68   | 3B    | 08 | 0F
'Prev 1s       |50| 04 | 68   | 3B    | 18 | 1F
'Prev re       |50| 04 | 68   | 3B    | 28 | 2F
'SES           |50| 04 | B0   | 3B    | 80 | 5F
'RT wählen dr  |50| 04 | C8   | 3B    | 80 | 27
'RT wählen 1s  |50| 04 | C8   | 3B    | 90 | 37
'RT wählen >1s |50| 04 | C8   | 3B    | A0 | 07
'RT wähl dr aus|50| 04 | C8   | 3B    | 40 | chk
'PDC AN        |[B]3F[/B]| 04 | 60   | 0C    | 80 | D7
'PDC AUS       |3F| 04 | 60   | 0C    | 40 | 17
'FB Schließen  |[B]00[/B]| 04 | bf   | 72    | 16 | df
'FB Öffnen     |00| 04 | Bf   | 72    | 26 | Ef
'licht         |00| 04 | bf   | 76    | 02 | chk

also macht das falls man 1 zeichen erkennt, und man erkennt das es eine zeichenkette ist, kann man gleich auf die 50,. usw prüfen, falls es ungleich ist, dann kann man den empfangszaehler gleich wieder =35 setzen,..
 
Jain...
Wenn Du den Empfangszähler da zurücksetzt, werden die restlichen Bytes dieses Telegrammes einem neuen Telegramm zugeordnet (oder wolltest Du mit dem Vergleich nach dem kompletten Byteempfang beginnen?). Die Wahrscheinlichkeit, daß dieser Rest ein konformes Telegramm ergibt - hab jetzt nicht überschaut, ob das wegen der CRC möglich ist, könnte aber trotzdem sein...
Warum DB bis 5? In der Tabelle sinds immer(!) 2, zulässig wären laut Hemi ja sogar bis zu 32...

Wenn man die nur einfach hintereinander ins Eeprom schreibt, kommt man (mit NEC-Byte statt dem CRC) auf 6*18=108 Speicherregister - wird also ziemlich voll.
Wenn man das strukturiert, könnte es wegen der wenigen verschiedenen Quell-IDs und Längen eventuell sparsamer werden. Auf alle Fälle wird es so einfacher, während des Empfanges bereits mit dem Prüfen anzufangen (in etwa, wie Du angedeutet hast).
Der Aufbau der Struktur kostet natürlich auch Speicherplatz, klar (ein Knoten muß die Anzahl und Adressen seiner Kinder kennen - bei einem Blatt jedoch kann man statt der adresse den NEC ablegen. Bei der Struktur, die ich derzeit wählen würde, wären im worst Case (also alle Bytes verschieden) nur 9 Telegramme drinn. Aber bei Deiner Tabelle siehts schon viel besser aus, denk ich...
 
mh hatte viel um diwe ohren , komme jetzt nich mehr so mit,.

also ablauf:
ints scharf
empfangszaehler=35


zeichen wird empfangen
empfangszaehler-1
timer starten
zeichen verarbeiten
-------------------
zeichen wird empfangen
empfangszaehler-1
ist timer0 <1,7ms?
ja || nein
zeichen verarbeiten || empfangspuffer= 35
-------------------
 
nicht ganz...
Ich würde Deine Tabelle da unten als Suchbaum ins Eeprom schreiben. Dabei enthält jeder Knoten die Anzahl seiner Kinder (1Byte), den wert eines jeden Kindes, sowie dessen Adresse im Eeprom (also 2 weitere Bytes pro Kind). Die Wurzel ist auch ein regulärer Knoten. Die unterste Ebene enthält dann statt der Kind-Adresse je den entsprechenden NEC-Code, der eben auf dem Weg von der Wurzel her festgelegt wird.
Man bräuchte denn einen Zeiger (Pointer) ins Eeprom, der zu beginn eines jeden Telegrammes auf die Wurzel (Adresse 0) zeigt (initial, und bei jedem Timerüberlauf bzw wie auch immer die 1,7ms detektiert werden).
Wenn in der RxD-ISR also ein Byte des Paketes empfangen wurde (und in einer Byte-Variable zwischengepuffert), Kannst Du jetzt dieses Byte mit den Knoten des Baumes vergleichen. Der Pointer zeigt erstmal auf die Anzahl der nötigen Vergleiche. Pointer inkrementieren, Eeprom laden, Pointer nochmal inkrementieren, und die beiden Werte vergleichen. Bei Übereinstimmung zeigt der Pointer auf die Speicherzelle, in der die Adresse des entsprechenden Kind-Knotens steht (also laden, und in den Pointer speichern). Ansonsten springt man zurück zum ersten inkrement. Vorher zählt man aber noch die Zahl der "restlichen" Vergleiche runter (erstes Byte). Wirds dabei 0, ist dieses Byte nicht im (Teil)Baum enthalten, also gibt es auch keinen NEC-Code dazu. Folglich kann das restliche Telegramm ignoriert werden. (Die entsprechende Abfrage muß also vorher erfolgt sein, genauso wie die, ob es sich bei dem Byte um ein Blatt handelt.)
Folgende Informationen müßten also global abgelegt verfügbar sein:
-es ist ein Byte im Puffer (also in der RxD-ISR aus dem UDR in eine Puffervariable geladen worden)
-neue Bytes im Puffer sind zu ignorieren (da somit erst recht nicht das entsprechende Blatt des Zweiges verarbeitet wird, wird somit das ganze restliche Telegramm ignoriert)
-CRC war korrekt (heißt, daß das, empfangene CRC-Byte korrekt war, und somit das Telegramm gültig. Wohin zeigt jetzt aber (also beim Eintritt in die Vergleichsfunktion) der Eeprom-Pointer? Nun, wenn jetzt ein CRC drann war, war das vorherige also der letzte Knoten eines Astes, der Pointer zeigt also jetzt auf die Zelle, in der (statt der Kind-Adresse) bereits der entsprechende NEC-Code abgelegt ist - ist CRC_OK gesetzt, kann also die, durch den Eeprompointer referenzierte Speicherzelle geladen werden, und deren Inhald an sendnec(...) übergeben werden.)
-Da das NEC-senden wesentlich langsamer geht, als das K-Bus-empfangen, macht ggf noch ein NEC_is_ready-Flag Sinn? (wie willst Du verfahren, wenn der NEC grad "ausgelastet" ist?)
Für diese Flags würde ich das General Purpose I/O Register 0 (GPIOR0) verwenden - Bascom ignoriert es mMn, und es bietet den Vorteil, daß seine einzeln abgefragt/manipuliert werden können.

Zum Empfangszähler: Ich kenne die Länge eines Telegrammes erstmal nicht (zumindest gehe ich davon aus). Ich würde als Initialwert (und bei jedem Timerüberlauf) die 255 nehmen. Dann wird der NACH dem Dekrement zu BEGINN der ISR 254.
Wurde der Zähler durch das Dec 0 wird automatisch das Zero-Flag im SREG gesetzt -> können wir zur Überprüfung des CRC nutzen.
Ansonsten wird halt das empfangene Byte in den Puffer gespeichert, das CRC weitergeführt, und das "NeuesByteImPuffer-Flag" im GPIOR0 gesetzt. Ist der Empfangszähler nach dem DEC 253 (also wenn wir grad das Längenbyte empfangen haben), können wir zusätzlich unseren Empfangszähler entsprechend anpassen.
Wir dürfen natürlich kein Byte verlieren - vielleicht macht da ein weiteres Flag Sinn?

Hmm... Das Konzept ist natürlich auch wieder sehr ASM-lastig... Suchfunktion mit dem Baum da oben auch...
 
kannste ein kleines bildchen zeichnen dazu ? mit kind wurzel usw :D?

d.h.
3 wurzeln (3 versch empfanger)->datenbytes als Knoten-> nec codes als kind?
 
sorry, grad nicht viel Zeit...
erstmal ein Bild (das ist aber erstmal nur die Idee - Dein Speicher ist ja in Wirklichkeit eindimensional strukturiert. Initial zeigt Dein "Such-Zeiger" auf den root-Knoten. Wenn ein Zeichen empfangen wurde, vergleichst Du dieses mit den Kind-Knoten (des aktuell indizierten Knotens). Findest Du kein solches Kind, setzt Du ein "Ignore-Flag" für den Rest diese Telegrammes, findest Du ein passendes Kind, setzt Du den "Such-Zeiger" auf die dessen Adresse. Ein Sonderfall liegt bei gesetztem Ignore-Flag vor - da wird einfach nichts weiter gemacht. Ein anderer, wenn das neue Zeichen ein gültiger CRC war. Dafür sollte die Empfangs-ISR ein "CRC-OK-Flag" setzen. In dem Fall wird nicht weiter gesucht, sondern der entsprechende NEC-Code gesendet (da kommen noch einige Feinheiten).
erstmal das Bild:
NEC-tree.png
Im Prinzip durchläuft man den Baum als Suchbaum im "level order" - allerdings mit etwas weniger Gehopse...
Jeder (von den Gelben) Knoten (inklusive Wurzel) kennt die Zahl seiner Kinder, deren jeweilige Werte, und die Adresse im Speicher (wo der entsprechende Teilbaum weitergeht). Die Wurzel beginnt also in Adresse 0x00 im Eeprom, dort ist dann abgelegt:
Code:
0x03       ;Anzahl der Kinder=3
0x50       ;erstes Kind
{lb_0x50}  ;Adresse davon
0x3F       ;zweites Kind
{lb_0x3F}  ;Adresse davon
0x00       ;drittes Kind
{lb_0x00}  ;Adresse davon

...

lb_0x50:   ;Label für root->50
0x01       ;Anzahl der Kinder von root->50 (hier 1)

...
in der untersten (gelben) Ebene ist das dann anders - hier wird die Gültigkeit ja durch den CRC festgestellt - ein eigentliches Kind gibt es nicht. Dort steht eigentlich die Adresse des NEC-Codes. Nunja ... die Adresse ist ein Byte - der NEC-Code ist ein Byte... dann kan man ja auch gleich dort den NEC-Code hinsetzen. Also zB:
Code:
...
           ;Label 
lb_0x50_0x04_0x68_0x32:   
0x02       ;Anzahl der Kinder von root->50->04->68->32 (=2)
0x11       ;erstes Kind
NECByte    ;entsprechendes Byte
0x10       ;zweites Kind
NECByte    ;entsprechendes (anderes) Byte
...
Nach einem verarbeiteten empfangenem Zeichen zeigt der "Such-Zeiger" je dahin, wo eigentlich die Adresse des gefundenen Knotens steht, also hier im Falle der "11" auf die Zelle, in der das entsprechende NECByte steht.
Wurde also ein Zeichen empfange (Neues Zeichen im Puffer), und ist dann das "CRC-OK-Flag" gesetzt, ist kein weiterer Vergleich nötig. es muß dann einfach das Byte aus dem Eeprom geladen werden, auf das derzeit der "Such-Zeiger" zeigt. Dieses Byte ist dann an "sendnec" zu übergeben.

Das Zurücksetzen des "Such-Zeigers" erfolgt beim Timerüberlauf (="Neues-Telegramm-Detektion"), dort ist auch das "Ignore_Flag" zu löschen, und der Bytezähler der Empfangs-ISR zu reinitialisieren... alles neu halt...

Ist jetzt aber alles erstmal nur so zusammengeschrieben -> da muß sicher noch etwas mehr Hirnschmalz rein...

Edit:
Unter ASM gilt:
mit der Direktive ".ESEG" landet der folgende "Code" im Eeprom
wenn dann ein ".org 0x00" folgt, landet der folgende "Code" dann in Eeprom-Register 0x00?
Mit ".db Bytekonstante" kann ich jetzt alle Bytes eintragen (also einzeln bzw durch Kommata getrennt auch mehrere).
Kann man da auch label verwenden? Oder muß man das dann selbst zu Fuß ausrechnen?
(hmm...mal das Studio starten...)

P.S.: Das konzept ist von der Speicherbelegung her noch optimierbar, was Knoten mit nur einem Kind betrifft - allerdings erhöht das den Aufwand im "Such-Algorythmus"...
 
Sorry für den Doppelpost - aber ich möchte das hier von oben abgrenzen...
Hab selbst mal einen Test durchs Studio jagen wollen - kompilieren tuts auch ohne Fehler
Code:
"ATtiny2313" memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x000004      4      0      4    2048   0.2%
[.dseg] 0x000060 0x000060      0      0      0     128   0.0%
[B][.eseg][/B] 0x000000 0x000010      0     [B]16     16     [/B]128  [B]12.5%[/B]
Assembly complete, 0 errors. 0 warnings
im Simulator allerdings:
eepromtest.png
Häh... mal etwas gegurgelt...
mikrocontroller.net schrieb:

Na toll... hab Version 5.1.208 und keinen Platz mehr, um was aktuelleres runterzuladen.
Hat vielleicht mal jemand anders die Möglichkeit, das zu testen? (Dino?)
Ergebnis sollte ja eigentlich sein:
00 00 00 00 0A 0B 00 00 00 00 10 20 00 00 00 00
 
Hi LotadaC,

Na toll... hab Version 5.1.208 und keinen Platz mehr, um was aktuelleres runterzuladen.
Hat vielleicht mal jemand anders die Möglichkeit, das zu testen? (Dino?)
Ergebnis sollte ja eigentlich sein:
00 00 00 00 0A 0B 00 00 00 00 10 20 00 00 00 00
äähhhh ... hab noch nie was mit dem Simulator gemacht :rolleyes:
Ich simuliere immer in der realen Welt ;)
Da müßte ich mich erstmal reinarbeiten.

Hast du keinen Platz mehr zum runterladen oder zum installieren?

Ich hab bei mir allerdings neben dem 4er auch nur das 5.1.208 installiert.
Grad mal nachgesehen.

Gruß
Dino
 
irgendwie hab ich schon probleme wenn ich nur die empfangsroutine testen will ;/
hab im moment recht wenig zeit, und kan mich auch nich sogut reindenken,.
hab mit nem Prog "Virtual Serial Port Emulator" mit die Bytes mit hterm an mein Simuliertes Programm geschickt , allerdings empfange ich nicht alles...
 
so kann ich ueber die simulierte schnittstelle, codes empfangen,. stimmt auch,
allersings muesste ich den code ein bisschen variabler gestalten, nicht immer stimmt die crc position,. usw
Code:
$crystal = 8000000
$regfile = "ATtiny2313.dat"
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 20                                               'default use 10 for the SW stack
$framesize = 20                                             'default use 40 for the frame space
$baud = 9600
$sim

Dim Empfangszaehler As Byte
Dim Serial_flag As Byte
Dim Recieved(35) As Byte

'empfangende daten
Dim Startadress As Byte At Recieved + 1 Overlay
Dim Messagelength As Byte At Recieved + 2 Overlay
Dim Zieladress As Byte At Recieved + 3 Overlay
Dim Data_1 As Byte At Recieved + 4 Overlay
Dim Data_2 As Byte At Recieved + 5 Overlay
Dim Xorbyte As Byte At Recieved + 6 Overlay
Dim Nxor As Byte
Dim Inhaltlength As Byte

Empfangszaehler = 1
Nxor = 0

'Hardware
Config Timer0 = Timer , Prescale = 256                      'Prescale = 256
Enable Timer0
Stop Timer0
Timer0 = 203

'INTs
Enable Interrupts
On Timer0 Timer0_isr

Enable Urxc
On Urxc Uart_isr                                            ' Keine automatische Register-Rettung

'PROGRAMM
Do
If Serial_flag = 1 Then
   While Ischarwaiting() = 1
      Inhaltlength = Messagelength - 1
      Recieved(empfangszaehler) = Inkey()                   'empfangenes abholen

      If Empfangszaehler > 0 And Empfangszaehler < Inhaltlength Then       'es soll ja nur die checksumme bis zur checksumme gebildet werden
         Nxor = Nxor Xor Recieved(empfangszaehler)
         Print "CRC CHeck " ; Hex(nxor)
      End If
      Incr Empfangszaehler
   Wend
   Serial_flag = 0
End If

'nachricht komplett empfangen
If Ischarwaiting() <> 1 And Empfangszaehler > 4 Then
   If Nxor = Xorbyte Then                                   'pausibilitätsprüfung der empfangenenen daten
      Print "CRC Prüfung i.O."
   End If
   'Print Hex(recieved(1)) ; " | " ; Hex(recieved(2)) ; " | " ; Hex(recieved(3)) ; " | " ; Hex(recieved(4)) ; " | " ; Hex(recieved(5)) ; " | " ; Hex(recieved(6)) ; " | " ; Hex(nxor)
End If
Loop
End


'_______________________________________________________________________________
Uart_isr:
   Start Timer0
   Serial_flag = 1
Return

Timer0_isr:
   Stop Timer0
   Timer0 = 203                                             'Nach 1,7ms den empfangszaehler wieder nullen= neue nachricht empfangen
   Empfangszaehler = 1                                      '
Return
 
Hast eigentlich recht - wenn das letzte Byte noch nicht verarbeitet wurde, das nächste aber bereits empfangen ist, gibts eh Probleme. Mehr, als das zu detektieren, hatte ich im RXD-IRQ bisher eh nicht vorgesehen. Dann kann man das eigentlich auch gleich in die Hauptschleife miteinbauen, und dazu das Recieve-complete-Flag pollen (Ischarwaiting).

Deine Verwendung von "Print" ist mir noch nicht ganz klar... das geht doch dann auch über den HW-UART raus. Mit denselben Einstellungen wie beim Empfänger (RXD). Meiner Meinung nach setzt Bascom das nicht irgendwie zusätzlich gepuffert und interruptgesteuert um - Es werden einfach alle Zeichen nacheinander gesendet, wobei zwischendurch immer UDRE-Flag (UART Data Register Empty) gepollt wird. Wenn Du also einen String sendest, wartet das restliche Programm, bis alles raus ist. Wenn der Empfänger bereits ein neues Telegramm empfangen soll, werden Bytes verschluckt.
 
Gut, die print ausgaben kannste ignorieren, die hatte ich wegen der simulation drinne...

also es dazu kommen jetzt die vergleichsdaten, und ein 2tes array mit den geprüften arbeitsdaten?
oder soll ich direkt prüfen, und in nem byte meinen zu senden code zwischenspeichern...
 
so ist der aktuelle stand,.
Code:
$crystal = 8000000
$regfile = "ATtiny2313.dat"
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 20                                               'default use 10 for the SW stack
$framesize = 20                                             'default use 40 for the frame space
$baud = 9600
$sim

Dim Empfangszaehler As Byte
[COLOR="#FF0000"]Dim Serial_flag As Bit At Empfangszaehler + 7 Overlay[/COLOR]
Dim Recieved(35) As Byte
Dim Code(6) As Byte
'empfangende daten
Dim Startadress As Byte At Recieved + 1 Overlay
Dim Messagelength As Byte At Recieved + 2 Overlay
Dim Zieladress As Byte At Recieved + 3 Overlay
Dim Data_1 As Byte At Recieved + 4 Overlay
Dim Data_2 As Byte At Recieved + 5 Overlay
Dim Xorbyte As Byte At Recieved + 6 Overlay
Dim Nxor As Byte
Dim Inhaltlength As Byte
Dim I As Byte
Dim I1 As Byte
Empfangszaehler = 1
Nxor = 0

'Hardware
Config Timer0 = Timer , Prescale = 256                      'Prescale = 256
Enable Timer0
Stop Timer0
Timer0 = 203

'INTs
Enable Interrupts
On Timer0 Timer0_isr

Enable Urxc
On Urxc Uart_isr                                            ' Keine automatische Register-Rettung

'PROGRAMM
Do
  If Serial_flag = 1 Then
     While Ischarwaiting() = 1
        Inhaltlength = Messagelength - 1
        Recieved(empfangszaehler) = Inkey()                 'empfangenes abholen

        If Empfangszaehler > 0 And Empfangszaehler < Inhaltlength Then       'es soll ja nur die checksumme bis zur checksumme gebildet werden
           Nxor = Nxor Xor Recieved(empfangszaehler)
           'Print "CRC CHeck " ; Hex(nxor)
        End If
        Incr Empfangszaehler
     Wend
     Serial_flag = 0
  End If

  'nachricht komplett empfangen
  If Ischarwaiting() <> 1 And Empfangszaehler > 4 Then
     If Nxor = Xorbyte Then                                 'pausibilitätsprüfung der empfangenenen daten
        'Print "CRC Prüfung i.O."
        For I = 3 To Empfangszaehler                        'die ersten 3 bytes werden nicht benoetigt,. sender/empfanger/laenge
           I1 = I - 3
           Code(i1) = Recieved(i)
        Next
     End If
     'Print Hex(recieved(1)) ; " | " ; Hex(recieved(2)) ; " | " ; Hex(recieved(3)) ; " | " ; Hex(recieved(4)) ; " | " ; Hex(recieved(5)) ; " | " ; Hex(recieved(6)) ; " | " ; Hex(nxor)
  End If
Loop
End

das komische ist, im simulatir bekomme ich den aktuellen und richtigen xor angezeigt, sonst jedoch keine empfangenenen daten,.

Das verträgt der Simulator nicht, obwohls keinenen COmpilier Fehler gibt
 
Ist Dir das mit den SRAM-Variablen und Dim und Overlay eigentlich klar?

Der SRAM ist in etwa so organisiert (also nicht wirklich physisch, aber adresstechnisch sind die Bereiche hintereinander "angeordnet"):
- die ersten 32 Register sind die Rechenregister (0x00 bis 0x1F)
-danach die I/O-Register (Zugriff/Konfiguration der peripheren Hardware usw) - beim Tiny2313 sind das 64 Stück, also von 0x20 bis 0x5F
-danach der frei verfügbare SRAM - hier 128 Bytes (Register/Speicherzellen) - von 0x60 bis 0xDF
siehe auch Conroller-Datenblatt S.15

Wenn Du nun in Bascom mit Dim eine Byte-Variable festlegst, weist Bascom dieser den ersten freien Platz im frei verfügbaren SRAM-Bereich zu. Mehrbytige Variablen (Words, Strings, Fließkommazahlen etc...) belegen dann logischerweise auch mehrere Bytes. Der nächste Dim-Befehl alloziiert dann dementsprechend den nächsten freien Platz.
Mit dem optionalen AT-Parameter kannst Du von Bascom verlangen, daß eine Variable in eine bestimmte SRAM-Adresse zugewiesen bekommt (sofern diese Adresse noch nicht belegt wurde (ansonsten wird die nächste freie zugewiesen).
Ausnahme: der optionale Overlay-Parameter - dadurch können dann mehrere Variablen dieselbe SRAM-Adresse referenzieren. Das macht zB. Sinn, wenn man einen mehrbytigen Bereich definiert (String, etc), und dann darin auf einzelne Elemente (Bytes/Words...) zugreifen will.

Und was ist jetzt mit den Bits? Nun, die benötigen kein ganzes Byte - müssen aber in einem solchen abgelegt werden, klar. Um Speicherplatz zu sparen packt Bascom immer 8 Bit-Variablen in ein gemeinsames Byte.
Mit AT..Overlay könnte man vielleicht das Träger-Byte festlegen, aber die Bitposition innerhalb dieses Bytes ist noch nicht klar...
 
also ich bin ja eher der Automatisierer.. und da sind bei mir 8bits ein byte, und ich kann mit X0.1 das erste bit meines bytes aufrufen ,.
deshalb dachte ich das geht hier mit dem overlay auch so,. na denn ,.


ich versuche gerade meine tabelle in den eeprom zu legen,.
das spart platz und laesst sich mit readeeprom áuslesen,.

hoffe das klappt wie ich mirs vorstelle,.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)