AT89c4051 i RC5

To forum jest dla wszystkich pasjonatów wiecznie młodych mikrokontrolerów '51. 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
Raflles
-
Posty: 77
Rejestracja: 06 sie 2005, 17:15
Lokalizacja: Tychy
Kontakt:

AT89c4051 i RC5

Post autor: Raflles » 15 mar 2006, 22:41

Witam !! Nie wiem co mam już z tym fantem zrobić więc zwracam się do szanownych forumowiczów o pomoc. Kombinowałem na wszystkie strony ale nic to nie dało. Problem jest następujący: Na listingu z BASOM 8051 w moim programie jest taki problem. Niby wszystko działa jeżeli do sterowania używa się przycisków. Program polega na tym że gdy wykonywana jest główna pętla programu to przyciskami wszystko da się sterować. Natomiast z pilota odbiornik, czy też mikrokontroler odbiera mi głupoty. Natomiast da się z pilota i przycisku przejść do podprogramu MENU i tam już zarówno pilot jak i przyciski działają prawidłowo. Nie mam pojęcia o co chodzi bo przecież oba programy mają tę samą strukturę i zadadę działania. Proszę bardzo o pomoc bo nie mam pojęcia co może być przyczyną takiego działania bo siedzę nad tym już tydzień i nic nie umiem wymyślić.

Poniżej przedstawiam kod nieszczęsnego programu:

Kod: Zaznacz cały


Config Lcd = 16 * 2
Config Timer1 = Timer , Mode = 1 , Gate = Internal
Deflcdchar 0 , 32 , 16 , 24 , 28 , 30 , 28 , 24 , 16
Deflcdchar 1 , 32 , 1 , 3 , 7 , 15 , 7 , 3 , 1

Dim M As Byte
Dim S As Byte
Dim H As Byte
Dim Vol As Integer
Dim Wartosc As Byte
Dim Flaga As Byte
Dim Subaddress As Byte
Dim Command As Byte
Dim Zmienna As Byte
Dim Ster As Byte
Dim Kod As Bit
Dim Wskaznik As Bit
Dim Wskaznik2 As Bit
Dim Funkcja As String * 14


Declare Sub Obslugatimera


Enable Timer1
Enable Int0
Enable Interrupts

On Int0 Recrc5
On Timer1 Zliczaj

I2cstart
I2cwbyte 130
I2cwbyte 0
I2cwbyte 212
I2cstart
I2cwbyte 130
I2cwbyte 1
I2cwbyte 212
I2cstart
I2cwbyte 130
I2cwbyte 2
I2cwbyte 246
I2cstart
I2cwbyte 130
I2cwbyte 3
I2cwbyte 246
I2cstart
I2cwbyte 130
I2cwbyte 8
I2cwbyte 206
I2cstop

Vol = -80
Wartosc = 212

Meni Alias P3.0
Up Alias P3.1
Down Alias P3.3
Selekt Alias P3.4
Wskaznik2 = 0

Do

Enable Interrupts

Set Meni
Set Up
Set Down
Set Selekt

If Kod = 1 Then
If Subaddress = 0 Then
Zmienna = Command
Kod = 0
Else
End If
End If


If Up = 0 Or Zmienna = 16 Then
Waitms 20
Gosub Starttimera
Gosub Volup
Zmienna = 0
End If
If Down = 0 Or Zmienna = 17 Then
Waitms 20
Gosub Starttimera
Gosub Voldown
Zmienna = 0
End If

If Meni = 0 Or Zmienna = 43 Then
Set Wskaznik2
Zmienna = 0
End If

If Wskaznik2 = 1 Then
Wait 1
Gosub Menu
End If

Gosub Zegar

Loop

End

Recrc5:

Disable Interrupts
Getrc5(subaddress , Command)
Kod = 1


Return

Starttimera:

Set Wskaznik
Flaga = 0
Stop Timer1
Load Timer1 , 0
Start Timer1

Return

Zegar:

I2cstart
I2cwbyte 162
I2cwbyte 2
I2cstart
I2cwbyte 163
I2crbyte S , Ack
I2crbyte M , Ack
I2crbyte H , Nack
I2cstop

H = Makedec(h)
M = Makedec(m)
S = Makedec(s)

