sdcc, 8031/8051 i avt2250

Jul 24, 2005 9 Replies

pisalem posta ju¿, ale mo¿e siê przypomne, bo siedze nad tym ju¿ kilka dni i nie mam ¿adnego pomys³u jak to zrobiæ, ¿eby dzia³a³ który kolwiek z liczników i przerwañ (1 lub/i 3) w wyniku przepe³nienia jednego z licznika. Niech mnie mo¿e kto¶ u¶wiadomi jak powinien wygl±daæ dzia³aj±cy kod, który dzia³a z przerwaniami. Chyba, ¿e to dzia³a a mam walnietego procka. Pisa³em program który sprawdza³ stan przepe³nienia licznika, tj sprawdza³em warto¶æ TF0 i ustawia³em jak±¶ liczbê na którym¶ wy¶wietlaczu i wychodzi³o na to, ¿e siê zapala³a, czyli znaczy ¿e siê przepe³nia i powinno zadzia³aæ przeranie a nie dzia³a. Mo¿e o czym¶ zapominam co trzeba ustawiæ?



Prosze pomó¿cie bo naprawde nie mam pomys³a na cokolwiek :( Pod spodem wklei³em kod zmodyfikowany ju¿ chyba milion razy.


#include "8051.h"



//adresy pod ktorymi jest wyswietlacz LED xdata at 0x4000 unsigned char liczba; xdata at 0x4001 unsigned char wyswietlacz;



//definicje liczb #define c0 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 #define c1 0x02 | 0x04 #define c2 0x01 | 0x02 | 0x40 | 0x10 | 0x08 #define c3 0x01 | 0x02 | 0x40 | 0x04 | 0x08 #define c4 0x20 | 0x40 | 0x02 | 0x04 #define c5 0x01 | 0x20 | 0x40 | 0x04 | 0x08 #define c6 0x01 | 0x20 | 0x40 | 0x04 | 0x08 | 0x10 #define c7 0x01 | 0x02 | 0x04 #define c8 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 #define c9 0x01 | 0x20 | 0x40 | 0x02 | 0x04 | 0x08 | 0x047 #define kr 0x80



char tab[11]={c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,kr}; unsigned char zn,cnt;



void obsluga(void) interrupt 1; //obsluga int T0 void obslug2(void) interrupt 3; //obsluga int T1



void main(void) { cnt = 0; //ustawiam wstepnie wyswietlacz zn = 0; //ustawiam liczbe TMOD = 17; //T0 i T1 16bit



//ustwaiam liczniki T1 i T0 TH1 = 0x80; TL1 = 0; TH0 = 0; TL0 = 0; //***



ET1 = ET0 = EA = 1; //ustawiam ogolne oraz T1 i T0 zezwolenie na przerwanie TR1 = 1; // 1 startuje licznik T1 - 0 zatrzymuje TR0 = 0; // 1 startuje licznik T0 - 0 zatrzymuje



while(1) //zapetlam dzialanie programu w nieskonczonosc { wyswietlacz = cnt; //ktory wyswietlacz LED aktywny liczba = tab[zn]; //jaka cyfre wyswietlic liczba = 0; //zgas liczbe



} }



void obsluga(void) interrupt 1 {



TR0 = 0; //zatrzymaj licznik T0 TH0 = 0; //ustawiam licznik starsze bity TL0 = 0; //ustawiam licznik mlodsze bity zn++; //zmien wskazanie na nastepna liczbe if (zn>9) zn=0; //jesli ma przekroczyc tab to zn 0 TR0 = 1; //wystartuj licznik



}

