Sida 1 av 1

SPI på PIC16F628A med USART

Postat: 25 april 2010, 15:22:25
av bos
Jag sitter med en 628a och försöker att få den att prata SPI med USART-modulen. Följande kod använder jag till mitt test:

Kod: Markera allt

#include <htc.h>

void main(void) {
    int foo;

    OSCF = 0;                                   // 4MHz INTOSC
    TRISA = TRISB = PORTA = PORTB = 0;

    SPBRG = 103;        // 9615 bps

    TXIE = GIE = 0;
    TXSTA = 0;
    CSRC = 1;   // Master mode
    SYNC = 1;  // Synchronous

    RCSTA = 0;
    SPEN = 1;  // Serial Port Enable

    TXEN = 1;
    while (1) {
        TXREG = 0b11001100;

        // some delay
        for (foo = 0; foo < 15000; foo++) {}
    }
}
Koden i sig fungerar, jag ser 11001100 på oscilloskopet, men kruxet är att en 1a ter sig som 0V och en 0a som 5V. När ingenting skickas är RB2 (DT) hög. Klockpinnen, RB1 (CK), beter sig som väntat.

I tidigare projekt har jag bit-bangat SPI, och då har jag kört allting lågt (0V) om inget är aktivt, och mina SPI-enheter har fungerat utan problem. I detta test har jag inte använt en extern SPI-enhet som tar emot datan från 628an, utan jag har bara läst av CK/DT med oscilloskop eftersom jag aldrig använt USART-modulen förut och ville bara undersöka hur den beter sig.

I 628ans datablad står det att om jag vill avbryta en sändning så ska jag sätta TXEN till 0, och då kommer DT/CK att sättas till high impedance. Nu vill jag ju inte avbryta något men jag vet inte vad det innebär att pinnarna sätts till high-Z, men det är den enda ledtråd jag kan hitta.

Min fråga, slutligen, lyder: Hur gör jag för att på DT-pinnen se en 1a som +5V och en 0a som 0V på oscilloskopet? Har jag konfiguerat USART-modulen fel eller har jag missat något annat?



(Fotnot: Hårdvaran för detta test består av en 628:a med WISP inkopplad. Inga övriga komponenter än ett motstånd på MCLR-pinnen och en konding över Vdd/Vss)

Re: SPI på PIC16F628A med USART

Postat: 25 april 2010, 15:39:10
av Icecap
Hi-Z betyder att utgången inte driver i någon riktning - varken '0' eller '1', den är rent elektrisk sett en ingång eller "bortkopplat" om du vill.

Re: SPI på PIC16F628A med USART

Postat: 25 april 2010, 15:45:09
av sodjan
> men jag vet inte vad det innebär att pinnarna sätts till high-Z

http://en.wikipedia.org/wiki/High-Z
http://en.wikipedia.org/wiki/High_impedance

> När ingenting skickas är RB2 (DT) hög.

Som jag tolkar databladet så ska den vara High-Z när ingen aktiv
sändning pågår, d.v.s i "receive" läge. CK ska däremot drivas, om
den är konfigurerad för intern klocka.

Sen så skulle nog jag skicka något annat än ett symetriskt möstner
("11001100"), det finns en liten risk att man läser av ett par bitar fel...
Något i stil med "11001110" eller något liknande.

Re: SPI på PIC16F628A med USART

Postat: 25 april 2010, 19:39:58
av bos
Tack för tipset. Att skicka åtta asymmetriska bitar fick mig att inse att jag läste av oscilloskopet från fel håll - LSB skickas ju först, inte MSB. Med andra är det inga fel alls, förutom läsfel.

>Som jag tolkar databladet så ska den vara High-Z när ingen aktiv
sändning pågår,

Var i databladet hittar jag detta? Jag tittar på figur 12-12 och 12-13 på sida 84, men där ser jag både hög och låg signal - samtidigt? - på RB1/DT.

Re: SPI på PIC16F628A med USART