Cls
If H < 10 Then
Locate 1 , 6
Else
Locate 1 , 5
End If
If M < 10 And S < 10 Then
Lcd H ; ":0" ; M ; ":0" ; S
Elseif M < 10 And S > 9 Then
Lcd H ; ":0" ; M ; ":" ; S
Elseif M > 9 And S < 10 Then
Lcd H ; ":" ; M ; ":0" ; S
Elseif M > 9 And S > 9 Then
Lcd H ; ":" ; M ; ":" ; S
End If

'If Wskaznik = 1 Then
'Lowerline
'Lcd "  Vol = " ; Vol ; "dB"
'Else
'If Kod = 1 Then
Lowerline
Lcd "S: " ; Subaddress ; "C: " ; Command
'End If
'End If

Cursor Off Noblink
Waitms 80

Return

Volup:

If Wartosc = 255 Then
Else
Vol = Vol + 2
Incr Wartosc
End If
Gosub Zapisz

Return

Voldown:

If Wartosc = 212 Then
Else
Vol = Vol - 2
Decr Wartosc
End If
Gosub Zapisz

Return

Zapisz:

I2cstart
I2cwbyte 130
I2cwbyte 0
I2cwbyte Wartosc
I2cstart
I2cwbyte 130
I2cwbyte 1
I2cwbyte Wartosc
I2cstop

Return

$large

Sub Obslugatimera

Incr Flaga
Waitms 1
If Flaga = 70 Then
Reset Wskaznik
Flaga = 0
End If

End Sub
Return


Zliczaj:

Call Obslugatimera

Return

Menu:

Ster = 3

Do

Enable Interrupts

Set Meni
Set Up
Set Down
Set Selekt

If Kod = 1 Then
If Subaddress = 0 Then
Zmienna = Command
Kod = 0
Else
End If
End If

If Up = 0 Or Zmienna = 42 Then
Incr Ster
If Ster = 3 Then
End If
Zmienna = 0
End If

If Down = 0 Or Zmienna = 46 Then
Decr Ster
If Ster = 0 Then
End If
Zmienna = 0
End If

If Ster = 3 Then Funkcja = "Clock setup   "
If Ster = 2 Then Funkcja = "Trebble       "
If Ster = 1 Then Funkcja = "bas          "
If Ster = 0 Then Funkcja = "Sound mode    "

Cls
Locate 1 , 7
Lcd "Menu"
Gosub Dolnalinia
Waitms 80

If Meni = 0 Or Zmienna = 43 Then
Reset Wskaznik2
Zmienna = 0
Wait 1
End If

Loop Until Wskaznik2 = 0

Return

Dolnalinia:

Lowerline
Lcd Chr(0) ; Funkcja ; Chr(1)

Return


Awatar użytkownika
marcing
Użytkownik
Posty: 868
Rejestracja: 14 lut 2006, 14:13
Lokalizacja: z pociągu...
Kontakt:

Post autor: marcing » 16 mar 2006, 12:40

Witam!

Nie kasujesz bitu "Toggle" w poleceniach dotyczących RC5
Powinieneś następujący fragment wpisać tak:

Zmienna = Command And &B01111111

Druga sprawa - czy nie byłoby lepiej wykorzystać komendę Lookup do dekodowania rozkazów z pilota? Gdybyś połączył to z dekodowaniem klawiatury, mógłbyś wykorzystać jedną (wspólną) zmienną. Co prawda nie bawię się BASCOM-em, i korzystam z AVR-ków (asembler), ale takie działanie potrafi uprościć program.

Jeszcze jedno - używasz I2C. Ale dlaczego nie wykorzystujesz autoinkrementacji przy zapisie rejestrów?
Przecież zapis:


I2cstart
I2cwbyte 130
I2cwbyte 0
I2cwbyte 212
I2cstart
I2cwbyte 130
I2cwbyte 1
I2cwbyte 212
I2cstart
I2cwbyte 130
I2cwbyte 2
I2cwbyte 246
I2cstart
I2cwbyte 130
I2cwbyte 3
I2cwbyte 246
I2cstart
I2cwbyte 130
I2cwbyte 8
I2cwbyte 206
I2cstop


Można zrobić tak:


I2cstart
I2cwbyte 130
I2cwbyte 0
I2cwbyte 212
I2cwbyte 212
I2cwbyte 246
I2cwbyte 246
I2cstart
I2cwbyte 130
I2cwbyte 8
I2cwbyte 206
I2cstop


Pozdrawiam!

Marcin G.