void obslug2(void) interrupt 3 { TR1 = 0; //zatrzymuje licznik T1 cnt++; //zmieniam nr wyswietlazca na ktorym bedzie //wyswietlona liczba TH1 = 0x80; //ustawiam licznik TL1 = 0; //ustawiam licznik TR1 = 1; //wlaczam licznik }



Liczniki masz ustawione prawidłowo i jedno z przerwań się generuje (drugie masz wyłączone).

Skąd wiesz czy nie działa ? sprawdziłeś pod jakimś symulatorem co się dzieje w programie ?

[...]

taka deklaracja powoduje, że tablica stałych niepotrzebnie ląduje w RAMie zamiast w pamięci programu. Poczytaj w instrukcji do swojego kompilatora jak umieścić tablice w pamięci programu

^^^^^^^^^^^^^^^^^^^^^^^^^

^^^^^^^^^^^^^^^^^^^^^^^^^^

W dwóch liniach które podkreśliłem najpierw zapalasz odpowiedni wyświetlacz, dopiero potem wystawiasz zawartość, by zaraz ją zgasić. Zupełnie bez sensu. Prawidłowo powinieneś

  1. wygasić wszystkie segmenty (zmienna wyświetlacz ?), inaczej będą widoczne prześwity między kolejnymi wyświetlaczami
  2. Wystawić odpowiednią wartość na wyświetlacz
  3. Zapalić odpowiedni wyświetlacz
  4. Poczekać spory kawałek czasu

Generalnie obsługę wyświetlania dynamicznego najlepiej umieścić w przerwaniu i wywoływać je raz na x ms. Przydałby się też schemat podłączenia wyświetlaczy (jak zapalasz segmenty, wyświetlacze).

ok

nie mam niestety symulatora, mo¿e co¶ polecisz?

oki popatrze, ale tak chyab tez powinno dzia³aæ?

to sie zgadza, s± prze¶wity, ale tylko wtedy kiedy kombinuje z przerwaniami, wtredy albo s± albo nie ma

ok narazie probuje zrobiæ cokolwiek, ¿eby zadzia³a³o przerwanie zeby zainkrementoa³o nawet jak±¶ zmienn±. i zeby nawet by³y prze¶wity ale, ¿eby dzia³a³o. Z tego co wiem to trzeba odczekaæ kolo 2ms z zapaleniem. Ale wpierw co¶ co spoeoduje dzia³aniem przerwania

dokumentacje ot tego cuda AVT umiescilem na:

formatting link
pdfach

a tak teoretycznie czy to ma szanse dzia³aæ tak jak napisa³em?

Poszukaj w archiwum grupy. Na stronie sdcc znalazłem coś takiego: "SDCC also comes with the source level debugger SDCDB, using the current version of Daniel's s51 simulator." Więc razem z pakietem powinieneś mieć jakieś narzędzie do debugowania.

Oczywiście, że będzie działać, tylko za jakiś czas się okaże, że zabraknie ci miejsca w RAMie.

Bo jak wyświetlasz to samo na wszystkich wyświetlaczach to skąd miały by się brać prześwity ?

W/g mojego symulatora przerwanie działa. A te 2ms to pewnie okres przerwania, a nie oczekiwanie na zapalenie.

Działać ma szanse, ale jakość tego działania jest raczej mierna.

Masz tutaj przerobiony program, który wyświetla stały napis:

#include "8051.h"

//adresy pod ktorymi jest wyswietlacz LED xdata at 0x4000 unsigned char liczba; xdata at 0x4001 unsigned char wyswietlacz;

//definicje liczb #define c0 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 #define c1 0x02 | 0x04 #define c2 0x01 | 0x02 | 0x40 | 0x10 | 0x08 #define c3 0x01 | 0x02 | 0x40 | 0x04 | 0x08 #define c4 0x20 | 0x40 | 0x02 | 0x04 #define c5 0x01 | 0x20 | 0x40 | 0x04 | 0x08 #define c6 0x01 | 0x20 | 0x40 | 0x04 | 0x08 | 0x10 #define c7 0x01 | 0x02 | 0x04 #define c8 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 #define c9 0x01 | 0x20 | 0x40 | 0x02 | 0x04 | 0x08 | 0x047 #define kr 0x80

#define Cryst 11059200 #define Refr 600 // czestotliwosc odswiezania #define Timer 65536-(Cryst/12/Refr)

char tab[11]={c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,kr}; char dispBuff[8];

void main(void) { char a;

TMOD = 0x01; //T0 - 16bit TL0 = Timer&256; TH0 = Timer>>8;

ET0 = EA = 1; //ustawiam ogolne oraz T1 i T0 zezwolenie na przerwanie TR0 = 1; // 1 startuje licznik T0 - 0 zatrzymuje

for (a=0;a<8;a++){ dispBuff[a]=tab[a]; // wyswietl po kolei 0,1,2...7 }

while(1); }

void obsluga(void) interrupt 1 { static char dispNr;

TL0|=Timer&256; // ta instrukcja powinna byc // wycieta przy optymalizacji // bo wynik dzialania to 0 TH0=Timer>>8;

liczba=0; // wygaszenie segmentów przed // zmiana wyswietlacza dispNr=(dispNr+1)&7; // numer wyswietlacza modulo 8 wyswietlacz=dispNr; // zapal kolejny wyswietlacz liczba=dispBuff[dispNr];// wyslij dana na wyswietlacz }

U mnie w symulatorze działa, sdcc nie mam więc nie sprawdzę, czy będzie działało u ciebie.

ps. Jak robisz crossposty to nie zapomnij ustawić FUTa na jedną z grup !

Witam Je¿eli u¿ywasz AVT2250, to nie zadzia³a ci ¿adne przerwanie. Przecie¿ AVT2250 posiada swój pseudo BIOS, a ten jest sterowany przerwaniami od T0. Aby wykorzystaæ to przerwanie nale¿y dopisaæ swój kod do istniej±cego i zezwoliæ na jego uruchomienie. Poniewa¿ w AVT2250 kod programu jest umieszczany od adresu 8000H wiêc aby przerwanie zadzia³a³o nale¿y do komórki systemowej 72H AVT2250 wpisaæ starszy bajt(np 80H, 99H czy 7FH itp.) adresu pod którym bêdzie umieszczona procedura obs³ugi przerwania. Zreszt± komórki RAM-u AVT2250 w zakresie 70-7FH s± zarezerwowane jako systemowe i nie odpowiednia zmiana ich warto¶ci prowadzi do "HELLO".

-- Pozdrowienia Zbych

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[...]

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

W tych dwóch miejscach, które zaznaczyłem powinno być 255 zamiast 256.

Witam Mnie się wydaje , że problem tkwi nie w samym programie ale w hardware tego kitu.Wydaje mi się , że w przestrzeni adresowej 0-XXXX znajduje się (EEP)ROM) z zapisanym programem monitora( coś jak bios) , a program jest ładowany do SRAM-u od adresu XXXX(chyba $8000) i monitor po załadowaniu programu do SRAM wywołuje go przez Lcall lub Ljmp.Nawet jeśli nasz świeżo załadowany programik włączy jakiekolwiek przerwania , to wektory do nich i tak są zapisane w (EEP)ROM-ie , a na co one wskazują ? ... Trzeba bliżej przyjrzeć dokumentacji.

Pozdrawiam Piotrek

Zbych snipped-for-privacy@wp.pl napisał(a):

No i jesteśmy w domu ;-)

Piotrek

U¿ytkownik "Zbych" snipped-for-privacy@wp.pl napisa³ w wiadomo¶ci news:dc012a$obg$ snipped-for-privacy@atlantis.news.tpi.pl...

ano wlasnie, to ma swoj bios. Jestem jeszcze moze zielony w pisaniu na tego typu rzeczy ale probuje cos dzialac. W miedzyczasie sprawdzi³em ten program co mi podes³a³e¶ i nic siê nie wy¶wietla. Zdaje sobei z teog sprawe, ¿e jest to miernie napisane to moje, ale z uwagi na moje pierwsze kroki w tym celu prosze przymknaæ oko i poprawiæ jak robie b³±d. Czyli rozumiem ze mam do 72H co¶ zapisaæ ¿eby to posz³o? Ewentualnie pozostaje mi æwiczenie na symulatroerze i przepa³ kilku ko¶ci EPROM poczym w robocie je kasowac :)

dzieki za wszelka pomoc i po¶wiecony czas

U¿ytkownik "Piotrek Sz." snipped-for-privacy@NOSPAM.gazeta.pl> napisa³ w wiadomo¶ci news:dc01nj$p7j$ snipped-for-privacy@inews.gazeta.pl...

ano pozosta³o moje pytanie amatorskie jak to zrobiæ, ¿eby to wreszcie zadzia³a³o by³ bym wtedy szcze¶liwy

zak³adam ze zrobic cos takiego typu sbit at 0x72 unsigned char cos;

cos = 0x80

? i w funkcji z interrupt 1 trzeba cos dodac? np using 1 albo co?

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required