Hallo Mikro-Freaks,
Ich habe wie im Anhang zu sehen einen uC(PIC18F4520) über portd (8bit)
mit einem CPLD(XC95288XL) verbunden.
Da ich 16bit-Register im CPLD mit diesen Daten füllen möchte ist nun
mein Plan diesen 8bit-Datenbus auf "virtuelle" 16bit zu erweitern (zmd.
in uC->CPLD -Richtung). Hierfür lege ich erst eine 8bit-Adresse auf den
Datenbus (adressCPLD=1 und chip select=1) und nachfolgend 8bit (lower
byte oder higher byte)(nur chip select=1).
Also folgende Reihenfolge (PIC):
1- Sende Adresse1
2- sende 8bit (lower byte)
3- sende Adresse2
4- sende 8bit (higher byte)
Mein PIC-Programm sieht folgendermaßen aus:
1
{
2
voidWrite_CPLD8(charpara,unsignedintadress)
3
4
////////
5
//first adress then byte
6
////////
7
8
//send adress
9
trisd=0x0;//portd=output
10
portd=adress;//8bit-adress on db
11
portb.2=1;//adressCPLD=1
12
portc.0=0;//CS=1
13
delay_us(10);//delay
14
portc.0=1;//CS=0
15
portb.2=0;//adressCPLD=0;
16
trisd=0xff;//portd=input
17
18
//send lower/higher byte
19
trisd=0x0;//portd=output
20
portd=para;//byte on db
21
portc.0=0;//CS=1, adressCPLD=0
22
portc.0=1;//CS=0
23
delay_us(10);
24
trisd=0xff;//portd=input
25
26
return;
27
}
Die Funktion wird also 2x für ein vollständiges Datenpaket aufgerufen.
Mein CPLD-Code ist noch in Abel geschrieben (musste leider auf einem
alten Projekt aufbauen), ich hoffe es gibt noch alte Hasen die damit
klarkommen:)
Das ganze scheint eig. auch einwandfrei zu funktionieren, allerdings
habe ich immer mal wieder Probleme bei der Übergabe. Die Framerate geht
dann kurzfristig auf 0 und erst danach auf den korrekten von mir
übergebenen Wert, dies geschieht ca. bei jeder 5. Übergabe. Ich sehe das
Problem darin, das bei den Zeilen
teils schon die Adresse erkannt wird aber noch keine byte-Daten auf dem
Datenbus liegen und er dadurch eine 0 einliest. Beim nächsten Durchlauf
liegen dann die Daten korrekt in byte_temp und er nimmt den Wert an.
Leider stehe ich gerade ein auf dem Schlauch wie ich hier eine korekte
Erkennung der Daten implementieren kann. Wäre nett wenn sich das mal
kurz jemand anschaut.
DANKE!
jey
Wozu brauchst du denn 8 Bit Adressen? Dein CPLD enthält doch nicht
einmal annähernd so viele MC wie du damit adressieren kannst.
Ich würde schlichtweg 2 Clocksignale nehmen: mit dem einen stopfst du
ein Byte in dein CPLD und mit dem anderen das andere Byte. Ferticht.
W.S.
W.S. schrieb:> Wozu brauchst du denn 8 Bit Adressen? Dein CPLD enthält doch nicht> einmal annähernd so viele MC wie du damit adressieren kannst.> Ich würde schlichtweg 2 Clocksignale nehmen: mit dem einen stopfst du> ein Byte in dein CPLD und mit dem anderen das andere Byte. Ferticht.>> W.S.
Richtig es werden wahrscheinlich max. 10 Adressen werden, allerdings
muss ich ja dem CPLD mitteilen welches Register gerade gefüllt werden
soll.
Wie meinst du das genau mit 2 Clocksignalen?
bko schrieb:> Was passiert denn genau, evtl. sowas?>>> Jey Soon schrieb:>>Also folgende Reihenfolge (PIC): | frame[15:8] [7:0]> ------------------------------------------------------>>1- Sende Adresse1 | alt alt>>2- sende 8bit (lower byte) | alt neu>>3- sende Adresse2 | alt neu>>4- sende 8bit (higher byte) | neu neu>> Beispiel> PIC | frame[15:8] [7:0]> -------------------------------------------> 1- Adresse1 | 0x00 0xFF <-- alter frame> 2- low-byte neu 0x00 | 0x00 0x00 <-- autsch> 3- Adresse2 | 0x00 0x00 <-- autsch> 4- high-byte neu 0x01 | 0x01 0x00 <-- neuer frame
genau das scheint zu passieren :/
when(adress[7..0]==[1,1,1,1,1,1,1,1]) then frame[7..0]:=byte_temp[7..0];
else frame[7..0]:=frame[7..0].FB;
when(adress[7..0]==[1,1,1,1,1,1,1,0]) then
frame[15..8]:=byte_temp[7..0];
else frame[15..8]:=frame[15..8].FB;
Du darfst die Frame-Daten nur übernehmen, wenn CS high ist !
when(adress[7..0]==[1,1,1,1,1,1,1,1] & CS == 1 & AddrCPL == 0) then
frame[7..0] := DB[7..0];
oder so ähnlich
Genau so habe ich es mir auch gedacht, allerdings scheint Abel die
Syntax zwar zu akzeptieren, allerdings führt der CPLD die
UND-Verknüpfung nicht richtig aus, es werden gar keine Daten mehr in
Frame geschrieben, da
nie erfüllt ist.
Wenn jemand weiss wie ich in Abel korrekt ein Register und ein Bit in
einer when-Anweisung als zwei Bedingungen miteinander verknüpfe wäre das
super, ich denke damit wäre das Problem erledigt (hoffe ich^^)
wenn tatsächlich dies passiert:
> Beispiel> PIC | frame[15:8] [7:0]> -------------------------------------------> 1- Adresse1 | 0x00 0xFF <-- alter frame> 2- low-byte neu 0x00 | 0x00 0x00 <-- autsch> 3- Adresse2 | 0x00 0x00 <-- autsch> 4- high-byte neu 0x01 | 0x01 0x00 <-- neuer frame
d.h. also wenn die frame [15:0] gleichzeitig anliegen
müssen, dann braucht du noch einen weiteren Zwischenspeicher
für das low-byte:
ich kann kein Abel aber evtl. müsste es so aussehen:
1
when(adress[7..0]==[1,1,1,1,1,1,1,1]) then temp2[7..0]:=byte_temp[7..0];
2
else temp2[7..0]:=temp2[7..0].FB;
3
when(adress[7..0]==[1,1,1,1,1,1,1,0])
4
then frame[15..0]:=[byte_temp[7..0],temp2[7:0]]; --syntax?