Raflles
-
Posty: 77
Rejestracja: 06 sie 2005, 17:15
Lokalizacja: Tychy
Kontakt:

Post autor: Raflles » 16 mar 2006, 20:09

Witam !! Dzięki za podpowiedź. Niestety to nie zdało egzaminu. Dodawałem &B00011111 i do adresu urządzenia i do bajtu danych, i nic żadnej reakcji, wszystko działało tak samo. Nawet zmieniłem kwarc z 11 do 12 MHz no o tyle większy niestety udało mi się dzisiaj kupić. Spróbuję jeszcze kupić 24MHz. A z komendą Lockup niestety nie wiem o co chodzi. nie używałem jej nigdy. Problem polega na tym że mimo wysyłania z pilota komend odbierane są inne komendy. Adres pilota się zgadza. Zawsze jest 0 bo taki adres ma pilot. Jest jeszcze jedno. Jak nie wysyłam podczerwienią danych z pilota to wyświetlane są adres 21 i komenda 21. A jeśli chodzi o to co odbiera procesor to wygląda to następująco:

BCD Bit pilot odbiera:
0 0000 2
1 0001 2
2 0010 2
3 0011 2
4 0100 5
5 0101 5
6 0110 5
7 0111 5
8 1000 9
9 1001 9
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
16 10000 16
17 10001 17
18 10010
19 10011

Może to komuś rozjaśni w głowie. Sam cały czas się zastanawiam czy są tutaj jakieś prawidłowości.

Pozdrawiam i proszę o pomoc !!

[ Dodano: 16-03-2006, 23:33 ]
Witam !!!
Jak by to się kiedyś komuś miało przydać to powiem, że rozwiązałem swój problem.

Tak na marginesie to kiedyś gdzieś przeczytałem, że BASCOM jest złym językiem do programowania mikrokontrolerów, bo programista nie dowie się co dzieje się w mikrokontrolerze, czyli chodzi o działanie układów wewnętrznych i rejestrów.

Więc mój problem polegał na tym, że program był, czy jest napisany prawidłowo, natomiast została przeze mnie przekroczona objętość dostępnej pamięci RAM. Błędne wyświetlanie komend było spowodowane tym, że instrukcja GETRC5 w Bascomie wykorzystuje 30 bajtów stosu, który znajduje się w zakresie pamięci RAM i nie umiał pomieścić dwóch ostatnich bitów sygnału wysyłanego z odbiornika podczerwieni.

Po usunięciu w moim programie zmiennej string która zajmowała 14 bajtów RAM pilot zaczął działać "Jak Bóg przykazał" :)

