
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
Moderatorzy:Jacek Bogusz, procesorowiec, robertw, tomasz_jablonski, r-mik, Moderatorzy
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.
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.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
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;
}

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;
}
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.
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.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Witam....
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.
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
...
Piotrek
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 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.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 0 gości