Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

SPI programowe dla 8051

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

SPI programowe dla 8051

Postautor: Sławek5 » 1 paź 2005, o 11:14

Mam funkcje wysyłającą bajt poprzez SPI ale programowy postaci

void LcdSend( unsigned char data_send )
{
unsigned char i;
i=8;
do
{
SPI_OUT=data_send&0x80;
data_send=data_send<<1;
CLK=1;
CLK=0;
}while(--i);
}
Zasada byłaby taka że najpierw wysyłany jest MSB.
Ale to nie działa za dobrze. Pierwszy bit tzn 7 nie jest wystawiany tylko nastepny.
Co tu jest nie tak. A może macie lepsze rozwiazanie (działajace i sprawdzone).

Jest to dla 8051 a napisane w RIDE'51.

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 paź 2005, o 11:33

Co znaczy zdanie z tym "pierwszy bit tzn. 7..." :)
Opisz dokładniej co się dzieje źle.

W ogóle to bardziej elegancko byłoby zastosować tu pętlę for zamiast do... while. No i np. krócej zapisywać bitshift:

data_send<<=1;

czy SPI_OUT to bit MOSI?

może coś takiego (na gorąco z głowy):

int i;
for(i=7;i>=0;i--)
{
SPI_OUT=(data_send & (1<<i))>>i;
CLK=1;
//moze tu jakies opoznienie?
CLK=0;
}

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 1 paź 2005, o 12:02

Oczywiscie SPI_OUT to MOSI.

Zobacz co generuje kompilator:

; FUNCTION _LcdSendCmd (BEGIN)
; Register R7 is assigned to parameter data_send

; R6 is assigned to i
; SOURCE LINE # 27
0004 7E08 MOV R6,#008H
0006 ?DO1:
; SOURCE LINE # 30
0006 EF MOV A,R7
0007 5480 ANL A,#080H
0009 24FF ADD A,#0FFH
000B 92B7 MOV SPI_OUT,C
; SOURCE LINE # 31
000D EF MOV A,R7
000E C3 CLR C
000F 33 RLC A
0010 FF MOV R7,A
; SOURCE LINE # 32
0011 D297 SETB CLK
; SOURCE LINE # 33
0013 C297 CLR CLK
0015 DEEF DJNZ R6,?DO1
0019 22 RET


Tam gzie jest napisane ; SOURCE LINE # 30 wykonuje ANL i ADD nastepnie wazna rzecz to mov SPI_OUT,c a dopiero później robi RLC. I faktycznie przy pierwszym przebiegu pętli nie wystawia bitu 7 prawidłowo zawsze jest 1 mimo ze przesyłam do funkcji 0, a dopiero przy nastepnym obiegu zmiena sie stan linii danych.

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 paź 2005, o 12:06

Spróbuj z moja pętelką i napisz czy działa :).

szymel
-
-
Posty: 212
Rejestracja: 16 sty 2005, o 16:42
Lokalizacja: Włocławek

Postautor: szymel » 1 paź 2005, o 16:55

...
Tam gzie jest napisane ; SOURCE LINE # 30 wykonuje ANL i ADD nastepnie wazna rzecz to mov SPI_OUT,c a dopiero później robi RLC. I faktycznie przy pierwszym przebiegu pętli nie wystawia bitu 7 prawidłowo zawsze jest 1 mimo ze przesyłam do funkcji 0, a dopiero przy nastepnym obiegu zmiena sie stan linii danych.
Witam.
Niestety , nie mogę zgodzić się z Twoim tokiem myślenia ;)
Poniżej "sporny" fragment kodu:

Kod: Zaznacz cały

... ; SOURCE LINE # 30 0006 EF MOV A,R7 0007 5480 ANL A,#080H //wyzeruj wszystkie bity w ACC , prócz najstarszego. 0009 24FF ADD A,#0FFH //dodaj do ACC wartość #FFH , czyli maksymalną wartość jaką można zapisać do ACC(bajtu).Jesli wynik dodawania przekroczy wartość #FFH - a tak się stanie , jeśli najstarszy bit w ACC był ustawiony(ACC=80H) - , to flaga C zostanie ustawiona(C=1) , w przeciwnum wypadku(ACC=0) flaga C zostanie wyzerowana(C=0) 000B 92B7 MOV SPI_OUT,C ...
Pozdrawiam
Piotrek

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 1 paź 2005, o 17:09

Masz rację mój błąd.
A to że nie było bitu 7 na poczatku to był inny błąd. - Wykryty i naprawiony.

Co do samej procedurki wysyłania bajtu to zobiłem jeszcze inaczej:
i=8;
do
{
if(data_send&0x80)
SPI_OUT=1;
else
SPI_OUT=0;
data_send=data_send<<1;
CLK=1;
CLK=0;
P1=i;
}while(--i);
Jest to może nieeleganckie ale naprawde generuje bardzo szybki kod. Moge polecić d szybkich transmisji, nie generuje ani ANL ani ADD.

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 paź 2005, o 18:44

Ale takich wyrażeń unikaj: data_send=data_send<<1;

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 2 paź 2005, o 09:25

Może masz rację, ale jak to zastąpić. Poprostu to mi przyszło do głowy.

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 2 paź 2005, o 09:57

Tak jak napisałem kilka postów wyżej: data_send<<=1;

W C istanieja zapisy skrótowe podstawowych operacji na tej samej zmiennej.
Np. zamiast pisać: x=x & 2 piszemy x&=2. Efekt ten sam. Dotyczy to wszystkich prostych operacji: +, -, *, /, <<, >>, %, &, |, ...

Wróć do „8051”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 70 gości