Problem z bascomem

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
solar1
-
Posty: 14
Rejestracja: 27 kwie 2008, 8:05
Lokalizacja: Banino

Problem z bascomem

Post autor: solar1 » 31 maja 2008, 6:17

Witam czy moze mi ktos wyjasnic po "polsku" jak dziala komenda shiftout w bascomie ?
Staram sie napsac program ktory bedzie odpowiadal na zapytania "mastera" zgodnie z pinem zegarowym - nie korzystajc z uartu zaprogramowanym wzorcem... i tak :

Kod: Zaznacz cały

'$sim
$crystal = 16000000
$regfile = "m8def.dat"

Dim Wartosc(256) As Byte           'wzorzec w matrycy
Dim Dana As Byte
Dim Licze As Byte                       'do odliczania do osmiu
Dim Licznik As Single
Config Portb.0 = Input                  ' zczytuj impulsy z tad sygnal clock
Config Portd.2 = Input                    ' sygnal reset
Config Portb.1 = Output                  ' Wyjscie danych  output
Config Portb.2 = Output               ' wyjscie przelacznika 

'Set Portb.0                                   ' ustaw stan wysoki
Set Portd.2                                    'ustaw stan wysoki

Clok Alias Pinb.0                        ' przypisuje nazwy
Rest Alias Pind.2
Outpu Alias Portb.1

Do

If Clok = 1 Then   ' jezeli jest juz akcja pownno to byc tak - poberz wartosc z tablicy , zamien na bit wyslij
' Dana = Wartosc(licze)
'          gdzie , zegar, co            , w jaki sposob , opoznienie w uS
 'Shiftout Outpu , Rest , Wartosc(dana) , 0 , 8
 Shiftout Outpu , Rest , Wartosc(dana) , 0 , 1 , 20  ' wyplowa jeden bit co 20uS
    ' obroc to 8 razy i dopiero powieksz
  If Licze = 8 Then
   Incr Dana                     ' zwieksz o jeden liczebnik dla ablicy
  End If
End If

Loop
End

' wzorzec do przeslania
Wartosc(1) = &HA2                 ' pierwsza cyfra
Wartosc(2) = &H13
Wartosc(3) = &H10
Wartosc(4) = &H91
Wartosc(5) = &H46
'(....)
Wartosc(256) = &HFF
wiem ze sa bledy bo jeszcze nie dodalem licznika zliczajacego do osmiu
ale czy dobrze rozumiem ze w momecie gdy pojawi sie sygnal clk <1 logiczna>
poleceni shiftout wysle mi pierwszy bit z wartosc(n) potem kolejny i kolejny i kolejny ?
czy odrazu wysle caly bajt ?
w helpie jest opisane ze ostatnia wartosc jest to opoznienie w uS ale dla stanu wysokiego czy niskiego ? <tj ile trwa dany stan? >
Przynam sie ze w internecie malo jest informacji na temat shiftout...

[ Dodano: 2008-05-31, 09:14 ]
hmm chyna nie poprawnie zrozumialem jak to polecenie ma dzialac z tego cowidze w sy,ulatorze shiftout sam generuje sygnal zegara - ale mimo to w symulatorze wysylane liczby nie sa poprawne... nie moge dojsc czemu

Awatar użytkownika
grysek67
Użytkownik
Posty: 315
Rejestracja: 27 cze 2007, 6:34
Lokalizacja: Limanowa
Kontakt:

Post autor: grysek67 » 31 maja 2008, 9:07

Witam czy moze mi ktos wyjasnic po "polsku" jak dziala komenda shiftout w bascomie ?
Zawsze najlepiej wyjaśnia help
Przeznaczenie:

Wysuwa ciąg bitów pochodzący z określonej zmiennej.

Składnia:

SHIFTOUT pin_danych , pin_zegarowy , zmienna , opcje [, il_bitów , opóźnienie ]

gdzie:

pin_danych nazwa końcówki portu będącą linią wyjściową strumienia bitów,
pin_zegarowy nazwa końcówki portu będąca linią zegarową,
zmienna zmienna z której wysuwane będą bity,
opcje opcje,
il_bitów ilość wysuwanych bitów,
opóźnienie opóźnienie w mikrosekundach między kolejnymi bitami.
Opis:

