PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Gerät über RS232 ansprechen



Xeus
17.09.2005, 11:26
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

PicNick
17.09.2005, 12:39
Du solltest schon etwas genauer sagen, WAS nicht geht, bzw. wieweit du gekommen bist.
Ev. Code posten

Xeus
17.09.2005, 12:47
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

PicNick
17.09.2005, 13:09
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

Xeus
17.09.2005, 14:08
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!

chr-mt
17.09.2005, 15:13
ganz einfach:

$BAUD = 19200

Gruß
Christopher

Xeus
17.09.2005, 15:26
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

PicNick
17.09.2005, 15:26
Ja, das ist wahr, das hilft enorm ](*,)

Xeus
17.09.2005, 15:37
Mein Problem, hab ich aber damit noch nicht gelöst

17.09.2005, 15:44
Hallo

Waher bekommt der AVR den seinen Takt:?

Intern oder extern ?

Wie hoch ?

MFG
Dieter

Xeus
17.09.2005, 15:46
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

chr-mt
17.09.2005, 20:42
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

Xeus
06.10.2005, 17:52
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

PicNick
06.10.2005, 19:01
Kannst du den aktuellen Code reinstellen ?

Xeus
07.10.2005, 08:26
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

PicNick
07.10.2005, 10:26
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

Xeus
07.10.2005, 14:46
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

PicNick
07.10.2005, 14:56
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

Xeus
07.10.2005, 15:16
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

PicNick
07.10.2005, 15:22
Nö. inputbin gibt 1:1 das abgesendete Zeichen

Xeus
07.10.2005, 15:42
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?

PicNick
07.10.2005, 15:46
Das stimmt schon so, auch die Reihenfolge. alles ok.
Irgendwie nach dem inputbin kontrollieren, dann fällt es dir wie Schuppen aus den Haaren

Xeus
07.10.2005, 16:08
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?

PicNick
07.10.2005, 16:11
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

Xeus
07.10.2005, 16:19
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?

PicNick
07.10.2005, 16:29
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.

Xeus
07.10.2005, 16:33
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?

PicNick
07.10.2005, 16:57
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

Xeus
07.10.2005, 17:29
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?

Xeus
07.10.2005, 17:45
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

PicNick
07.10.2005, 18:40
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 ?

Xeus
07.10.2005, 20:03
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

Xeus
07.10.2005, 20:05
ah, noch was in bscom gibt es doch einen befehl crc16 weist du was genaueres darüber.arbeitet der genauso wie meiner?

PicNick
07.10.2005, 20:25
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 !

Xeus
07.10.2005, 20:41
mit crc16 krieg ich aber nur ein byte

PicNick
07.10.2005, 20:43
Nöööö. Lies dir das Help duch, der will in ein word reinschreiben

Xeus
07.10.2005, 20:45
ja richtig, nochmals danke, werds am sonntag mal testen und dann vergleichen

Xeus
10.10.2005, 09:46
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

PicNick
10.10.2005, 09:53
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 ?

Xeus
10.10.2005, 10:01
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

Xeus
10.10.2005, 10:10
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?

PicNick
10.10.2005, 10:15
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

PicNick
10.10.2005, 10:17
dim crc_l as byte
dim crc_l as byte

zweimal gleich. Verschrieben ?

Xeus
10.10.2005, 10:33
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.

PicNick
10.10.2005, 10:35
Nein, nein, die Buffer sind schon getrennt, keine Sorge. Können auch verschieden groß sein.

Xeus
10.10.2005, 10:50
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

PicNick
10.10.2005, 10:59
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 ?

Xeus
10.10.2005, 11:05
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.

PicNick
10.10.2005, 11:13
Hartnäckige Sache.
Kannst du bitte deine Source komplett, so wie sie ist, reinstellen ?

Xeus
10.10.2005, 11:25
$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

Xeus
10.10.2005, 11:39
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!!!

PicNick
10.10.2005, 11:44
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)

Xeus
10.10.2005, 11:46
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.

PicNick
10.10.2005, 12:33
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)

Xeus
10.10.2005, 13:18
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

PicNick
10.10.2005, 13:48
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

Xeus
10.10.2005, 13:50
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.

Xeus
10.10.2005, 14:29
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.

Xeus
10.10.2005, 15:32
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?

Xeus
10.10.2005, 15:56
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?

PicNick
10.10.2005, 16:00
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

Xeus
10.10.2005, 16:14
ok, das mit dem buffer klappt jetzt auch wie gewollt.

was meinst du mit 11 komma 5?

PicNick
10.10.2005, 16:22
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)

Xeus
10.10.2005, 16:24
ne habs jetzt anders gemacht, er nimmt auch die acht, er wollte nur das ich auch den ausgang configuriere.

Xeus
10.10.2005, 16:31
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?

Xeus
10.10.2005, 16:38
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

PicNick
10.10.2005, 16:38
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.

Xeus
10.10.2005, 16:41
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?

10.10.2005, 16:46
2) versuch es mal.

Xeus
10.10.2005, 16:51
@gast:

mich hät ja interessiert wie ich das am effektievsten mach

PicNick
10.10.2005, 17:00
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

Xeus
10.10.2005, 17:04
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.

PicNick
10.10.2005, 17:14
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

Xeus
10.10.2005, 17:27
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.

PicNick
10.10.2005, 18:54
Genau. Initialisieren ganz vorn und dann nach jeder Erstellung oder Prüfung.
Also , weiterhin viel Erfolg !

Xeus
10.10.2005, 19:09
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.

PicNick
10.10.2005, 19:31
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

Xeus
12.10.2005, 06:58
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

Xeus
21.10.2005, 08:55
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

Xeus
25.10.2005, 06:41
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

Xeus
25.10.2005, 13:04
erstmal vielen dank, aber eigentlich meinte ich die "Geräte" die ich über rs232 anspreche.