Hi,
ich werde mit meinem Code einfach nicht warm.
Im Grunde habe ich mich recht genau an das Datenblatt vom PIC16F193X
gehalten und dazu noch (zu Testzwecken) die C-Funktion von
http://www.hoelscher-hi.de zum einlesen von DMX-Werten verwendet.
Dabei wurde folgendes initialisiert:
BRG16=0;//16-Bit-Generator; -->Formel in Abhängigkeit von BRGH beachten!!
27
28
SREN=0;//TODO: no effect
29
TXIE=0;//disable tx interrupts
30
RX9=0;//8-bit reception
31
RCIF=0;//TODO: reset notwendig?
32
// //----RS232---
33
CREN=0;//TODO: reset notwendig?
34
CREN=1;//Empfänger einschalten
35
SYNC=0;//Asyncronmodus
36
SPEN=1;//Seriellen Port einschalten
37
//
38
// ABDEN = 1; //Automatische Erkennung der Baoudrate
39
//
40
RCIE=1;//RCIE Interrupt einschalten
41
PEIE=1;//Peripheral
42
init_DMX_RX();//Alle DMX-Kanäle mit "0" belegen
43
}
44
45
voidinit_system(void)
46
{
47
GIE=0;
48
init_IO();
49
init_USART();
50
init_Timer();
51
init_PWM();
52
CPD_OFF;//TODO: Wirkung? (Defaultwert?)
53
WDTE_OFF;//TODO: Wirkung? FIXME: CLRWDT(); muss dennoch aufgerufen werden!?!
54
BOREN_OFF;//TODO: Wirkung? (Defaultwert?)
55
CLKOUTEN_OFF;//TODO: Wirkung? (Defaultwert?)
56
GIE=1;
57
}
Ich habe hier nur Mal die Werte gepostet, die ich für relevant halte.
Da die PWM-Ausgabe bereits Fehlerfrei im 8-Bit Betrieb funktioniert,
kann ich auch mit Sicherheit sagen, dass der unten aufgelistete ISR
aufgerufen wird. (An verschiedenen Stellen im Code habe ich einfach eine
der drei Farben aufleuchten lassen):
1
voidinterruptISR()
2
{
3
//Prüfen, ob der Interrupt von USART aktiviert ist dieser übergelaufen ist
4
if(RCIE&&RCIF)
5
{
6
//FIFI ISR
7
CLRWDT();
8
decode_DMX();
9
CLRWDT();
10
//Flag löschen, um Endlosschleifen zu vermeiden
11
RCIF=0;//FIXME: writeable??
12
}
13
....
Ich hoffe ich bekomme von Hendrik jetzt nicht einen auf den Deckel, da
ich hier seinen (als Free GNU General Public License) veröffentlichten
Code in (von mir) AVR-->PIC abgewandelter Form poste:
1
voiddecode_DMX(void)
2
{
3
new_DMXData=1;
4
uint8_tERROR=FERR;//FERR bit must be read before reading the RCREG
5
uint8_tDmxByte=RCREG;//get data
6
uint8_tDmxState=gDmxState;//
7
8
9
if(ERROR)
10
{
11
//FERR
12
DmxSkipValue=DmxAddress;//Startadresse holen
13
gDmxState=BREAK;
14
}
15
elseif(DmxState==BREAK)
16
{//Wir erwarten das Startbyte mit 0b00000000
17
if(DmxByte==0)
18
{
19
set_pwm(0,1,0,255);
20
gDmxState=STARTBYTE;//normal start code detected
21
//Pointer wird auf die zweite Array-Zelle gesetzt
22
gDmxPnt=((uint8_t*)DmxRxField+1);
23
}
24
elsegDmxState=IDLE;
25
}
26
elseif(DmxState==STARTBYTE)
27
{//Erster Kanal mit Nutzdaten auslesen
28
if(--DmxSkipValue==0)//Startaddress erreicht?
29
{
30
set_pwm(1,0,0,255);
31
gDmxState=STARTADR;
32
DmxRxField[0]=DmxByte;
33
}//"else": der Counter wurde nur verringert und die Daten verworfen
34
}
35
elseif(DmxState==STARTADR)
36
{//Kanal 2,3,4,...wird ausgelesen
37
uint8_t*DmxPnt;//lokaler Pointer...
38
DmxPnt=gDmxPnt;//lokalen Pointer
39
*DmxPnt=DmxByte;//Daten an diese Speicheradresse eintragen
So wie er hier gepostet ist bleibt bei 16Mhz alles dunkel :(
Ich habe ein auch shcon direkt in die if (ERROR){set_pwm(...)} die LED
Funktion geschrieben und das Licht ging an.
Doch ich denke, dass ein FERR bei jeder erdenklichen Baudrate zu stande
kommt.
Alternativ kam auf folgendes zum Test (habe sozusagen alle Formeldn für
250k durch):
FOSC/[16 (n+1)] 8Mhz-->SPBRG = 1; BRGH = 1; BRG16 = 0;
FOSC/[16 (n+1)] 8Mhz-->SPBRG = 1; BRGH = 0; BRG16 = 1;
FOSC/[16 (n+1)] 16Mhz-->SPBRG = 3; BRGH = 1; BRG16 = 0;
FOSC/[16 (n+1)] 16Mhz-->SPBRG = 3; BRGH = 0; BRG16 = 1;
FOSC/[4 (n+1)] 8Mhz-->SPBRG = 7; BRGH = 1; BRG16 = 1;
FOSC/[4 (n+1)] 16Mhz-->SPBRG = 15; BRGH = 1; BRG16 = 1;
Jetzt frage ich mich, ob es möglich ist an die stelle im ISR bei der
"RCREG" ausgelesen wird ein Breakpoint zu setzen und zu debuggen, was
dort rein kommt?
Falls ja, läuft der EUSART vom PIC dann beim debuggen in echtzeit,
sprich sind die Kalkulationen für die Baudrate etc. richtig?
Oder gibt es irgendwie eine andere Möglichkeit das ganze zu überprüfen?
[Ich danke an dieser Stelle schon Mal für die Bemühungen das ganze zu
lesen!
Falls noch etwas zur Diagnose fehlt, liefere ich es gerne nach)
Es dürfen sich auch gerne Leute aus der Region 27***/28*** melden, die
Zeit und Lust haben mir den Kram live für 2 Kästen Bier oder so zu
fixen. Denn nach 16Std. dauergrübeln sollte ich so langsam Mal auf die
Problematik gestoßen sein grr PM ;) ]
Grüße Oekel
D a v i d K. schrieb:> Jetzt frage ich mich, ob es möglich ist an die stelle im ISR bei der>> "RCREG" ausgelesen wird ein Breakpoint zu setzen und zu debuggen, was>> dort rein kommt?>>>> Falls ja, läuft der EUSART vom PIC dann beim debuggen in echtzeit,>> sprich sind die Kalkulationen für die Baudrate etc. richtig
Was hat die Baudrate mit Debuggen und Breakpoint zu tun...habe es im
Nachbarthread versucht zu erklären, scheint aber nicht angekommen zu
sein...
Bevor du mit dem Debugger im Nebel herumstocherst (denn offensichtlich
hast du davon eher wenig Ahnung) solltest du mal testen, ob deine EUSART
überhaupt mit 250 kBaud eine Verbindung zu einem Terminalprogramm
bekommt - wie z.B. "HyperTerm" o.ä.
Also Minianwendung mit EUSART-Initialisierung und einer Schleife welche
1 Zeichen vom Terminal einliest und dieses wieder retour sendet.
Pegelanpassung an Schnittstelle nicht vergessen (MAX2323 etc).
Vielleicht!!! funkteoniert das sogar mit dem internen Oszillator.
Bevor so etwas "primitives" nicht läuft, brauchst du keine DMX-Routine
testen.....
Chris B. schrieb:> Bevor du mit dem Debugger im Nebel herumstocherst (denn offensichtlich> hast du davon eher wenig Ahnung) solltest du mal testen, ob deine EUSART> überhaupt mit 250 kBaud eine Verbindung zu einem Terminalprogramm> bekommt - wie z.B. "HyperTerm" o.ä.
Habe nun endlich einen MAX232N gefunden und das vorgeschlagene
ausprobiert.
Hyperterminal gibt es bei Win leider nicht mehr, daher habe ich
puttytel, hterm und realter genommen.
In einer Richtung klappt es auch, jeder Buchstabe, den ich ins Terminal
tippe kommt auch im Debug-Register zurück. Ein echo bekomme ich aus
irgendeinem Grund nicht hin. (Brauche ich ja aber auch nicht)
Mein Problem ist nun aber, dass ich die 250k nicht testen kann (siehe
Anhang), da der Port am Rechner sich nicht darauf konfigurieren lässt.
wie kann ich nun weiter testen und warum kann der Port diese Rate nicht?
Grüße Oekel
Schön und gut, aber durch die Verwendung einer anderen Software wird
sich die Hardware des Ports nicht ändern. Die frage lautet ja, warum
sich der Port nur mit diesen geringen Raten unter Windows konfigurieren
lässt. Ist dort wirklich eine Begrenzung oder brauche ich nur andere
Treiber?
Kann ich evtl. Glück haben, dass der Port eines anderen Rechners mehr
Baud kann oder sollte ich sogar das OS wechseln? Oder sollte jeder
Rechner mit jedem Betriebsystem 250k Baud schaffen?
Grüße Oekel
D a v i d K. schrieb:> Die frage lautet ja, warum>> sich der Port nur mit diesen geringen Raten unter Windows konfigurieren>> lässt.
Das liegt an den verwendeten Terminalprogrammen.
Mein PC ist ein ordinärer "noname" PC in der 300€ Preisklasse, der
schafft 1000kBaud - wenn sich das Terminalprogramm darauf einstellen
läßt und HT tut das.
Win7, keine extra Treiber oder sonstigen PiPaPo.
Chris B. schrieb:> Das liegt an den verwendeten Terminalprogrammen.> Mein PC ist ein ordinärer "noname" PC in der 300€ Preisklasse, der> schafft 1000kBaud - wenn sich das Terminalprogramm darauf einstellen> läßt und HT tut das.
Und ich hatte mich schon so gefreut, doch es klappt NICHT.
Habe mir HyperTerminal runtergeladen uns auf Win7 ausgeführt sowie einen
alten Rechner mit original XP gestartet.
BEIDE Hyperterminals zeigen mir NUR die im Anhang (s.o.) ersichtlichen
Raten.
Nirgends steht 250000
230400 und 460800 währen als nächstes verfügbar, doch auch diese
verweigern den Dienst mit der Meldung:
"Unable to open COM1. Please check your port settings"
erst bei Raten 115200 funktioniert es und ich bekomme ein "Zeichen",
sobald ich RX und TX "kurzschließe".
Habt ihr noch eine Idee?
Grüße Oekel
PS: Es handelt sich bei mir um das P5W DH Deluxe (ein nicht ganz so
günstiges Board von Asus)
[[Beitrag "RS232 - hohe Baudrate"]]
Ich denke Mal, dass ihr mit eurer Hardware einfach nur Glück gehabt
habt.
Werde Mal sehen, ob ich hier irgendwo einen Adapter auftreiben kann.
Ist aber schon ärgerlich, dass so etwas on-Board existiert, zumal Mal
wieder keiner im Support-Center von Asus Bescheid wusste.
Falls doch noch Jemand weißt, wie ich den
"Intel(R) 82801GB/GR (ICH7-Produktfamilie) LPC-Schnittstellencontroller
- 27B8" dazu überredet bekomme 250000 zu produzieren, möge er sich bitte
melden.
Grüße Oekel
Ich muss noch Mal um eure Hilfe bitten.
Ich habe zwar immer noch keinen comport mit 250k auftreiben können, doch
ist das Vorgehen der Routinen ja auch bei einer Baudrate von 9600
dasselbe.
ergo bin ich den Code bei 9600 mittels eingabe von 00000000 (bei 4200
Baud für das Break) und 00000000 00000001 00000010 (bei 9600 Baud für
startbyte + 2 Kanäle) durchprobiert und erhalte die erwarteten werte in
meiner Variablen
DmxRxField[].
Soweit so gut, alles wieder auf 250k gestellt und an einem DMX-Sender
angeschlossen und bei:
1
valid_DMXData=1;//====BREAKPOINT====
einen Breakpoint gesetzt.
Nun erhalte ich AN diesem BREAKPOINT manchmal die richtigen Werte, was
mich davon überzeugt, dass die baudrate richtig eingestellt ist!??
Doch dann einige Schleifen lang DmxRxField[0] = DmxRxField[1] = 0 usw.
jetzt meine Theorie: Wenn die Baudrate hin und wieder nicht sauber wäre
(aufgrund des internen osc) würde ich doch erst garnicht so weit im Code
kommen! (Also bis zum Breakpoint)
Sieht von euch Jemand den Fehler? (hier noch Mal der Code:)
1
voiddecode_DMX(void)
2
{
3
new_DMXData=1;
4
uint8_t_FERR=RCSTAbits.FERR;//FERR bit must be read before reading the RCREG
5
uint8_t_OERR=RCSTAbits.OERR;
6
uint8_tDmxByte=RCREG;//get data AND clear FERR
7
uint8_tDmxState=gDmxState;//
8
9
10
if(_OERR)
11
{
12
RCSTAbits.CREN=0;//Overrun error (can be cleared by clearing bit CREN)
13
RCSTAbits.CREN=1;
14
}
15
if(_FERR)
16
{
17
//FERR stellt hier das BREAK da, welches sich von 0b00000000b11 durch die fehlenden Stopbits am Ende unterscheidet
18
DmxSkipValue=DmxAddress;//Startadresse holen
19
gDmxState=BREAK;
20
}
21
elseif(DmxState==BREAK)
22
{//Wir erwarten das Startbyte mit 0b00000000
23
if(DmxByte==0)
24
{
25
gDmxState=STARTBYTE;//normal start code detected
26
//Pointer wird auf die zweite Array-Zelle gesetzt
27
gDmxPnt=((uint8_t*)DmxRxField+1);
28
}
29
elsegDmxState=IDLE;
30
}
31
elseif(DmxState==STARTBYTE)
32
{//Erster Kanal mit Nutzdaten auslesen
33
if(--DmxSkipValue==0)//Startaddress erreicht?
34
{
35
gDmxState=STARTADR;
36
DmxRxField[0]=DmxByte;
37
}//"else": der Counter wurde nur verringert und die Daten verworfen
38
}
39
elseif(DmxState==STARTADR)
40
{//Kanal 2,3,4,...wird ausgelesen
41
uint8_t*DmxPnt;//lokaler Pointer...
42
DmxPnt=gDmxPnt;//lokalen Pointer mit globaler Speicheradresse versehen
43
*DmxPnt=DmxByte;//Daten an diese Speicheradresse eintragen
Nachtrag: wenn ich einfach die Werte 0 von einem Kanal abfange,
funktioniert alles wie gewollt. (auch ohne warnehmbare Verzögerung)
Dennoch muss da ja irgendwo ein Fehler sein, denn der Transmitter sendet
ja zwischendurch nicht zum Spaß Nullwerte auf allen Kanälen.
Oekel
Ich denke ich habe die Ursache ausfindig machen können, jedoch noch
KEINE Lösung für dieses. :((
Ich habe die Vermutung, dass meine Routine innerhalb der 512 Kanäle
nicht nur einen BREAK am Anfang ausfindig macht, sondern mitten in den
restlichen Kanälen ebenfalls fälschlicherweise ein oder mehrere
BREAKs/Framingerrors erkennt.
Zum testen habe ich bisher immer die Startadresse 1 genommen und auf den
5 Folgekanälen einen DMX-Wert von 128 und mehr ausgegeben. Alle
restlichen Kanäle standen auf 0.
Aufgrund meiner Vermutung habe ich nun Mal ALLE restlichen Kanäle auf 1
gestellt, um zu testen ob ich bereits durch die Veränderung der
"falschen Pause" von 0b00000000 auf 0b00000001 einen Unterschied
bemerke.
Und tatsächlich kann ich keinen "falschen Break" mehr erkennen.
Nun frage ich mich, ob dies durch die Missachtung des vom PIC
einstellbaren 9ten Bits sein kann, welches ja theoretisch das 1. von 2
Stopbits repräsentieren könnte.
Allerdings finde ich keinen logischen Zusammenhang, denn wenn mein
DMX-Sender 2 Stopbits sendet und mein Empfänger (PIC-CODE) nach nur
einem sucht, sollte er doch in Jedem Fall fündig werden. (Ergo kann ich
es ignorieren, dachte ich)
Kann es damit zusammenhängen? Wenn ja, bitte ich um Erläuterung.
Grüße Oekel
PS: Stimmt denn meine Vermutung überhaupt, dass ich die Baudradte
mitlerweile gut getroffen haben MUSS, da überhaupt Daten ankommen?
@ D a v i d K. (oekel)
>Ich habe die Vermutung, dass meine Routine innerhalb der 512 Kanäle>nicht nur einen BREAK am Anfang ausfindig macht, sondern mitten in den>restlichen Kanälen ebenfalls fälschlicherweise ein oder mehrere>BREAKs/Framingerrors erkennt.
Kann sein.
>Allerdings finde ich keinen logischen Zusammenhang, denn wenn mein>DMX-Sender 2 Stopbits sendet und mein Empfänger (PIC-CODE) nach nur>einem sucht, sollte er doch in Jedem Fall fündig werden.
Ja.
> (Ergo kann ich> es ignorieren, dachte ich)
Ja.
>PS: Stimmt denn meine Vermutung überhaupt, dass ich die Baudradte>mitlerweile gut getroffen haben MUSS, da überhaupt Daten ankommen?
Nein. Das kann auch Zufall sein. Ist es denn SOOO schwer, einfach
250kbit/s korrekt einzustellen?
Falk Brunner schrieb:> Nein. Das kann auch Zufall sein. Ist es denn SOOO schwer, einfach> 250kbit/s korrekt einzustellen?
Eigentlich nicht, denn ich habe ja das Datenblatt. (und auch die Formeln
verstanden)
Doch es gab hier ja Einige, die meinten, dass ich ohne externen Quarz
gar nicht erst weiter probieren brauch. Laut Formel habe ich einen
Abweichung von 0,0%. Daher müsste der interne OCR schon ziemlich falsch
gehen, wenn allein durch diesen eine so hohe Abweichung erzeugt wird,
dass alles für den A**** ist.
Grüße Oekel
@ D a v i d K. (oekel)
>Doch es gab hier ja Einige, die meinten, dass ich ohne externen quarz>garnicht erst weiter probieren brauch.
Würde ich auch nicht.
>Laut Formel habe ich einen>Abweichung von 0,0%.
Sicher, aber in der Formel ist die Taktquelle als exakt angenommen.
>Daher müsste der interne OCR schon ziemlich falsch>gehen, wenn allein durch diesen eine so hohe Abweichung erzeugt wird,>dass alles für den A**** ist.
Nimm einen Quarz(oszillator).
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
D a v i d K. schrieb:> die meinten, dass ich ohne externen Quarz>> gar nicht erst weiter probieren brauch. Laut Formel habe ich einen>> Abweichung von 0,0%.
Formel und Taschenrechner sind geduldig.
Wenn du eine niedrigere Baudrate ohne Probleme hinbekommst sollte es
auch für 250kBaud reichen.
Ich hätt einfach mal 20 Minuten investiert, einen Timer mit 1ms
aufgesetzt, damit einen Pin getoggelt und die erzeugte Frequenz
gemessen(dazu reicht der "Frequenzzähler" eines Multimeters).
Bei größerer Abweichung kann man mit dem OSCTUNE-Register am internernen
Oszillator "drehen".
Zumindest wäre damit die Baustelle "Baudrate" abgeschlossen!
(bei dem Projekt scheit es ja noch mehr Baustellen zu geben ;-) )
Chris B. schrieb:> gemessen(dazu reicht der "Frequenzzähler" eines Multimeters).
Ich habe leider nur ein Mittelklasse Multi. Diese Funktion habe ich
daran noch nie gesehen.
> Bei größerer Abweichung kann man mit dem OSCTUNE-Register am internernen> Oszillator "drehen".
Das Register habe ich bereits mehrmals anfassen wollen. Aber ohne
Messwerte schwierig.
> Zumindest wäre damit die Baustelle "Baudrate" abgeschlossen!> (bei dem Projekt scheit es ja noch mehr Baustellen zu geben ;-) )
Ja das stimmt leider, werdet bestimmt heute Abend noch etwas Gejammer
zum Thema 10Bit-PWM (8Bit funktioniert) und ADC hören ;)
Grüße Oekel
D a v i d K. schrieb:> Ich habe leider nur ein Mittelklasse Multi. Diese Funktion habe ich>> daran noch nie gesehen.
Mittelklasse???? Also in der 50€ Klasse haben die meisten nen
"Frequenzzähler" der 0,1% Genauigkeit schafft - das reicht für solche
Zwecke locker - aber ich möchte hier keinen Multimeter-Nebenschauplatz
aufmachen weil sonst gleich die Fetzen fliegen ;-)