Instrukcja ta podobnie jak SHIFTIN, może być używana do szybkiej transmisji szeregowej pomiędzy dwoma procesorami.
Pin_danych powinien być połączony z końcówką wejściową drugiego procesora, który jest odbiornikiem strumienia bitów. Pin_zegarowy w trybie MASTER generuje sygnał zegarowy synchronizujący transmisję. W trybie SLAVE jest on wejściem sygnału zegarowego pochodzącego z drugiego procesora.


Podana jako parametr zmienna może być dowolną – oprócz zmiennych bitowych! - zmienną języka BASCOM BASIC. Bity nadawane będą wysuwane właśnie z tej zmiennej.

Można podać ilość wysyłanych bitów, maksymalnie 255. Jeśli ten parametr nie występuje lub jest określony jako NULL, liczba bitów jest automatycznie określana na podstawie ilości bitów składających się na zmienną. Dla typu Byte będzie to 8 bitów a dla typu Word – 16.

Znaczenie liczby podanej jako parametr opcje, jest następująca:


0 najpierw bit MSB jest podawany przy niskim poziomie logicznym na końcówce zegarowej
1 najpierw bit MSB jest podawany przy wysokim poziomie logicznym na końcówce zegarowej
2 najpierw bit LSB jest podawany przy niskim poziomie logicznym na końcówce zegarowej
3 najpierw bit LSB jest podawany przy wysokim poziomie logicznym na końcówce zegarowej
Gdy liczba określająca opcję zostanie powiększona o 4, wtedy sygnał zegarowy nie będzie generowany i lina zegarowa będzie pełnić rolę wejścia zewnętrznego sygnału zegarowego (tryb SLAVE).

Jako opóźnienie normalnie używane są dwie instrukcje maszynowe NOP. Gdy częstotliwość zegara jest zbyt duża, można podać czas opóźnienia w mikrosekundach

ZbeeGin

Post autor: ZbeeGin » 31 maja 2008, 16:15

solar1 pisze:hmm chyna nie poprawnie zrozumialem jak to polecenie ma dzialac z tego cowidze w sy,ulatorze shiftout sam generuje sygnal zegara - ale mimo to w symulatorze wysylane liczby nie sa poprawne... nie moge dojsc czemu
Po pierwsze nie pisze się CONFIG PORTB.0 tylko CONFIG PINB.0. Określasz kierunki pracy końcówek portu a nie całego portu.
Po drugie nie definiuje się zawartości tablicy poprzez ciąg przypisań po słowie END. Gdyż po tej instrukcji nic się już nie wykona (oprócz wywoływanych procedur czy przerwań).

W symulatorze BASCOM-a nie będziesz widział co się dzieje podczas SHIFTOUT. Trzeba program (plik OBJ) wgrać do AVR Studio i tam dokonać symulacji w odpowiednim miejscu przełączając się na opcję "Disassembler" o oglądać stan portów podczas jej krokowego wykonywania.
Ponadto SHIFTOUT nie będzie za każdym wywołaniem wysyłał następnego bitu z danej komórki tablicy. Wyśle tyle bitów ile mu wpisałeś by wysłał.
Dodatkowo tablice zaczynają się od indeksu 1 a Dana na początku jest równa zero. Zatem BASCOM albo weźmie te dane "z powietrza" - czyli z komórki o adresie przed tablicą, albo z komórki o indeksie 256.

solar1
-
Posty: 14
Rejestracja: 27 kwie 2008, 8:05
Lokalizacja: Banino

Post autor: solar1 » 31 maja 2008, 18:11

ok dokonalem pewnych poprawek , zaladowalem plik obj do avr studio - i sie teraz zastanawiam czemu procesor startuje w tak dlugim czasie .. czy mozna skrocic czas startu procesora ? (teraz mam 6800 cykli)
shiftout - nie do konca zrozumialem jak dziala ta instrukcja z tad moj blad - pin zegarowy to jest pin ktory Generuje zegar a nie czeka na podanie mu wartosci ... (chce wyslac dane z uC ale taktowac go z innego zrodla )
obmyslilem ze wykorzystam w tym celu pin przerwania zewnetrznego i dane bede se wysylal wlasnie w momecie gdy dostane przerwanie i teraz ( w skrocie )procedura wyglada tak :

