PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 8bit Zahl seriell ausgeben...



flown
27.05.2005, 09:23
Hallo zusammen,

ich arbeite gerade an einem Projekt, 8bit Zahlen seriell über den PortA ausgeben muss.
Ich arbeite mit einem PIC18F452 mit einem 10MHz Oszi und habe die PLL aktiviert, das heisst also mit 40MHz (10MHz effektiv).

Mit meinem Code komme ich gerade auf lächerliche 200kHz und interessant wäre da schon um die 1MHz.
1MHz wäre nähmlich die max. Übertragungsgeschwindigkeit zu dem Endgeräte. (500ns Datenvorbereitung und 500ns Clockimpuls)
Deshalb auch die NOPs im code

Ich hoffe ihr könnt mir da mal Tips geben wie ich mein Prog schneller machen kann.

Vielen Dank schon im voraus

Hier noch mein Quellcode

bitmask --> muss zuerst den msb ausgeben darum '10000000'
writeBlock --> ist die 8bit zahl welche ich ausgeben muss
setData ist deklariert als bit
PIC_OUTPUT_RF_DATA ist fix gegeben durch PORTA RA2
PIC_OUTPUT_RF_CLK1 ist fix gegeben durch PORTA RA1

int i;
UINT8 bitmask = 0x80;
for(i = 0 ; i < 8 ; i++ )
{
if((writeBlock & bitmask) == bitmask)
{
setData = 1;
}
else
{
setData = 0;
}

PIC_OUTPUT_RF_DATA = setData;
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
PIC_OUTPUT_RF_CLK1 = 1;
writeBlock <<= 1;
PIC_OUTPUT_RF_CLK1 = 0;
}

Arexx-Henk
27.05.2005, 13:36
Hallo,

Bei 10MHz daurt einen instruction 100ns. So eine NOP daurt auch 100ns.

so bei

clock-ausgang hoch
NOP
NOP
NOP
NOP
clock-ausgang niedrich

daurt die clockpuls genau 500ns

dass 'for(i = 0 ; i < 8 ; i++ ) '

duart offensichtlich viel zu lange

ich weiss nicht wie dein compiler ein INTEGER interpretiert, vielleicht wie ein 16-bit variable, besser du nutzt fur 'i' ein 'char' oder 'unsigned char' denn diess ist immer 8-bit und beim hochzahlen von 0 bis 8 braucht nur eine byte addiert zu werden statt zwei bytes. Damit wird dass program schon scheller.

Vielleicht hilfts :mrgreen:

gruss

Henk

flown
27.05.2005, 13:49
Bin nun einwenig weitergekommen:

if( writeBlock & 0x80 )
{
PIC_OUTPUT_RF_DATA = 1;
}
else
{
PIC_OUTPUT_RF_DATA = 0;
}
asm(" NOP");
asm(" NOP");
PIC_OUTPUT_RF_CLK1 = 1;
asm(" NOP");
asm(" NOP");
asm(" NOP");
asm(" NOP");
PIC_OUTPUT_RF_CLK1 = 0;

dieser block mache ich 8 mal (für jedes bit einmal)
Jetzt bin ich bei einer Geschwindigkeit von ca 600kHz.

Nun ein Bit beim Pic zu setzten dauert genau eine Clockperiode.
Das if else braucht 6 Clockperioden

Damit ich auf 1MHz kommen würde müsste ich logischerweise das ganze in Assembler schreiben und die NOP's mit zwischenblöcken des nächsten IF, else Blockes auffüllen. So mache anstelle der nops schon das nächste IF ELSE und so würde ich auf die 1MHz kommen, aber leider bin ich nicht so gut in Assembler das ich ein IF in verschiedene Blöcke teilen kann respektive weiss nicht ob dies überhaupt möglich ist

Vielen Dank schon im voraus

mcs
27.05.2005, 13:58
HI!

Ich würde die ganze zeitkritische Routine komplett in Assembler schreiben (also auch die if's). Da kann man noch mal einiges mehr optimieren und 1 MHz sollte gehen.

mfG Matthias

flown
29.05.2005, 19:50
Da ich nicht gerade gut in assembler bin, bräuchte ich da eure hilfe. Habe mich da einwenig eingelesen und ich weiss nicht ob ich diesen Befehl richtig interpretiere:

BTFSC a , b
befehl 1
befehl 2

also kann ich mit 'a' das register auswählen und mit 'b' sagen welches bit er mit 0 vergleichen soll?

Wenn ja so könnte ich eine kleine Routine schreiben die wie folgt aussehen würde:

BTFSC writeBlock , 0
GOTO PIC_OUTPUT_RF_DATA_PUT_1
GOTO PIC_OUTPUT_RF_DATA_PUT_0

BTFSC writeBlock , 1
GOTO PIC_OUTPUT_RF_DATA_PUT_1
GOTO PIC_OUTPUT_RF_DATA_PUT_0

etc...

wenn ja, ich schreibe mein programm in c mit mplab und nun müsste ich ein assemblerprogramm aufrufen mit dem parameter writeBlock, wie kann ich das genau machen?

Vielen Dank

30.05.2005, 11:51
moin. mich würd interessieren welchen compiler du für c code in mplab nimmst. CCS, CC8E, C18 von Microchip?

flown
30.05.2005, 12:28
ich benutze den C18 compiler

the_Ghost666
30.05.2005, 13:42
ist der C18kostenpflichtig?

30.05.2005, 15:00
naja, du hast eine 30 tägige Testpase. Danach werden die Optimierungen abgeschalten, d.h. der Quelltext wächst an, aber, wenn man das in Kauf nimmt, ist er kostenlos.

MfG
Mobius

flown
30.05.2005, 17:15
kann mir niemand sagen wie ich in c eine assemblerfunktion aufrufe und zusätzlich noch ein parameter übergeben kann???

und zusätzlich reicht es mit mplab nur die funktion in assembler zu schreiben oder muss ich noch irgendwas einbinden?

vielen dank

mcs
31.05.2005, 14:36
du müsstest den übergabewert in eine extra variable in der funktion schrieben und die variable dann im asm-teil deiner funktion benutzen.

flown
31.05.2005, 17:24
schreibe es in c und zwar folgendermasse:

void testAssembler(UINT8 *writeBlock)
{
asm(" BTFSC r0 , 0x01 ");
asm(" BCF 0x0F80 , 0x01"); /* Port A bit 1 auf 1 */
asm(" BSF 0x0F80 , 0x01"); /* Port A bit 1 auf 0 */
}

ich erhalte mit *writeBlock ja die speicheradresse von meiner variable.

Und nun müsste ich es irgendwie machen das ich diese addresse irgendwie in den assemblercode einfügen kann. kurzgesagt wo jetzt r0 steht müsste die speicheraddresse von *writeBlock stehen... aber wie???

Merci