Co nie zmienia faktu, że nie mam pojęcia jak napiszę ten program bez zmiany mikrokontrolera na większy. :(((((

Awatar użytkownika
marcing
Użytkownik
Posty: 868
Rejestracja: 14 lut 2006, 14:13
Lokalizacja: z pociągu...
Kontakt:

Post autor: marcing » 17 mar 2006, 12:50

Witam ponownie!

Widzę, że jeden problem rozwiązany ;)
Pozostała jeszcze optymalizacja - czyli np. usunięcie zbędnych odwołań do I2C (przykład wyżej).
Nie wiem, czy potrzebne jest wyświetlanie sekund? Gdybyś z niego zrezygnował, zyskałbyś kilka bajtów RAM potrzebnych na zmienną. Same zliczanie sekund jak najbardziej może być realizowane, ale w tle. Wtedy można zerować licznik sekund przy ustawianiu minut.
Przy obsłudze przycisków można odczytywać cały port, do którego są one podłączone.

Co do komendy LOOKUP() - opisana jest czytelnie w pomocy do BASCOM-a. Jeśli nie "trawisz" angielskiego, skorzystaj z pliku pomocy napisanego przez Zbigniewa Gibka
(ZBeeGin).
W zasadzie cała logika tego polecenia jest w tym, że pobiera element o numerze podanym jako pierwszy argument z tablicy podanej jako drugi argument. Przekazuje wynik do zmiennej:

zmienna=LOOKUP(nr_elementu, tablica)

Warto skorzystać również z "Mikroprocesorowej Oślej Łączki" - co prawda dotyczyła innego uP, ale zasady programowania (algorytmy) są dosyć podobne.

Pozdrawiam!

Marcin G.

Raflles
-
Posty: 77
Rejestracja: 06 sie 2005, 17:15
Lokalizacja: Tychy
Kontakt:

Post autor: Raflles » 26 mar 2006, 23:16

Witam !!

Ok już rozumiem o co chodzi w komendzie Lookup, ale w pomocy jest opisane jej działanie tylko odnośnie polecenia DATA. Mógłby mi ktoś wyjaśnić o co chodzi dokładnie ??
Piszę program, który już zajmuje prawie całą pamięć uPC a jestem dopiero przy 70% tego co chciałem tam zaimplementować.

Pozdrawiam !!

ZbeeGin

Post autor: ZbeeGin » 28 mar 2006, 18:22

Lookup przecież musi gdzieś "looknąć" by pobrać dane. Dlatego kompilator BASCOM udostępnia polecenie DATA - między innymi. Jeśli napiszesz:

Kod: Zaznacz cały

_dane:
  DATA 1, 2, 3, 4
To w pamięci flash pod adresem reprezentowanym przez etykietę _dane zostaną umieszczone 4 kolejne bajy, w których znajdą sie liczby 1, 2, 3, 4 w postaci dwójkowej.

Jeśli teraz napiszesz:

Kod: Zaznacz cały

A = LookUp(2, _dane)
to w zmiennej A znajdzie się liczba 3, gdyż funkcja ta elementy liczy od zera.

----

:arrow: marcing: Nie tablica tylko etykieta. Nie wprowadzaj kolegi w błąd. :mrgreen:
Ostatnio zmieniony 29 mar 2006, 5:45 przez ZbeeGin, łącznie zmieniany 1 raz.

Awatar użytkownika
marcing
Użytkownik
Posty: 868
Rejestracja: 14 lut 2006, 14:13
Lokalizacja: z pociągu...
Kontakt:

Post autor: marcing » 28 mar 2006, 22:33

ZbeeGin pisze:Arrow marcing: Nie tablica tylko etykieta. Nie wprowadzaj kolegi w błąd. Mr. Green
Racja, mój błąd :oops: w helpie jest "etykieta", tak samo p.Górecki w MOŁ nazywa to "etykietką".

:arrow: Raflles
Chodzi mi o to, że jeżeli stworzysz tablicę o 64 polach, a jednocześnie będziesz odczytywał port P3 nie jako pojedyńcze piny, tylko liczbę, możesz trochę uprościć sterowane. No i zaoszczędzić kilka bajtów. Np.:


If Kod=0 Then
Zmienna = P3 And &b00001111
Else
Zmienna=LOOKUP(zmienna, Kodyklaw)
' ^odwołanie do etykiety, za którą znajduje się tablica z kodami odpowiadającymi stanom portu P3 po wciśnięciu klawisza
If Zmienna=&b0001 Then ' zastępuję odwołanie do przycisku Meni
Set Wskaznik2
Zmienna = 0
Wait 1
Gosub Menu
End If
If Zmienna=&b0010 Then ' Zastępuję odwołanie do przycisku Up
Waitms 20
Gosub Starttimera
If Wartosc = 255 Then
Vol = Vol + 2
Incr Wartosc
End If
Gosub Zapisz
Zmienna = 0
End If
If Zmienna=&b0100 Then ' Zastępuję odwołanie do przycisku Down
Waitms 20
Gosub Starttimera
If Wartosc = 212 Then
Vol = Vol - 2
Decr Wartosc
End If
Gosub Zapisz
Zmienna = 0
End If
...
...
' Poniżej tablica z kodami klawiszy w na klawiaturze lokalnej - 64bajty, bo tyle jest możliwych rozkazów z pilota
Kodyklaw:
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,&b0001,&b0010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0,0,&b0010,&b0001,0,0,&b0100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


Zlikwiduj też niepotrzebne skoki do podprogramów - zaoszczędzisz zarówno pamięć RAM, jak i parę bajtów Flash. Przenieś większą część kodu do pętli głównej.
W Twoim programie jest też coś takiego:


If Wartosc = 212 Then
Else
Vol = Vol - 2
Decr Wartosc
End If
Gosub Zapisz

Chodzi o to "Else" - wszystko co jest PO tej komendzie wykona się JEŚLI Wartość będzie różna od 212. Prze ten element tracisz ok 4 bajty ROM (Flash) - o ile nie więcej. W asm będzie to wczytanie wartości zmiennej, porównanie, i skok do podprogramu wykonującego komendy po ELSE, gdy wartość jest różna, lub wykonanie skoku dalej gdy równa.

ODPOWIEDZ