Postat: 25 april 2010, 20:04:23
av bos
Fast, nu när jag läser om SPI-mode i SSP-modulen ser jag att MSB ska skickas först. Inte LSB, som USART-modulen i mitt test gör.

Då återupplivas frågan om det är jag som konfigurerat fel eller om USART alltid skickar LSB först och därmed inte kan användas för SPI. Det senare är med stor sannolikhet en felaktig premiss eftersom introduktionstexten till USART-modulen säger att det synkrona master-läget kan med fördel användas till SPI-enheter.

Jag hittar dock inget i TXSTA-registret där jag kan ställa in att MSB ska skickas först. För det kan väl knappast vara så att jag i mjukvara måste spegelvända alla bytes före de skickas?

Re: SPI på PIC16F628A med USART

Postat: 25 april 2010, 22:18:20
av sodjan
En annan fråga är ju varför du tror att du kan köra
SPI med hjälp av USART modulen alls. Var har du
fått det ifrån ?

> eftersom introduktionstexten till USART-modulen säger att det synkrona master-läget
> kan med fördel användas till SPI-enheter.

Det står det *INTE* i min kopia av databladet, och jag plockade just
ner det senaste (40044G) för att kolla. Det står:
...or it can be configured as a half-duplex synchronous system that
can communicate with peripheral devices such as A/D or D/A
integrated circuits, Serial EEPROMs, etc.
Alltså ingenting om SPI.

Ta en PIC-modell med en "riktig" SSP eller MSSP modul istället.

Re: SPI på PIC16F628A med USART

Postat: 26 april 2010, 00:42:33
av bos
>En annan fråga är ju varför du tror att du kan köra SPI med hjälp av USART modulen alls.

Bra fråga. Det går, iallafall, även om det inte går out-of-the-box.

Efter lite trixande på bitnivå går det nu utmärkt att prata SPI med USART. Såhär gjorde jag:

Kod: Markera allt

unsigned char from, to;
unsigned char reversebits(unsigned char b) {
    from = b;
    to = 0;

#asm
    movlw   7
loop
    rlf     _from
    rrf     _to
    addlw   -1
    btfsc   _STATUS, 0
     goto loop
#endasm

    return to;
}
Sen undrar säkert någon varför jag ska krångla såhär istället för att bit-banga direkt. Anledningen är att jag behöver interrupt-möjligheten som USART handahåller, och det går inte byta PIC i detta projekt. En PIC med MSSP-modul hade givetvis varit det absolut bästa på alla plan.

Re: SPI på PIC16F628A med USART

Postat: 29 april 2010, 15:35:46
av willmans
Om du inte har ont om programminne så finns det snabbare sätt att vända om bitarna. Den funktionen du visar tar ca 48 instruktioner att utföra.

Kod: Markera allt

;reverse bits
swapf   _reverseByte, w     ;efghabcd
xorwf   _reverseByte, w     ;efghabcd
                            ;abcdefgh
andlw   0x66                ;.fg..bc.
                            ;.bc..fg.
xorwf   _reverseByte, f     ;afgdebch
rrf     _reverseByte, w
rrf     _reverseByte, f     ;hafgdebc
andlw   0x55                ;.a.g.e.c
addwf   _reverseByte, f     ;h.f.d.b.
                            ;a.g.e.c.
rrf     _reverseByte, f     ;.h.f.d.b
                            ;.a.g.e.c
addwf   _reverseByte, f     ;ahgfedcb
rlf     _reverseByte, w
rlf     _reverseByte, f     ;hgfedcba


Tar 12 instruktioner att utföra, 4x snabbare 8)
Hämtad från (lite ändrad) http://www.piclist.com/techref/microchi ... evbits.htm

Re: SPI på PIC16F628A med USART

Postat: 29 april 2010, 16:23:00
av bos
Jag optimerade själv ner till följande:

Kod: Markera allt

rlf from
rrf to
rlf from
rrf to
(upprepa 4 ovanstående 4 gånger till)
Totalt 16 instruktioner. Fyra fler än din variant, men mer lättläst ;)

Tack för tipset iallafall. Kan säkert komma till användning framöver.