Kod: Zaznacz cały

(...)
On Int0 Seriout                               ' wlacz przerwania
Enable Int0                                     ' i je ustaw
Enable Interrupts 
(...)
Seriout:                                                    ' przerwanie
   If Flaga = 1 Then                              ' jezeli masz zezwolenie to
     Iowy = Databyte.bitpointer              ' wyslij bit z bajta
     Incr Bitpointer
     If Bitpointer = 8 Then                     'wyzerruj go i zacznij zliczac od poczatku
       Bitpointer = 0                                  'Reset po
       Incr Dana                                        ' przesun sie w matrycy o 1 w gore
      Databyte = Wartosc(dana)             ' przypisz dane z tablicy do bita obrabianego
     End If
   End If                                                 
(...)
Return

ZbeeGin

Post autor: ZbeeGin » 31 maja 2008, 21:51

solar1 pisze:zaladowalem plik obj do avr studio - i sie teraz zastanawiam czemu procesor startuje w tak dlugim czasie .. czy mozna skrocic czas startu procesora ?
Można. $NORAMCLEAR załatwi sporą część tego czasu. Z tym, że nie zainicjowane zmienne będą na początku mieć wartości przypadkowe, a nie zero lub pusty ciąg.
solar1 pisze:pin zegarowy to jest pin ktory Generuje zegar a nie czeka na podanie mu wartosci ... (chce wyslac dane z uC ale taktowac go z innego zrodla )
Przecież podane jest jak na tacy :evil: . Aż zacytuję sam siebie:
0 najpierw bit MSB jest podawany przy niskim poziomie logicznym na końcówce zegarowej
1 najpierw bit MSB jest podawany przy wysokim poziomie logicznym na końcówce zegarowej
2 najpierw bit LSB jest podawany przy niskim poziomie logicznym na końcówce zegarowej
3 najpierw bit LSB jest podawany przy wysokim poziomie logicznym na końcówce zegarowej
4 najpierw bit MSB jest podawany przy stwierdzeniu niskiego poziomu logicznego na końcówce zegarowej
5 najpierw bit MSB jest podawany przy stwierdzeniu wysokiego poziomu logicznego na końcówce zegarowej
6 najpierw bit LSB jest podawany przy stwierdzeniu niskiego poziomu logicznego na końcówce zegarowej
7 najpierw bit LSB jest podawany przy stwierdzeniu wysokiego poziomu logicznego na końcówce zegarowej
Zatem:
Gdy liczba określająca opcję zostanie powiększona o 4, wtedy sygnał zegarowy nie będzie generowany i lina zegarowa będzie pełnić rolę wejścia zewnętrznego sygnału zegarowego (tryb SLAVE).
Oczywiście należy wtedy poprawnie przypisać końcówki portów. Nie moża w SHIFTOUT zapisać PORTB.0 jako wejścia zegarowego w trybie SLAVE, gdyż nici z transmisji.
Tam gdzie wystawiasz dane: PORTx.y
Tam gdzie oczekujesz danych: PINx.y

To jest podstawowy błąd początkujących, że nie rozróżniają faktycznego działania portów w AVRach.

solar1
-
Posty: 14
Rejestracja: 27 kwie 2008, 8:05
Lokalizacja: Banino

Post autor: solar1 » 01 cze 2008, 7:07

Mam najnowszego bascoma i niestety w helpie w temacie shiftout nie ma nic na temat powiekszenia o 4 .... dlatego to mnie zaskoczylo <bardziej ufalem Helpowi i temu co w nim pisze niz to co jest napisane na forum.... przepraszam ? >
Pin i port ustawialem tylko dlatego zeby zobaczyc jakas transmisje w symulatorze .. z tad moje deklaracje

ZbeeGin

Post autor: ZbeeGin » 01 cze 2008, 10:08

solar1 pisze:Mam najnowszego bascoma i niestety w helpie w temacie shiftout nie ma nic na temat powiekszenia o 4 .... dlatego to mnie zaskoczylo <bardziej ufalem Helpowi i temu co w nim pisze niz to co jest napisane na forum.... przepraszam ? >
Niestety nie mam już starych helpów źródłowych, ale w poprzednich wersjach taka opcja jeszcze była. :roll: Obecnie ta opcja jest dostępna tylko dla operacji SHIFTIN.

