Archiv verlassen und diese Seite im Standarddesign anzeigen : Gerät über RS232 ansprechen
Hallo,
ich habe eine Art von messgerät, das ich über die serielle schnittstelle ansprechen kann um werte zu erhalten.
dazu benutze ich einen mega 8 und einen max232 die bautrate muss bei 19200 liegen.
jetzt muss ich mit bascom ein prog schreiben, das mir ein packet mit insegsamt 10 bytes sendet:
byte1,2,3,4,5,6,7,8,9,10:
002 050 000 032 032 032 032 032 037 135
und ein packet von 8 bytes wieder empfangt:
byte1,2,3,4,5,6,7,8:
000 006 002 002 002 000 105 115
dabei soll jedes empfangene byte in einer variablen hinterlegt werden, um sie danach zu auszuwerten.
wenn z.b. das 2. empfangene byte 002 enthält, soll auf dem lcd 'ok' angezeigt werden.
ich hoffe sehr, das mir jemand dabei helfen kann. alle meine versuche sind bis jetzt gescheitert.
gruß
xeus
Du solltest schon etwas genauer sagen, WAS nicht geht, bzw. wieweit du gekommen bist.
Ev. Code posten
mein erstes prob ist, das ich nicht weis in welchem still ich das ganze senden soll. bis jetzt hab ich immer nur zeichen und keine bytes wie oben beschrieben gesendet.
hier der bisherige code
do
print "002 050 000 032 032 032 032 032 037 135"
loop
so bekomm ich halt nur einen string hin und nicht die bytes.
angenommen ich würd es schaffen es als bytes zu senden:
bytes gesendet
mc soll auf antwort warten
do
if usr.rxc=1
I=udr
select case
case ' was jetzt empfangen wird, soll auf dem lcd erscheinen???
lcd ???
end select
end if
loop
ich hab echt keinen plan
Man kann das folgendermaßen senden
do
print chr(32); chr(32); chr(32); chr(37); chr(135) ;
print chr(32); chr(32); chr(32); chr(37); chr(135) ;
loop
(auf zwei Zeilen aufgeteilt, damit übersichtlich bleibt)
Es werden so bei jedem Loop zehn Byte gesendet
ABER: das ist weder elegant noch gut brauchbar.
Mach lieber ein Array
DIM Sendepaket(10) as byte
'erstmal die Daten ins Paket reinschreiben
Sendepaket(1) = 2
Sendepaket(2) = 50
Sendepaket(3) = 0
Sendepaket(4) = 32
Sendepaket(5) = 32
Sendepaket(6) = 32
Sendepaket(7) = 32
Sendepaket(8) = 32
Sendepaket(9) = 37
Sendepaket(10) = 135
'und jetz komplett alle 10 Byte senden
Do
PRINTBIN Sendepaket(1); 10
Loop
Beim empfang geht's umgekehrt:
DIM Sendepaket(10) as byte
DO
' zehn byte empfangen
INPUTBIN Sendepaket(1), 10
if Sendepaket(2) = 2 then LCD "OK"
LOOP
Schau mal
super, das senden funzt schon, allerdings nur mit einer baudrate von 4800.
um das gerät aber ansprechen zukönnen benötige ich unbedingt 19200.
was kann ich in diesem fall tun?
und nochmals danke für die rasche hilfe!
ganz einfach:
$BAUD = 19200
Gruß
Christopher
ha, ha, ha
das hab ich doch gemacht. nur an der empfangsseite kommt es verfälscht an.
ja, ich hab auch am empfangsterminal 19200 eingestellt
Ja, das ist wahr, das hilft enorm ](*,)
Mein Problem, hab ich aber damit noch nicht gelöst
Hallo
Waher bekommt der AVR den seinen Takt:?
Intern oder extern ?
Wie hoch ?
MFG
Dieter
ich habe ihn derzeit mit dem internen 1mhz getaktet.
1. muss ich die taktrate ändern, damit ich mit 19200 baudrate arbeiten kann?
2. wenn ja, auf wieviel mhz?
3. wie stell ich das an?
danke,
xeus
linux_80
17.09.2005, 18:17
Hallo,
wie sollte man denn die Serielle Schnittstelle einstellen damit das Gerät auch so empfängt wir der AVR sendet,
also ich mein jetzt nicht nur wieviel Baud, sondern auch den Rest wie Stoppbit, Parität, anzahl Bits usw. ?!
Bratwurst
17.09.2005, 19:41
guten abend zusammen,
also lass deinen Takt mal von einem externen Quarz machen. Saubere Taktraten lassen sich unter anderem aus folgenden Quarzfrequenzen generieren:
3,6863Mhz
14,7456MHz
zum erstgenannten noch 33p Bürdekapazitäten und dann müsste das funktionieren. Tut es auf jeden Fall bei mir ;)
greetzle brat
und ach ja
serielle schnittstelle 8N1 also 8 bits, keine parität, und 1 stopbit
ha, ha, ha
das hab ich doch gemacht. nur an der empfangsseite kommt es verfälscht an.
Das war aber aus deinem Code nicht zu ersehen.
Also wenn du die Zeilen:
$crystal=1000000 und
$baud=19200
und der Taktgenerator auf 1MHz steht (fusebits einstellen !, wobei ich nicht weiß, welche Settings der Mega 8 kann.)
dann sollte es funktionieren.
Du kannst Bascom auch eine andere Baudrate vorgaukeln...
mach' crystal = geteilt durch 4, dann kommst du auch auf 19200,
wenn du vorher 4800 hattest. ;)
Funzt zwar, ist aber Quatsch, denn entweder ist dein Takt falsch in den Fusebits eingestellt, oder die Taktfrequenz falsch in Bascom eingegeben.
Gruß
Christopher
Also ich habs ets hinbekommen, das mein m16 mit 16Mhz läuft. und bei einer baudrate von 19200 mit dem gerät kommuniziert.
ich hab die kommunikation wie oben beschrieben realisiert, nun will ich das er das 2.empfangene Byte mit der Zahl 6 vergleicht, und mir 'fehler' bzw. 'kein fehler' über das uart ausgibt.
Sub Status
if Packete(2)= 6 then
print 'kein Fehler'
else
print 'Fehler'
return
end sub
wenn ich im nun als 2.Byte eine 6 sende, gibt er kein fehler aus, und bei einer zahl ungleich 6 fehler. was so weit je schon mal gut ist. aber wiederhole ich diesen vorgang gibt er immer fehler aus.
woran kann das liegen?
mfg
xeus
Kannst du den aktuellen Code reinstellen ?
Hier der code, wie gesagt ich empfange ein packet mit 8 bytes, davon soll er das 2. mit '006' vergleichen.
desweiteren hab ich noch ein Problem mit der Checksummen berechnung, er läst mich bei einer bitverschiebung das ergebnis nicht in eine seperate variable schreiben.
$regfile = "m16def.dat"
$crystal = 20000000 'Quarz: 3.6864 MHz
$baud = 19200
Dim I As Byte
Config Lcdpin = Pin , Db4 = Porta.6 , Db5 = Porta.5 , Db6 = Porta.4 , Db7 = Porta.3 , E = Porta.7 , Rs = Porta.2 ' Natürlich so wie es wirklich angeschlossen ist (4-Bit-Modus)
Dim A As Byte
Config Lcd = 20 * 4 'Baudrate der UART: 9600 Baud
Config Pind.1 = Input
Config Pind.0 = Output
Config Pind.5 = Output
Config Pind.2 = Input
Dim Clc_l As Byte
Dim Clc_h As Byte
Dim New , New1 , New2 , New3 As Byte
Dim Tmp As Byte
Dim Bcclo As Byte
Dim Bcchi As Byte
Dim X As Byte
Dim Packets(10) As Byte
Dim Packete(8) As Byte
Declare Sub Sendewr
Declare Sub Empfangewr
Declare Sub Clc
Declare Sub Lcdout
Declare Sub Status
Dim Line1 As String * 20
Dim Line2 As String * 20
Dim Line3 As String * 20
Dim Line4 As String * 20
'PowerLED
Portd.5 = 1
'Init Packets
Packets(1) = 002
Packets(2) = 050
Packets(3) = 000
Packets(4) = 032
Packets(5) = 032
Packets(6) = 032
Packets(7) = 032
Packets(8) = 032
Packets(9) = 9
Packets(10) = 10
'LCD init
Initlcd
Line1 = "test"
Line2 = " S T A R T!"
Line3 = " com"
Line4 = "www.ich.de"
Gosub Lcdout
Do
'Taster 1
If Pind.2 = 1 Then
Line2 = " reset"
Line3 = " com"
Print "reset"
Gosub Lcdout
End If
'Taster 2
If Pind.4 = 1 Then
Gosub Sendewr
Gosub Empfangewr
'Gosub Status
End If
Loop
'SUBs
'Anfrage an WR stellen
Sub Sendewr
Line2 = " sende Anfrage"
Line3 = " com"
Printbin Packets(1) ; 10
Gosub Lcdout
'Gosub Clc
Return
End Sub Sendewr
'Status vom WR empfangen
Sub Empfangewr
Line2 = " warte auf Daten"
Gosub Lcdout
Inputbin Packete(1) , 8
Gosub Status
Return
End Sub Empfangewr
'Checksumme berechnen
Sub Clc
'Init
Bcclo = &H0XFF 'setze high
Bcchi = &H0XFF 'setze high
New = &B11011001 'lade byte
New = New Xor Bcclo
Tmp = Shift New , Left , 4 'Fehlermeldung
New = Tmp Xor New
Tmp = Shift New , Right , 5 'Fehlermeldung
Bcclo = Bcchi 'setze gleich
Bcchi = New Xor Tmp
Tmp = Shift New , Left , 3 'Fehlermeldung
Bcclo = Bcclo Xor Tmp
Tmp = Shift New , Right , 4 'Fehlermeldung
Bcclo = Bcclo Xor Tmp
'Gosub Lcdout
Return
End Sub Clc
'LCD Ausgabe
Sub Lcdout
Cls
Locate 1 , 1 '1. Zeile
Lcd Line1
Locate 2 , 1 '2. Zeile
Lcd Line2
Locate 3 , 1 '3. Zeile
Lcd Line3
Locate 4 , 3 '4. Zeile
Lcd Line4
Return
End Sub
'Status Auswertung
Sub Status
If Packete(2) = 006 Then 'Vergleich ob das 2.Byte den wert 6 trägt
Line3 = "kein Fehler"
Print "kein fehler"
Else
Line3 = " Fehler"
Print "fehler"
End If
Gosub Lcdout
Return
End Sub Status
End 'end program
wär nett wenn mir jemand helfen könnte das mit dem vergleich und der checksumme hintzkriegen.
mfg
xeus
Moddy: Code-Tags ausgebessert
mein Bascom ist aus mehreren Gründen stinkesauer mit deiner source
dim new, new1, .. as byte nimmt er nicht, das braucht er einzeln
SHIFT hat keinen output-parameter. das Feld wird geshiftet, bleibt aber, wo es ist.
wenn du sowas willst wie
Tmp = Shift New , Left , 4
muttu schreiben:
Tmp = New
Shift Tmp, Left , 4
Welche Art Checksum ist das ? (nur informativ)
Fehler Pakete(2)
Schau mal, ob der Sender nicht vielleicht <CR><LF> nach den 8 byte dazusendet.
Egal, überprüfe den input:
nach
inputbin pakete(1), 8
machst du
Print str(pakete(1)) ;str(pakete(2)) ;...str(pakete(8))
dann siehst du, was effektiv drinsteht und kannst dir vielleicht einen Reim drauf machen
erstmal danke, für deine hilfe.
bei der CRC handelt es sich um ein CCITT standrisiertes CRC Polynom:
mit 2Bytes BccLo & Bcchi
Bn=N^16+N^12+N^5+Bn-1
A. Init BccLo=0xFF, BccHi=0xFF
B. Für jedes Byte das gesendet und empfangen wird
new=new XOR BccLo
tmp=new<<4
new=tmp XOR new
tmp=new>>5
BccLo=BccHi
BccHi=new XOR tmp
tmp=new<<3
BccLo=BccLo XOR tmp
tmp=new>>4
BccLo=BccLo XOR tmp
C. Negieren Bit by Bit BccLo & BccHi: CLC_L=~BccLo CLC_H=~BccHi
also, das mit XOR ist schon mal kein Problem.
das mit dem bitverschieben müsste eigentlich auch möglich sein. das problem ist nur den wert in die entsprechende variable zu übertragen.
Also mein sender hängt defenetiv keine bytes oder bits dran, denn bei dem sender handelt es sich um ein selbstgeschriebenes programm, sendet genau 6 bytes + 2bytes CLC_L,CLC_H
Noch eine zusätzliche Fragen:
wenn ích die bytes empfange (input packet(1)...)
muss es doch möglich sein z.b. das 2. byte mit einem vorgegebenen wert zu vergleichen, und daraufhin eine reaktion auszuführen.
gruß
xeus
Wegen dem 2. Byte: Ich hab ja gesagt, mach nach dem Empfang der 8 Byte ein print mit allen Zeichen.
Da werden irgendwelche verschiebungen stattfinden. da du ja weißt, was du schickst, kannst du daraus dann das Problem einkreisen
ok, werd ich mal austesten, aber ist es prinzipiell so richtig im meinem program, oder muss ich die zu vergleichende zahl irgendwie in ein byte umwandeln?
danke
xeus
Nö. inputbin gibt 1:1 das abgesendete Zeichen
Also stimmt der vergleich so:
Sub Status
If Packete(2) = 006 Then 'Vergleich ob das 2.empfangsbyte = 6
Line3 = "kein Fehler"
Print "kein fehler"
Else
Line3 = " Fehler"
Print "fehler"
End If
return
end sub
stimmt das so?
ich hab ets mal nach
inputbin Packete(1),8
folgendes geschrieben:
printbin packete(1);8
kommt alles etwas durcheinander an, stimmt das so?
Das stimmt schon so, auch die Reihenfolge. alles ok.
Irgendwie nach dem inputbin kontrollieren, dann fällt es dir wie Schuppen aus den Haaren
also hab deinen vorschlag mal so eingefügt, und getestet.
mir ist aufgefallen, das er die reihenfolge irgendwie durcheinander haut.
weisst du was ich dagegen machen kann?
Er haut sie eben nicht "irgendwie" durcheinander, das hat sicher Methode.
schreib dir untereinander
SENT..Byte1, Byte2,...., Byte8 (soll)
RECV..Byte1, Byte2,...., Byte8 (ist)
Irgendwas ist zuviel oder zuwenig
wie meinst du das?
mir ist aufgefallen, das er immer die 3 letzten bytes vorne anhängt:
z.b.
6
7
8
1
2
3
4
5
was kann ich da machen?
Könnte sein, daß dein PC-Programm früher zu senden beginnt, als der Controller bereit ist.
Laß' den BasCom buffern
Schreib vorne irgendwo
CONFIG SERIALIN = buffered, SIZE = 24
Dann ist er immer empfangsbereit.
juihu, ich habs geschaft, wenn jetzt das 2.byte 6 ist schreibt er mir 'kein fehler'
danke, danke, danke.
kannst du mir vielleicht helfen, das problem mit der checksumme zu lösen?
Puh, ich hab das einfach nur abgeschrieben bzw. angepaßt
'Checksumme berechnen
Clc: 'Init
'A. Init BccLo=0xFF, BccHi=0xFF
Bcclo = &HFF 'setze high
Bcchi = &HFF 'setze high
'B Für jedes Byte das gesendet und empfangen wird
New = &B11011001 'lade byte
New = New Xor Bcclo 'new=new XOR BccLo
Tmp = New
Shift Tmp , Left , 4 'Tmp = New << 4
New = Tmp Xor New 'New = Tmp Xor New
Tmp = New
Shift Tmp , Right , 5 'Tmp = New >> 5
Bcclo = Bcchi 'Bcclo = Bcchi
Bcchi = New Xor Tmp 'Bcchi = New Xor Tmp
Tmp = New
Shift Tmp , Left , 3 'Tmp = New << 3
Bcclo = Bcclo Xor Tmp 'Bcclo = Bcclo Xor Tmp
Tmp = New
Shift Tmp , Right , 4 'Tmp = New >> 4
Bcclo = Bcclo Xor Tmp 'Bcclo = Bcclo Xor Tmp
'C. Negieren Bit by Bit BccLo & BccHi: CLC_L=~BccLo CLC_H=~BccHi
Clc_l = Bcclo Xor &HFF
Clc_h = Bcchi Xor &HFF
Wenn du mehrere Byte checkst, mußt du zuerst A) initialisieren,
dann für jedes Byte einmal B)
und am Schluß einmal C)
wenn ich das richtig verstehe
super danke, aber was ich noch nicht verstehe ist:
ich habe ein sende paket von 8 bytes + 2 bytes checksum,
und
ein empfangs paket von 6 bytes + 2 bytes cheksum
wenn ich z.b beim senden jedes zu sendende byte dieses packets durch diese routine laufen lasse, habe ich doch am ende 16 bytes für die checksumme und nicht zwei. oder verstehe ich da was falsch?
hier der dazugehörige orginaltext:
aufbau vom protokoll des anzusprächenden gerätes, und angaben zur checksum
Checksum calculation
The algorithm to compute the checksum to validate the RS485 transmission is the CRC polynomial
standardized by CCITT:
Bn=N^16+N^12+N^5+Bn-1
Where N^16 means that N is elevated to the sixteenth power of 2 (i.e. it is shifted left of 16 bit)
and where the symbol ‘+’ represents the XOR bit by bit.
Practically, if New is the byte to process , Tmp is a swap byte and BccLo and BccHi are the low
and high parts of the validation word, the following algorithm must be followed:
A. Initialize BccLo=0xFF, BccHi=0xFF
B. For each byte to transmit or receive repeat the following steps:
1. New = New XOR BccLo
2. Tmp=New << 4
3. New=Tmp XOR New
4. Tmp=New >> 5
5. BccLo=BccHi
6. BccHi= New XOR Tmp
7. Tmp= New << 3
8. BccLo= BccLo XOR Tmp
9. Tmp= New >> 4
10. BccLo= BccLo Xor Tmp
C. Negate bit by bit BccLo e BccHi : CRC_L=~BccLo CRC_H=~BccHi
Aufbau des Protokols
The communication protocol uses commands of fixed length (8Byte + 2Byte for Checksum)
structured as follows:
Address Command Par.1 Par.2 Par.3 Par.4 Par.5 Par.6 CRC_L CRC_H
The structure of the answer is also with fixed length (6 Byte + 2 Byte for Checksum) :
Transmission State Module State Par.1 Par.2 Par.3 Par.4 CRC_L CRC_H
schon mal danke, für deine mühe
Die CRC-Rechnung erfolgt immer in die selben zwei Byte rein, also auch bei 100 Byte-Messages hast du nur 2 Byte CRC.
BccLo u. Hi werden am Anfang gesetzt, und dann einfach weitergerechnet
EDIT: MUSST du einen Crc-16 nehmen, für diese kleinen Messages reicht doch ein BCC mit 8 Bit genauso ?
leider kann ich mir das nicht aussuchen.
Was in meinem progrmm jetzt noch alles ansteht:
1.da ich mehrer geräte auf dem rs232 bus ansteuern will, muss ich mein Programm noch so umbauen, dass ich für jedes gerät eine eigene abfragesequenz habe (1.byte ist die Adresse). So das ich z.b. sende: an adresse 12
2.desweiteren gibt es verschiedene parameter, die ich abfragen will.(2.byte Commando)
3.weiter muss ich eine art tabelle in meinem prog hinterlegen, so dass der mc auch weiss, was der empfangene Status (2. byte status) bedeutet
4. werde ich versuchen die über die abfrage gesammelten daten, auf einem eeprom tabellarisch abzulegen
5. will ich ein schönes benutzer lcd menü erstellen
6.muss ich versuchen eine software uart zu realisieren, damit ich die gesammelten daten aus dem eeprom über den pc in einem delphi prog auszuwerten, und eine statistik zu führen
7.schluss endlich, soll der mc bei einem bestimmten empfangenem status byte eine modem, bzw. gsm-modems verbindung zu einem fax, oder dem internet aufbauen und den status übermitteln.
so, wie du siehst, habe ich noch einiges an arbeit vor mir.
nochmals vielen dank für deine hilfe, wär schö wenn mehr benutzer so hilfsbereit wären.
gruß
xeus
ah, noch was in bscom gibt es doch einen befehl crc16 weist du was genaueres darüber.arbeitet der genauso wie meiner?
Komischerweise gibt BasCom keine Auskunft, welche Polynom er verwendet. Es kann aber gut sein, daß es für dich stimmt, ist ja ziemlicher Standard.
Es zahlt sich auf jeden Fall aus, es zu versuchen, das Gefummel ist ja langweilig.
Mächtig viel Arbeit, aus weia. Ich wünsch dir viel Erfolg !
mit crc16 krieg ich aber nur ein byte
Nöööö. Lies dir das Help duch, der will in ein word reinschreiben
ja richtig, nochmals danke, werds am sonntag mal testen und dann vergleichen
jetzt hätte ich noch zwei fragen:
1. wie kann ich das errechnette crc16 word in zwei bytes zerlegen?
2. kann es sein, das er die sende und empfangsreihenfolge nicht richtig verarbeitet (inputbin(1) ,1..8, printbin(1),1...10)?
gruß
xeus
1)
Byte_1 = low(crcval) ' das ist das eine Byte von dem word
Byte_2 = high(crcval) ' das ist das andere
2)
von sich aus verdreht er da nix. wie kommst du drauf ?
1.
hab mir mal die empfangenen bytes im lcd anzeigen lassen, und die sind immer irgendwie nicht in der richtigen reihenfolge.ab und zu, gibt er auch anstelle von 115 nur den wert 112 aus.
2.
kann es sein, das ich nach jedem empfang eines bytes meinen buffer löschen soll, weil immer wenn ich die empfangsprozedur öffter als 1mal durchführe bekopmme ich einen anderen wer:
1. durchlauf: z.b. 001 005 176 156 099 156 176 002
2... durchlauf: 003 006 143 178 005 070 090 076
die werte sind nur erfunden.
mfg
xeus
er gibt mir daraufhin immer fehler aus:
dim crc_l as byte
dim crc_l as byte
dim crc as word
crc_l=low(crc)
crc_h=high(crc
an was kann das liegen?
Es kann im Prinzip immer auch kommunikationsfehler geben, wenn z.B. sende- und empfangsseitig die erzielten baudraten knapp an den Toleranzgrenzen sind ( Baudraten haben immer einen %-Fehler)
Aber rein Erfahrungsmäßig würde ich das, solang noch das mit den Bytefolgen irgendwie unsicher ist, mal nicht annehmen. sondern erstmal das restliche Terrain absichern.
Der Befehl:
inputbin Packete(1),8 überschreibt auf jeden Fall 8 Byte des Buffers, da brauchst du nix löschen.
Mach ganz einfach mal den Buffer größer, wenn es sich irgendwie ausgeht:
CONFIG SERIALIN = buffered, SIZE = 128
und schau, obe sich das Verhalten ändert
dim crc_l as byte
dim crc_l as byte
zweimal gleich. Verschrieben ?
also wegen der crc muss ich mich berichtigen, hab nur die variablen vertauscht, leider kann ich die crc16 nicht verwenden, gibt mir falsche werte aus.werd die prozedur doch selbst machen müssen.
ist es nicht so das für empfang und senden nur einen puffer git? da ich ja 10 bytes sende aber nur 8 empfange, nicht das er die letzten 2bytes mit in die andere prozedur überträgt.
Nein, nein, die Buffer sind schon getrennt, keine Sorge. Können auch verschieden groß sein.
aber auf wieviel soll ich den buffer erhöhe, wenn ich ihn auf 128 hochsetz kommt nichts mehr an.
auszug von dem was der PC senden, und was der mc Empfängt:
pc:000 006 002 002 002 000 105 115
mc 000 103 114 000 006 002 002 002
??? kann das am buffer liegen
Irgendwie kommen Sender / Empfänger aus dem Tritt.
Wenn der Sender immer 8 Byte schickt, und der Empfänger immer 8 Byte liest (auch wenn er sie nicht verwertet) kann das so nicht sein.
Kann es sein, daß du beim lesen auf die 2 Byte CRC vergißt ?
nein, die werden mit gesendet und auch mit empfangen, aber halt nicht berechnet.komisch senden tut er die 8bytes+2bytes einwandfrei zum pc, nur irgendwie haut er das mit dem empfangen immer durcheinander.
hab mal versucht den buffer zu erhöhen, aber dan macht er garnichts mehr.
Hartnäckige Sache.
Kannst du bitte deine Source komplett, so wie sie ist, reinstellen ?
$regfile = "m16def.dat"
$crystal = 19999998 'Quarz: 3.6864 MHz
$baud = 19200
Dim I As Byte
Config Lcdpin = Pin , Db4 = Porta.6 , Db5 = Porta.5 , Db6 = Porta.4 , Db7 = Porta.3 , E = Porta.7 , Rs = Porta.2 ' Natürlich so wie es wirklich angeschlossen ist (4-Bit-Modus)
Dim A As Byte
Config Lcd = 20 * 4 'Baudrate der UART: 9600 Baud
Config Pind.1 = Input
Config Pind.0 = Output
Config Pinb.3 = Output
Config Pind.5 = Output
Config Pind.2 = Input
Dim Crc_l As Byte
Dim Crc_h As Byte
Dim New As Byte
Dim Tmp As Byte
Dim Bcclo As Byte
Dim Bcchi As Byte
Dim X As Byte
Dim Crce As Word
Dim Crcs As Word
Dim Packets(10) As Byte
Dim Packete(8) As Byte
Declare Sub Sendewr
Declare Sub Empfangewr
Declare Sub Clc
Declare Sub Lcdout
Declare Sub Status
Declare Sub Auswahltyp
Dim Wrtyp As String * 10
Declare Sub Auswahlanzahl
Dim Anzahl As Integer
Dim Line1 As String * 20
Dim Line2 As String * 20
Dim Line3 As String * 20
Dim Line4 As String * 20
'PowerLED
Portd.5 = 1
Portb.3 = 1
'Init Packets
Packets(1) = 002
Packets(2) = 050
Packets(3) = 000
Packets(4) = 032
Packets(5) = 032
Packets(6) = 032
Packets(7) = 032
Packets(8) = 032
Packets(9) = 037
Packets(10) = 135
'Config Serialin = Buffered , Size = 8
Do
'Gosub Auswahltyp
'Taster 1
'If Pind.2 = 1 Then
' Line2 = " reset"
' Print "reset"
' Gosub Lcdout
'End If
'Taster 2
If Pind.4 = 1 Then
Gosub Sendewr
Gosub Empfangewr
'Gosub Status
End If
Loop
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'SUBs
Sub Sendewr
Line2 = " sende Anfrage"
Printbin Packets(1) ; 10
Gosub Lcdout
'Gosub Clc
Return
End Sub Sendewr
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub Empfangewr
Line2 = " warte auf Daten"
'Gosub Lcdout
Inputbin Packete(1) , 8
Printbin Packete(1) ; 8
Crce = Crc16(packete(1) , 6)
Crc_l = Low(crce)
Crc_h = High(crce)
Cls
Locate 1 , 1
Lcd "Empfangenes Paket:"
Locate 2 , 1
Lcd "1:" ; Str(packete(1))
Locate 2 , 5
Lcd "2:" ; Str(packete(2))
Locate 2 , 9
Lcd "3:" ; Str(packete(3))
Locate 2 , 13
Lcd "4:" ; Str(packete(4))
Locate 2 , 17
Lcd "5:" ; Str(packete(5))
Locate 3 , 1
Lcd "6:" ; Str(packete(6))
Locate 3 , 5
Lcd "7:" ; Str(packete(7))
Locate 3 , 9
Lcd "8:" ; Str(packete(8))
Locate 4 , 1
Lcd "CRC_l:" ; Crc_l
Locate 4 , 12
Lcd "CRC_H:" ; Crc_h
'Gosub Status
Return
End Sub Empfangewr
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'Checksumme berechnen
Sub Clc
Bcclo = &HFF
Bcchi = &HFF
Return
End Sub Clc
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'LCD Ausgabe
Sub Lcdout
Cls
Locate 1 , 1 '1. Zeile
Lcd Line1
Locate 2 , 1 '2. Zeile
Lcd Line2
Locate 3 , 1 '3. Zeile
Lcd Line3
Locate 4 , 1 '4. Zeile
Lcd Line4
Return
End Sub Lcdout
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'Status Auswertung
Sub Status
If X = 6 Then
Line3 = "ok"
Print "kein fehler"
Else
Line3 = "Fehler"
Print "fehler"
End If
Gosub Lcdout
Return
End Sub Status
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
End
also anscheinend empfängt er alle bytes, aber er ordnet sie falsch.
byte 6,7,8 stellt er immer vorran.
wenn ich ein zweites paket sende überschreibt er byte 7, 8 garnicht
beim dritten paket überschreibt er alle bis auf byte 8
VERZWEIFLUNG!!!
Ich schau' mir dein Programm grad an, bleib locker.
Wenn du grad in der Panik-Phase bist, die immer irgendwann eintritt, dreh' ein paar Runden ums Haus oder füttere die Katze, kraulen ist noch besser. In dem Zustand sieht man den Wald vor Bäumen nicht mehr.
(glaub' mir, ich mach das schon länger)
Guter tipp danke, das problem ist nur dass es sich hierbei um ein projekt für die arbeit ist und ich am 15.nov abgabetermin habe.
Aaaallsooo:
Im Programm ist KEIN direkter Fehler, es geht ums Timing
Vom Sendwr bis zum Inputbin brauchst du offenbar mal zu lange, da geht was verloren.
du MUSST config serialin = buffered angeben, der Sender schickt nach Empfang sicher sofort los, anders kriegst du die Hälfte nicht mit.
soweit, sogut.
aaaaber:
Der Sender schickt (ziemlich sicher) nicht nur ein Paket, sondern mehrere.
Es könnte sein, daß er deinen "Bestätigungs-printbin" gleich nach dem Empfangen als Aufforderung versteht, oder es hat andere Gründe.
Deswegen klappt's ja auch einmal, aber dann nichtmehr.
Da du ja das Empfangspaket eh' auf dem LCD zeigst, kannst du diesen "Retour-print" ja mal weglassen, vielleicht reicht das schon.
Sonst muß man sich den Sender näher anschauen.
Nochmal: DU MUSST den serialin-Buffer nehmen (size = 8 muss reichen, wenn der Sender auch wirklich nur ein Paket schickt)
Wenn sich der Sender nicht disziplinieren läßt, müssen wir deinen input auf asynchron umstellen. Wenn der einfach drauflosplappert, wird sowas immer wieder passieren.
Hast du Info, WANNN WER WEM was zu schicken hat ?
Und such keinen Fehler, da is keiner (s.o)
Aufgabenstellung:
also ich hab in diesem fall 12 geräte mit 12 adressen (2-13)
mein mc soll anfangs sequeziell den status der geräte abfragen und den status am lcd und über usart ausgeben.
immer wenn ich eine anfrage an eine gerät sende bekomme ich gleich darauf antwort.
Vom Sendwr bis zum Inputbin brauchst du offenbar mal zu lange, da geht was verloren.
du MUSST config serialin = buffered angeben, der Sender schickt nach Empfang sicher sofort los, anders kriegst du die Hälfte nicht mit.
soweit, sogut.
das hab ich schon versucht, nur dann empfängt er anscheinend garnichtsmehr.
ich glaub nicht, dass was verloren geht, da ich das packet bei der anfrage ja komplett empfange, halt nur in einer falschen reihenfolge.
bei weiteren anfragen, bleibt immer das 8byte gleich wie beim ersten und ändert sich nicht.
Der Sender schickt (ziemlich sicher) nicht nur ein Paket, sondern mehrere.
nein, er schickt sicher nur ein antwort-paket mit 8bytes + 2bytes crc
Es könnte sein, daß er deinen "Bestätigungs-printbin" gleich nach dem Empfangen als Aufforderung versteht, oder es hat andere Gründe.
welchen bestätigungs-printbin?
ich sende gerät empfängt und gibt darauf antwort
Da du ja das Empfangspaket eh' auf dem LCD zeigst, kannst du diesen "Retour-print" ja mal weglassen, vielleicht reicht das schon.
das hab ich nur gemacht, dass ich die packete am pc mitbeobachten kann
Der Inputbin ist einfach und übersichtlich: Er schreibt ab der angegebenen Addresse ( Packete ( 1 ) ) die nächsten 8 Byte, die er erwischt, strikt aufsteigend rein. Da gibt's keine Querschläger.
Das hab ich überprüft, das steht so in der Hex-file.
Wenn also der Sender tatsächlich nur ein paket mit 8 Byte schickt, dann stehen die auch genau so drin, wie sie weggeschickt wurden.
( Ich ignoriere mal die Möglichkeit, daß der Sender was verdreht )
Solange du dich drauf fixierst, daß so ein Buffer schon mal durcheinander kommen kann, hast du schlechte Karten
bis jetzt, hab ich das ganze ja nur mit einem prog das ich geschrieben hab getestet, vielleicht bringt auch das etwas durcheinander. werd mich mal auf den weg machen und es mal schnell in reality testen.
bis jetzt, hab ich das ganze ja nur mit einem prog das ich geschrieben hab getestet, vielleicht bringt auch das etwas durcheinander. werd mich mal auf den weg machen und es mal schnell in reality testen.
also, ich habs jetzt mal vorort getestet und einen pc dazu geschalten, der die empfangenen pakete mitliest:
der pc hat auf die anfrage vom gerät eine antwort bekommen, aber der mc zeigte keine reaktion.
wie kann ich testen, ob beim mc was ankommt. kann ich einfach zwischen die readleitung und gnd eine led reinlöten?
hab den buffer jetzt mal auf 9 gesetzt und hab über ein prog vom pc aus ein 8byte paket zu mc gesendet, und wow er hats richtig angezeigt. auch komisch das ich den auf neun setzten muss, bedeutet dass das die software doch noch etwas anderes mitsendet?
Nun, es zeigt zumindest, daß die Sache nicht ganz so ist, wie angenommen.
Wenn du einen PC als Spion einsetzen kannst, ist es ja super. Schau die die diversen Meldungung genau an.
Bis das geklärt ist, schreib meinethalben auch 11 komma 5 rein, hauptsache, man kommt der Sache näher
ok, das mit dem buffer klappt jetzt auch wie gewollt.
was meinst du mit 11 komma 5?
Ich mein damit, schreib alles rein, was hilft, auch wenn es seltsam scheinen mag
Diese 9. Zeichen schon mal angeschaut, was das ist ?
(Vergiß nicht, ggf. auch Packete(x) anzupassen)
ne habs jetzt anders gemacht, er nimmt auch die acht, er wollte nur das ich auch den ausgang configuriere.
ha ha, die probleme minimieren sich schön langsam. juhu.
ich schließe die geräte die ich ansteuern will nicht direkt am mc an, sondern über ein funkteil, das leider nicht an meinem arbeitsplatz steht sondern einpaar straßen weiter in einem anderen gebäude. so das ich wenn ich es real,ohne softwaresim testen will immer dorthin fahren muss.
das ist macht die sache etwas unflexible, aber naja hilft ja nichts.
bleibt nur noch das große problem warum der mc wenn er mit den geräten verbunden ist keine reaktion zeigt aber der pc schon. könnte es vielleicht sein das der mc zu langsm ist? oder die rx leitung vom funkteil wo anders aufgelekt ist?
gibt es vielleicht irgendeine möglichkeit, dass ich mir eine meldung am lcd ausgeben lasse, sobalt irgendwelche daten empfangen werden. egal ob 1byte oder 20 nur um zusehen ob was ankommt hauptsache rs232 pegel
Hast du jetzt einen serialin= Buffer drin ?
Wenn der MC zu langsam ist, dann ZWISCHEN den "inputbin". Die ganzen LCD-Geschichten brauchen schon ihre Zeit.
Die RX-Leitung woanders ? Da mußt du nachschauen. Gibt's nicht, gibt's nicht.
1)
das mit dem buffer funzt (habs nur mit dem pc getestet)
2)
soll ich die lcd geschichte mal weglassen, und mir nur am schluss, also wenn das empfangen zuende ist, eine meldung anzeigen lassen?
@gast:
mich hät ja interessiert wie ich das am effektievsten mach
Ich würd mal alles weglassen, was nicht unbedingt notwendig ist.
Aber irgendwie muß es natürlich kontrollierbar sein. Mach es vielleicht mal so, dass du nur dann den Buffer herzeigst, wenn die empfangene Meldung irgendwie nicht passt und es eh' nicht mehr weiter geht.
Für jede OK Meldung zählst du nur irgendwo mit und sagst dann am Schluß
Empfangen: n ok: m
gibt es nicht irgendwie die möglichkeit, das ich beim empfang von daten einen interrupt auslöse und dadurch eine led angeht, nur das ich seh, das der mc auch was empfängt.
Naja. auf dem RX-Interrupt sitzt schon der BasCom drauf.
Du kannst aber eins machen:
Sub Empfangewr
while ischarwaiting() = 0
' LED aus
wend
' LED on hier kommt er nur her, wenn irgendwas ankommt
inputbin .... usw.
Inputbin Packete(1) , 8
passt wunderbar. es hat geklapt bin gerade hingefahren und habs getestet und tatsächlich empfängt er bytes und gibt sie mir ans lcd aus.super
mein nächster schritt:
ich werd versuchen die crc irgendwie mit einzubinden. weis nur noch nicht, wie ich die prozedur mach, denn er muss ja den schritt b für jedes byte machen aber immer unter verwendung von bcclo und bcchi. werd also die init der bcc's relativ weit zu beginn machen und dan eine prozedure für b. muss halt nach dem übertragen der beiden bcc's diese neu initialisieren, damit ich für das nächste packet empfangsbereit bin.
nochmals vielen vielen danke für deine hilfe, und für deine gedult mit mir.
Genau. Initialisieren ganz vorn und dann nach jeder Erstellung oder Prüfung.
Also , weiterhin viel Erfolg !
hab mich gerade mal ans crc gemacht und ne eigene sub erstellt, in der ich dein berechnung 8 mal (pro byte1x) durchlaufen lasse (pro packets(1)...1x)
und am schluss lass ich sie mit ausgeben, aber da kommt er immer auf 0 0. gibts da nicht ne einfachere variante das zu machen, ist ja ein ewig langer code sonst.
0 0 wird zwar nicht stimmen, aber da muß wo ein Hund drinnen sein.
Aber eine Shift-Orgie ist das auf jeden Fall, da is nix zu machen
Also wie schon gesagt, die anfrage und das erhalten einer antwort von mehreren geräten funzt schon mal.
jetzt hab ich gerade auf meine platine noch einen 2 m16 + max232 aufgelötet. der soll die speicherung der daten und das aufbereiten dieser übernehmen.
nun überlege ich schon die ganze zeit was einfacher und sinnvoller ist, i²C oder über ein software uart das einfach den uart datenstrom des 1.mc mitließt. Was denkst du?
gruß
xeus
Hier mein Fünktionsprinzip meiner (zukünftigen) Schaltung:
MC1:
1) MC1 frägt sequenziell die Adr 1 - 10 ab und erhält pro anfrage sofort eine Antwort.
IST: geräte werden sequenziell abgefragt und die antwort analysiert
Problem: wenn ein gerät nicht erreichbar ist soll eine art time out erfolgen, der mc soll dann einfach die nächste adr abfragen. Aber Wie realisieren?
2) Diese empfangenen daten(6Byte) sollen mit der aktuellen zeit und dem datum des pcf8583 im speicher des 24c256 abgespeichert werden
IST: I²C kommunikation funktioniert Uhr kann abgefragt werden
Problem: Die ansteuerung des eeproms, bring ie speicherroutine einfach nicht zum laufen
MC2:
1) MC1 soll die Komplette Kommunikation mit dem PC ausführen das heist:
- Den 24c256 auslesen und die daten ans uart ausgeben.
- Soll die RTC (PCF8583) stellen (datum und uhr einstellen)
IST: I²C slave gekauft
Problem: - Kann den 24c256 nicht auslesen???
- Wenn ich die twi slave.bas mit in mein prog mit einbaue, dass
mir die zeit des pcf8583 übers uart ausgibt, kommen
zwar die daten vom master an, aber nicht mehr die des pcf8583
Wär nett wenn jemand lösungen für mich hätte
PS: Hardware ist schon vorhanden!!!
gruß
xeus
Hallo,
Hier mein bishäriger code:
'Mikrocontroller Setup
$lib "mcsbyteint.lbx"
$regfile = "m16def.dat"
$crystal = 20000000
$baud = 19200
'Display Setup
Config Lcdpin = Pin , Db4 = Porta.6 , Db5 = Porta.5 , Db6 = Porta.4 , Db7 = Porta.3 , E = Porta.7 , Rs = Porta.2 ' Natürlich so wie es wirklich angeschlossen ist (4-Bit-Modus)
Config Lcd = 20 * 4
Config Pind.2 = Input 'taster
Config Pind.4 = Input 'Taster
Config Pind.7 = Output 'Buzzer
Config Pina.1 = Output 'Relais (öffner)
'Sende & Empfangs Variablen
Dim Packets(10) As Byte
Dim Packete(8) As Byte
'Allgemeine WR Variablen
Dim Wranzahl As Byte
'Display & Line Variablen
Dim Line1 As String * 20
Dim Line2 As String * 20
Dim Line3 As String * 20
Dim Line4 As String * 20
'Checksum Variablen
Dim Bcclo As Byte
Dim Bcchi As Byte
'Sendepaket Variablen
Dim Adr As Byte
Dim Command As Byte
Dim Par1 As Byte
Dim Par2 As Byte
Dim Par3 As Byte
Dim Par4 As Byte
Dim Par5 As Byte
Dim Par6 As Byte
Dim Par7 As Byte
Dim Par8 As Byte
'Empfangspaket Variablen
Dim Globalstate As Byte
Dim Inverterstate As Byte
Dim Dc1state As Byte
Dim Alarmstate As Byte
Dim Transstate As Byte
Dim Dc2state As Byte
Dim Tglobalstate As String * 20
Dim Talarmstate As String * 20
'Uhr
Dim S As Byte , M As Byte , H As Byte , D As Byte
Dim Wm As Byte , Yd As Byte , Month As Byte
'Checksum
Declare Sub Crc
Declare Sub A_crc16
'Paket subs
Declare Sub Paketinits
Declare Sub Paketinite
'Subroutines
Declare Sub Sendewr
Declare Sub Empfangewr
Declare Sub Lcdout
Declare Sub Status
Declare Sub Abfrageroutine
'Uhr
Declare Sub Gettime
Declare Sub Settime
'configure the used port pin for I2C
Config I2cdelay = 5
Config Sda = Portc.1
Config Scl = Portc.0
'Setup Comports
'Serial 1 Configuration
Config Serialin = Buffered , Size = 8
Config Serialout = Buffered , Size = 10
'Program Paramter init
Wranzahl = 12 'Anzahl der Geräte
'Uhr Variablen setzen
S = 10
M = 0
H = 0
D = 1
Month = 1
Wm = 1
Yd = 1
Ddrd = &B00010000
Cls
'LCD init
Initlcd
Line1 = "Test"
Line2 = "boot"
Line3 = " 0.1 "
Line4 = "xeus"
Gosub Lcdout
Enable Interrupts
Call Settime
Do
Porta.1 = 1 'relais
Gosub Abfrageroutine
Wait 2
Loop
End
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'SUBs
'Paketinitialisierung Senden
Sub Paketinits
'Init Packets
Packets(1) = Adr 'Adr
Packets(2) = Command 'command
Packets(3) = Par1 'Par1
Packets(4) = Par2 'Par2
Packets(5) = Par3 'Par3
Packets(6) = Par4 'Par4
Packets(7) = Par5 'Par5
Packets(8) = Par6 'Par6
Packets(9) = Bcclo 'CRC_L
Packets(10) = Bcchi 'CRC_H
Return
End Sub Paketinit
'--------------------------------------------
'Packetinitialisierung Empfangen
Sub Paketinite
'Init Packete
Transstate = Packete(1) 'Transmission State
Globalstate = Packete(2) 'Global State
Inverterstate = Packete(3) ' Stat
Dc1state = Packete(4) '1 State
Dc2state = Packete(5) '2 State
Alarmstate = Packete(6) 'Alarm State
Bcclo = Packete(7) 'CRC_L
Bcchi = Packete(8) 'CRC_H
End Sub Packetinie
'---------------------------------------------
'Anfrage an gerät stellen
Sub Sendewr
Gosub Crc
Gosub Paketinits
Printbin Packets(1) ; 10 'Paket wird gesende
Return
End Sub Sendewr
' - - - - - - - - - - - - - - - - - - - -
'Status vom WR empfangen
Sub Empfangewr
Inputbin Packete(1) , 8 ' Bytes einlesen
Return
End Sub Empfangewr
'- - - - - - - - - - - - - - - - - - - -
'LCD Ausgabe
Sub Lcdout
Cls
Locate 1 , 1 '1. Zeile
Lcd Line1
Locate 2 , 1 '2. Zeile
Lcd Line2
Locate 3 , 1 '3. Zeile
Lcd Line3
Locate 4 , 1 '4. Zeile
Lcd Line4
Return
End Sub Lcdout
'- - - - - - - - - - - - - - - - - - - -
'PCF8583 stellen
Sub Settime
S = Makebcd(s) 'Sek
M = Makebcd(m) 'Min
H = Makebcd(h) 'Std
D = Makebcd(d) 'Tag
Month = Makebcd(month) 'Monat
'Setzen der vorgebenen Werte
I2cstart
I2cwbyte &HA0 'Schreibmodus
I2cwbyte 0 'select control register
I2cwbyte 8 'set year and day bit for masking
I2cstart
I2cwbyte &HA0 'Schreibmodus
I2cwbyte 2 'Sekundenregister auswählen
I2cwbyte S 'Sek schreiben
I2cwbyte M 'min schreiben
I2cwbyte H 'std schreiben
I2cwbyte D 'tag schreiben
I2cwbyte Month 'monat schreiben
I2cstop
End Sub Settime
Sub Gettime
'Aktuelle Werte auslesen
'---------------------- sekunden --------------------
I2cstart
I2cwbyte &HA0
I2cwbyte 2 'Sek register auswählen
I2cstart
I2cwbyte &HA1
I2crbyte S , Nack 'lese sek
'---------------------- minuten --------------------
I2cstart
I2cwbyte &HA0
I2cwbyte 3 'min register auswählen
I2cstart
I2cwbyte &HA1
I2crbyte M , Nack 'lese min
'---------------------- stunden --------------------
I2cstart
I2cwbyte &HA0
I2cwbyte 4 'Std register auswählen
I2cstart
I2cwbyte &HA1
I2crbyte H , Nack 'lese std
'---------------------- tag --------------------
I2cstart
I2cwbyte &HA0
I2cwbyte 5 'tag register auswählen
I2cstart
I2cwbyte &HA1
I2crbyte Yd , Nack 'lese jahr und tag
'---------------------- wotag --------------------
I2cstart
I2cwbyte &HA0
I2cwbyte 6 'mon register auswählen
I2cstart
I2cwbyte &HA1
I2crbyte Wm , Nack 'lese wochentag und monat
I2cstop
End Sub Gettime
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'Abfrageroutine sequenziell
Sub Abfrageroutine
Wranzahl = Wranzahl + 1
Adr = Wranzahl 'Abrage Commando 2.Byte
For Adr = 2 To Wranzahl
'Adr = Wranzahl
Command = 050
Adr = Adr
Command = Command
Par1 = 000
Par2 = 032
Par3 = 032
Par4 = 032
Par5 = 032
Par6 = 032
Par7 = Bcclo
Par8 = Bcchi
Gosub Paketinits
Gosub Sendewr
Gosub Empfangewr
Gosub Paketinite
Gosub Status
Wait 2
Next Adr
If Adr = 13 Then
Adr = 2
End If
Return
End Sub Abfrageroutine
'------------------------------------------------------------------------------------------------------------
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub Crc
'--------------------- make CCITT -----------------------------
Loadadr Packets(1) , X ' addr of data
Ldi r19,8 ' Anzahl bytes )
'----- berechnet CCITT und schreibt ihn nach Bcclo u. Bcchi -----
Gosub A_crc16 ' callit
Packets(9) = Bcclo
Packets(10) = Bcchi
End Sub
'------------------------------------------------------------------
' register X --> first data byte
' register 19 --> Number of data bytes
'------------------------------------------------------------------
Sub A_crc16:
ser r16 ; crc low byte
ser r17 ; crc high byte
ldi r24,&H08 ; polynome
ldi r25,&H84
A_crc16_1:
ld r20,x+ ; get data byte
ldi r18,8 ; 8 bits
A_crc16_2:
push r20 ; save data byte
andi r20, 1 ; mask out 2^^0
eor r16, r20 ; data XOR crc-Lo
clc ; clear carry for shift
ror r17 ; shift crchi to right
ror r16 ; shift crclo to right
brcc A_crc16_3 ; no carry --> skip
eor r17,r25 ;
eor r16,r24 ; XOR Polynome
A_crc16_3:
pop r20 ; restore databyte
ror r20 ; shift right, too
dec r18 ; bit counter
brne A_crc16_2 ; continue
dec r19 ; byte counter
brne A_crc16_1 ; continue
ser r24 ; make FF
eor r17,r24 ; XOR crchi with FF
eor r16,r24 ; XOR crclo with FF
Loadadr Bcclo , X ' Address Of Result
st x+ , r16 ; store crclo
st x+ , r17 ; store crchi
Return ' that's it
'-----------------------------------------------------------------------------
End Sub
'-----------------------------------------------------------------------------
'STATUS ANALYSE
'-----------------------------------------------------------------------------
'Status Auswertung
Sub Status
'Init Packete
Transstate = Packete(1) 'Transmission State
Globalstate = Packete(2) 'Global State
Inverterstate = Packete(3) 'Inverter Stat
Dc1state = Packete(4) '1 DC State
Dc2state = Packete(5) '2 DC State
Alarmstate = Packete(6) 'Alarm State
Bcclo = Packete(7) 'CRC_L
Bcchi = Packete(8) 'CLC_H
'2.Byte Global State
If Globalstate = 006 Then
Tglobalstate = "Run"
Porta.1 = 1
Else
Tglobalstate = "FEHLER"
Portd.7 = 1
Porta.1 = 0
Wait 1
Portd.7 = 0
End If
or
If Globalstate = 009 Then
Tglobalstate = "Ground Fault"
End If
or
If Globalstate = 016 Then
Tglobalstate = "Waiting for reset"
End If
'6.Byte Alarm State
If Alarmstate < 000 Then
Talarmstate = "Fehler"
End If
or
If Alarmstate = 001 Then
Talarmstate = "Fehler: Sun Low"
End If
or
If Alarmstate = 002 Then
Talarmstate = "Fehler: Input OC"
End If
or
If Alarmstate = 003 Then
Talarmstate = "Fehler: Input UV"
End If
or
If Alarmstate = 004 Then
Talarmstate = "Fehler: Input OV"
End If
or
If Alarmstate = 007 Then
Talarmstate = "Fehler: Bulk OV"
End If
or
If Alarmstate = 009 Then
Talarmstate = "Fehler: AC OC"
End If
or
If Alarmstate = 013 Then
Talarmstate = "Fehler: Grid Fail"
End If
or
If Alarmstate = 016 Then
Talarmstate = "Fehler: DC/DC Fail"
End If
or
If Alarmstate = 018 Then
Talarmstate = "Fehler: Ground Fault"
End If
or
If Alarmstate = 019 Then
Talarmstate = "Fehler: Over Temp."
End If
or
If Alarmstate = 020 Then
Talarmstate = "Fehler: BulkCap Fail"
End If
or
If Alarmstate = 023 Then
Talarmstate = "Fehler: Ground Fault"
End If
or
If Alarmstate = 024 Then
Talarmstate = "Degauss ERROR"
End If
or
If Alarmstate = 026 Then
Talarmstate = "Fehler: DCDC Fail"
End If
or
If Alarmstate = 032 Then
Talarmstate = "Fehler: Grid OV"
End If
or
If Alarmstate = 033 Then
Talarmstate = "Fehler: Grid UV"
End If
or
If Alarmstate = 034 Then
Talarmstate = "Fehler: Grid OF"
End If
or
If Alarmstate = 035 Then
Talarmstate = "Fehler: Grid UF"
End If
or
If Alarmstate = 036 Then
Talarmstate = "Fehler: Z Grid Hi"
End If
or
If Alarmstate = 038 Then
Talarmstate = "Fehler: Riso Low"
End If
Cls
Locate 1 , 1
Lcd "testl"
Locate 2 , 1
Lcd "WR-Adr: " + Str(adr)
Locate 3 , 1
Lcd Tglobalstate
Locate 4 , 1
Lcd Talarmstate
Return
End Sub Status
leider konnte ich bis jetzt noch keines der oben genannten probleme lösen. vielleicht hat von euch jemand eine idee.
Torsten_G
25.10.2005, 12:42
...
Problem: wenn ein gerät nicht erreichbar ist soll eine art time out erfolgen, der mc soll dann einfach die nächste adr abfragen. Aber Wie realisieren?
...
Hallo xeus,
auf einen Interrupt musst Du eigentlich gar nicht aufsetzen, ein fehlerhafter Zugriff auf einen i2c-Slave liefert Dir automatisch ein Error-Bit...
I2cstart
I2cwbyte Pcf1w_adr
If Err = 1 Then
I2c_state = "Fault"
end if
I2cstop
In der Variable Pcf1w_adr muss natürlich die Adresse des Slaves stehen (hier die Write-Adresse), und i2c_state ist eine String-Variable.
Ich hoffe, es hilft Dir weiter, und viele Grüße
Torsten
erstmal vielen dank, aber eigentlich meinte ich die "Geräte" die ich über rs232 anspreche.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.