Zatem rzeczywiście musisz to sobie napisać samemu.

solar1
-
Posty: 14
Rejestracja: 27 kwie 2008, 8:05
Lokalizacja: Banino

Post autor: solar1 » 11 cze 2008, 7:52

Hello !
Z braku czasu dopiero teraz wracam do tego problemu...
postanowilem napisac ten program od nowa ale uzywajac do tego celu SPI
...wydaje mi sie ze to bedzie bardziej "prawdilowe" podejscie do tego problemu napisalem sobie taki oto kodzik - i nie che zabardzo dzialac :

Kod: Zaznacz cały

crystal = 14745600 
$regfile = "m8def.dat" 
$noramclear 

Dim Databyte As Byte                                        'Data to send 

Config Spi = Hard , Data Order = Msb , Master = No      
Databyte = &HA2 


Do                                                          
Restore Dta1 
Read Databyte 
Spiout Databyte , 3 

Loop 
End 

Dta1: 
Data &H23 , &HA1 , &H91 , &H46 , &H0B , &H81 

Czy moge nie podlaczac lini MOSI ? zeby transmisja zaczela dzialac ?
teoretycznie jak podam stan niski na SS na CLK impulsy zegarowe to na MISO powinem miec dane prawda ?
.... niestety nic tam sie nie pojawia .. analizowalem to nawet fizycznym analizatorem stanow logicznych :) <bardzo fajne narzedzie!>

[ Dodano: 2008-06-12, 15:32 ]
A wiec po paru bojach - udalo sie ..mniejwiecej :
_ shiftout na piechote z zwenetrznym generatorem zegarowym _

Kod: Zaznacz cały

$crystal = 16000000
$regfile = "m8def.dat"
$noramclear

Dim Wartosc(10) As Byte                  ' ilosc wysylanych bajtow
Dim Databyte As Byte                      ' bajt wysylany
Dim Dana As Byte                            ' licznik
Dim Bitpointer As Byte                     ' wskaznik aktualnie wysylanego bitu

Config Pinb.1 = Output                                      ' I/O jako wyjscie danych
Config Pind.2 = Input                                       ' pin zewnetrznego zegara

Iowy Alias Portb.1

On Int0 Seriout                                             'przerwanie
Config Int0 = Rising                                      ' jak je wyzwalamy

'########## tabela z wysylanymi bajtami ##################
Wartosc(1) = &B10101010                              
Wartosc(2) = &B10101010                               
Wartosc(3) = &B10101010
Wartosc(4) = &B10001001
Wartosc(5) = &B01100010
Wartosc(6) = &B11010000
Wartosc(7) = &B10000001
Wartosc(8) = &B10101000
Wartosc(9) = &HFF
Wartosc(10) = &HFF
'#####\ustawiamy wartosci startowe ################
Dana = 1
Bitpointer = 0
Databyte = Wartosc(1)

nop
nop
nop
nop
Enable Int0
Enable Interrupts                         ' uruchamiamy przerwania

Do                                                          'Forever loop
Loop
End

Seriout:                                                    ' przerwanie
Disable Interrupts
        Iowy = Databyte.bitpointer                           'Send bit out
        Incr Bitpointer
        If Bitpointer = 8 Then                                'wyzeruj go i zacznij zliczac od poczatku
          Bitpointer = 0                                         'Reset po
          Incr Dana                                       ' przesun sie w bajtach wyjsciowych o 1 w gore
         Databyte = Wartosc(dana)                           ' przypisz dane z do bajta wsylanego
    End If
Enable Interrupts
Return


Program dziala dosc dobrze - z tym ze , pomiedzy wykryciem taktu zegara a reakcja uC mam 5,02uS opoznienia..
czy mozna dopiescic jeszcze ten program ?
a moze w bascomienie da sie osiagnac lepszych wynikow ?
... zegar dla megi jest maksymalny na jaki pozwala nota katalogowa... zastanawiam sie czy wogole mozna podkrecic atmege8 na np 20mhz.. albo czy to cos da ?

[/list]

ODPOWIEDZ