[ janko11 @ 16.08.2018. 10:27 ] @
Da li moze neko da mi da konkretan savet u vezi jednog problema? Naime, program treba da na displeju prikaze odredjenu poruku. Kada testiram program u simulatoru, sve savrseno radi, ali kada se program izvrsava na fizickom hardveru, dolazi do problema, ne ukljucuju se svi segmenti, samim tim poruka se ne prikazuje kako treba. Procesor je 80C32. DIP Switch su povezani na ulaz 74HC573, 74HC573 je povezan na P1 port procesora, takodje na P1 port procesora preko ULN2803 povezani su i displeji. Kombinacijom DipSWitch - eva prikazuje se odredjena poruka. Da li moze neko da mi pomogne oko datog problema, posto mi je potrebna pomoc? Hvala unapred svima na savetima i odgovorima.

ispleji su sa zajednickom anodom. Ima ih 6, ali se samo 5 ukljucuju i na njima se ispisuje poruka.
Navedeni program gde se ispisuje poruka izgleda ovako:
Code:

 void timer0(void) interrupt 1

  TH0=0xFC;
  TL0=0x66;
  switch(disp)
  {
    case 1:
       C=1;
       BB=1;  // OE=0 kod 573
       A=1;
       if(e0==1 && q4==0 && q5==0 && q6==0)  // proveri koji je switch pristisnut
          pom=1;
    break;
    case 2:
       C=1;
       BB=0;
       A=1;
       if(pom==1)
          displayDigit('S');
       delay(5);
    break;
    case 3:
       C=1;
           BB=0;
       A=0;
       if(pom==1)
          displayDigit('T');
       delay(5);
    break;
    case 4:
       C=0;
       BB=1;
       A=1;    
           if(pom==1)
          displayDigit('A');
       delay(5);
    break;
    case 5:
       C=0;
       BB=1;
           A=0;
       if(pom==1)
          displayDigit('R');
       delay(5);
    break;
        case 6:
       C=0;
       BB=0;
       A=1;
       if(pom==1)
          displayDigit('T');
      delay(5);
    break;
    }
    disp++;
    if(disp>6)
      disp=1;
}

// funkcija koja ukljucuje masku
void displayDigit(unsigned char cifra)
{
   switch(cifra)
   {
      case 'S': P1=0x6D; break;
      case 'T': P1=0x78; break;
      case 'A': P1=0x77; break;
      case 'R': P1=0x50; break;
   }
}

void delayTimer()
{
  TMOD&=0xF0;
  TMOD|=0x01;
  TH0=0xFC;
  TL0=0x66;
  TR0=1;
}


U prilogu dostavljam i semu
[ bogdan.kecman @ 16.08.2018. 11:19 ] @
ako ja dobro kontam ono gore desno je multiplexer 4051? dipovi idu kroz 573 ok (mogao si p1.7 da spojis na tacku, imas i tacku na 7seg-u i slobodan pin na uln-u :D kad vec pravis, mozda zatreba :D ), jasno sad sta si radio .. sto se hw dela tice ovo def nece da radi .. treba ti pullup na svim izlaznim pinovima sa U4, mozda treba jos nesto ali za pocetak bez pullup-a na U4 izlazu sigurno nece radi kako treba jel su floating izlazi, posebno je je pitanje kako ce se ponasa U2.OE (X7) ... tako da je to jedan od mogucih problema (koji simulator nece skoro nikad da pokaze)

e sad za sw .. ja nisam koristio '51 ima hiljadu godina a '31 mislim da nisam nikad :D tako da za delayTimer bem li ga .. sto se tice display-a ja bi to drugacije al sama funkcija bi trebalo da radi ... ovaj interapt - koliko se cesto poziva? da li van interapta nesto drugo radis?

jedan nebitan deo .. ovaj ++ mozes mnogo lepse da uradis umesto
Code:

    disp++;
    if(disp>6)
      disp=1;

zamenis samo jednom linijom, mnogo preglednije
Code:

    if(++disp>6) disp=1;


e sad, da se vratimo na realnost .. bilo bi zgodno da si minimalno iskomentarisao delove specificne za '31 ko ce da se seti sad cemu sluzi TH0 :D .. (mislim znam da je timer0 0xFC66 novi count value al .. sam moro pogledam datasheet ) ... ili jos bolje C, BB ? ovo su tvoji neki ili nesto mapirano?

Code:

       C=1;
       BB=1;  // OE=0 kod 573
       A=1;
...


ovo mora objasnis jbg... kako ja kontam trebalo bi da bude
1. spusti OE na U2 dakle posalji na P3.5, P3.6 i P3.7 keca (U4A-C selektuju X7 i spustaju OE na low)
2. prebaci P1 u READ
3. iscitaj P1
4. prebaci U4 da gadja "odgovarajucu cifru" (OE automatski ide high)
6. odradi displayDigit()
7. prebaci P2 na write
(ne secam se kako ide kod '51/'31 mozda 6 i 7 mora zamene mesta)


ja ne vidim da ti u kodu radis ista od ovoga (osim sto pozivas displaydigit)
[ janko11 @ 16.08.2018. 12:12 ] @
Interrupt se poziva na 1ms. Sto se tice A,BB i C stavio sam da je: sbit A=P3^5; sbit BB=P3^6; sbit C=P3^7; Tako da umesto P3^5=1, pisem A=1; Kolo U4 gore levo je multiplekser 4051. Da li to moze da bude problem sto nema pullup na svim izlazima 4051? TH0 i TL0 su registri tajmera T0 koji radi kao 16b - tni tajmer.

Da li mozes da mi das primer koda za ove stavke koje si napisao, da bi bolje razumeo, gde pravim gresku:
1. spusti OE na U2 dakle posalji na P3.5, P3.6 i P3.7 keca (U4A-C selektuju X7 i spustaju OE na low)
2. prebaci P1 u READ
3. iscitaj P1
4. prebaci U4 da gadja "odgovarajucu cifru" (OE automatski ide high)
6. odradi displayDigit()
7. prebaci P2 na write

Kako mislis da prebacim P1 u READ? Na pocetku programa P1 je inicijalizovano sa P1=0xFF.



[ bogdan.kecman @ 16.08.2018. 14:47 ] @
vidi sad jbg ja nisam radio sa '51 20 godina ... na modernim cpu/mcu ti bilo koji IO port mora postavis da bude ili read ili write ili hiz .... da bi iscitao vrednost porta ti ga samo citas i on sam postavi port na read ili moras rucno da postavis port na citanje?
[ janko11 @ 16.08.2018. 17:27 ] @
Kod 8051 da bi port bio ulazni, svi njegovi pinovi se postavljaju na 1, da bi port bio izlazni pinovi su postavljeni na 0. U interruptu u prvom prolazu postavljam OE=0 (P3.5=1,P3.6=1,P3.7=1), citam vrednost P1 i upisujem u neku promenljivu, u sledecem koraku ukljucujem displeje, ispitujem vrednost date promenljive (vrednost P1) i u zavisnosti od vrednosti te promenljive ispisujem poruku ili cifre na displeju, pa se zatim brojac
vraca ponovo da broji od pocetka. Da li pravilno razmisljam?
[ bogdan.kecman @ 16.08.2018. 22:54 ] @
Citat:
janko11: Kod 8051 da bi port bio ulazni, svi njegovi pinovi se postavljaju na 1, da bi port bio izlazni pinovi su postavljeni na 0.


nekaj mi tu smrdi?! kako ces da izbacis 0xFF, 0xFF na port ako kad postavis sve pinove na 1 postane HIZ (ulazni) ?!


Citat:
janko11:
U interruptu u prvom prolazu postavljam OE=0 (P3.5=1,P3.6=1,P3.7=1), citam vrednost P1 i upisujem u neku promenljivu, u sledecem koraku ukljucujem displeje, ispitujem vrednost date promenljive (vrednost P1) i u zavisnosti od vrednosti te promenljive ispisujem poruku ili cifre na displeju, pa se zatim brojac
vraca ponovo da broji od pocetka. Da li pravilno razmisljam?


vidi ti ne mozes da "ukljucis display-e" ... ti u interaptu palis/gasis display po display, znaci uvek samo jedan, ... imas problem u startu sa tajmingom za zadnji display posto ga mnogo brzo gasis koliko mi se cini... e sad nisam skonto sta je "poenta" ovoga, ti citas dip u svakom interaptu pre svake cifre ili hoces da citas jednom po prolazu za sve cifre?
[ janko11 @ 17.08.2018. 07:32 ] @
Kao sto si i rekao, u interruptu palim/gasim display po display. Pogresno sam bio rekao. U interruptu, prvo procitam dip, zatim palim/gasim display po display, pa zatim ponovo procitam dip, pa palim/gasim display po display. Da li je to dobro resenje? Kako mislis da zadnji display mnogo brzo gasim? Mozes li da mi pomognes da to ispravim?
[ goran_68 @ 17.08.2018. 08:44 ] @
Code:
delay(5);



Koliko traje ovo delay(5);
5us ili 5ms?
[ janko11 @ 17.08.2018. 08:50 ] @
Evo funkcije za delay(5):
Code:

void delay(unsigned int msdelay)
{
  unsigned int i,j;
  for(i=0;i<msdelay;i++)
  {
    for(j=0;j<100;j++);
  }
}


Da li mislis da je tu greska?
[ goran_68 @ 17.08.2018. 09:12 ] @
U prekidnoj rutini koja se izvršava na 1ms imaš kašnjenje od 5ms. To nije dobro a taj delay ti ionako ne treba.
[ janko11 @ 17.08.2018. 09:23 ] @
Kada sam izbacio delay nista se nije videlo, zato ga i koristim. Mislis da to moze da bude uzrok problema? Mozes li da mi das primer koda za prekidnu rutinu, sta bih trebao da ispravim?
[ goran_68 @ 17.08.2018. 10:26 ] @
Nemam primer koda. Ja sam sa 8031 radio poslednji put 1999-te godine.
Napiši kod koji će prvo da ugasi sve displeje, potom da na displeju 1 da ispiše S, zadrži to sekundu-dve, pa ugasi taj displej. Sačekaj opet sekundu pa na displeju 2 ispiši T, zadrži neko vreme, ugasi displej 2... itd.
Kad to dobiješ siguran si da ti obraćanje hardveru koji kontroliše rad displeja radi pa cepaj dalje.
To dalje treba da bude čitanje onog dip prekidača.
Kad ti i to prođe uključi u kod oba npr da ti displej 1 prikaže koji je dip uključen.
Na kraju tek radiš sve displeje i čitanje dip preko prekidne rutine tajmera.
[ janko11 @ 17.08.2018. 13:03 ] @
Kod koji ce prvo da ugasi sve displeje, da li isto radim u prekidnoj rutini tajmera, ili da napisem funkciju koja ce da ugasi sve displeje i pozovem je u funkciji main, a zatim u prekidnoj rutini tajmera, ukljucim displej 1, prikazem 'S', ukljucim displej 2 prikazem 'T' i tako dalje?
[ janko11 @ 17.08.2018. 13:55 ] @
Probao sam program koji samo na displeju ispisuje poruku (START), to radi, bez upotrebe dip switch - a. Problem imam kad ukljucim dip switch, jer u zavisnosti koji je dip pritisnut prikazuje se odredjena poruka, tada ili nece da se ukljuce svi segmenti ili segmenti blinkuju.
[ bogdan.kecman @ 17.08.2018. 14:16 ] @
ok znaci jednom pitas dipp pa prikazes string, pa pitas pa prikazes ... etc...

Code:

 void timer0(void) interrupt 1

  TH0=0xFC;     // resetuj timer0
  TL0=0x66;     //

  switch(disp)
  {
    case 1: //pitaj dipove
       C=1;
       BB=1;
       A=1;
       if(e0==1 && q4==0 && q5==0 && q6==0) pom=1;
    break;
    case 2: // cifra 1
       C=1;
       BB=0;
       A=1;
       if(pom==1)
          displayDigit('S');
       delay(5);
    break;
    case 3: // cifra 2
       C=1;
           BB=0;
       A=0;
       if(pom==1)
          displayDigit('T');
       delay(5);
    break;
    case 4: // cifra 3
       C=0;
       BB=1;
       A=1;    
           if(pom==1)
          displayDigit('A');
       delay(5);
    break;
    case 5: // cifra 4
       C=0;
       BB=1;
           A=0;
       if(pom==1)
          displayDigit('R');
       delay(5);
    break;
    case 6: // cifra 5
       C=0;
       BB=0;
       A=1;
       if(pom==1)
          displayDigit('T');
      delay(5);
    break;
    }
    disp++;
    if(disp>6)
      disp=1;
}



kako ocekujes da ti se bilo sta desi sa cifrom 6 kad nema koda za nju?

1. da li si dodao one pullup koje sam ti rekao? bez toga to ne moze da radi
2. OE linije ti "levitira" i samim tim ti pravi problem i klesuje sa izlazom sa mcu i ispis nije normalan

[ janko11 @ 17.08.2018. 14:46 ] @
Sta mislis pod cifrom 6? Shvatio sam da OE linija pravi probleme. Da li ce kada se dodaju pullup to resiti problem zbog cega ispis nije kako treba? Trenutno nemam otpornike, stavicu ih tek od ponedeljka. Da li je potrebna mozda i neka korekcija u programu da bi sve to radilo kako treba?
[ bogdan.kecman @ 17.08.2018. 14:52 ] @
pa kazes imas 6 cifara ne radi ti 6ta, ne moze da radi nema koda?

OE je floating, mora turis, nemoguce da nemas 10k otpornije u kuci? bar
da turis jedan na OE  :D bilo sta od 1 do 15k ce radi posao za test

za ostalo - ne znam napamet, malo to cudno radi sa '51 a ja sam to radio
ko sto rekoh pre 20+ godina jbg a ni tad ih nisam voleo
[ uart @ 18.08.2018. 05:28 ] @
Da li hardver može da se menja?

Sve je nepotrebno iskomplikovano povezivanjem displeja i DIP switcheva na isti port, a P0 i P2 se uopšte ne koriste.
[ janko11 @ 19.08.2018. 01:27 ] @
P0 i P2 se koriste za spoljasnji EPROM na kome se nalazi program koji se izvrsava. Da li je do hardvera problem, jer su displeji i dip switch - evi povezani na isti port?
[ bogdan.kecman @ 19.08.2018. 01:47 ] @
do hw-a je problem zato sto za pocetak nemas pullup-ove ... kad to
stavis onda mozemo da pricamo dalje ako i dalje imas neki problem
[ uart @ 19.08.2018. 08:56 ] @
Citat:
janko11:
P0 i P2 se koriste za spoljasnji EPROM na kome se nalazi program koji se izvrsava. Da li je do hardvera problem, jer su displeji i dip switch - evi povezani na isti port?


OK. Pretpostavljam da si odradio softverske izmene koje su kolege sugerisale:

1. Iz interapt rutine je izbačena funkcija delay.

2. Pre čitanja linija na portu koje se koriste kao dvosmerne (P1.3, P1.4, P1.5 i P1.6) treba ih prebaciti u READ (upisati "1" u dogovarajući latch).
Nije dovoljno samo pri inicijalizaciji uraditi P1=0xFF. To ima smisla ako se port koristi isključivo kao ulazni.

Pretpostavljam da imaš neki 8051 datasheet, u njemu verovatno postoji poglavlje koje se zove "port hardware configuration" ili nešto slično. Pažljivo pročitaj,

3. Ovo nije uzrok problema, ali bi trebalo zaustaviti tajmer pre inicijalizacije:

Umesto

TH0=0xFC;
TL0=0x66;

bi trebalo da stoji

TR0=0;
TH0=0xFC;
TL0=0x66;
TR0=1;

[ janko11 @ 19.08.2018. 17:37 ] @
Mozes li mi detaljnije objasniti kako dvosmerne linije (P1.3, P1.4, P1.5 i P1.6) prebaciti u READ, posto nisam nasao u datasheet. Da li mozes pokazati smernice kako to treba uraditi? Pokusacu da pronadjem.

Sto se tice pullup, da li je dovoljno staviti 10k za pullup - ove na svim izlaznim pinovima 4051 ka napajanju?
[ bogdan.kecman @ 19.08.2018. 19:22 ] @
za pinove nemam pojma, proleteh kroz ds i nisam ni ja skonto

sto se pullup tice, 10k na svaku liniju iz 4051 bi trebalo da resi ove
probleme
[ uart @ 20.08.2018. 21:13 ] @
Citat:
janko11:
Mozes li mi detaljnije objasniti kako dvosmerne linije (P1.3, P1.4, P1.5 i P1.6) prebaciti u READ, posto nisam nasao u datasheet. Da li mozes pokazati smernice kako to treba uraditi? Pokusacu da pronadjem.


Pre svakog čitanja podataka (stanja DIP prekidača) treba linije P1.3 - P 1.5 postaviti na "1".

Uz poruku je prikačena šema jednog pina na portu P1.

Za čitanje logičkog nivoa sa pina FET na izlazu mora da bude isključen, a isključuje se tako što se u D latch upiše "1".
Logički nivo na pinu određuje signal sa 74HC573.

Kada se pin koristi ako izlazni:

Kada se u D latch upiše "0" FET se uključuje i drži izlazni pin na niskom nivou.

Kada se u D latch upiše "1" FET se isključuje i interni pullup drži izlazni pin na visokom nivou.






[Ovu poruku je menjao uart dana 20.08.2018. u 22:29 GMT+1]
[ janko11 @ 24.08.2018. 08:05 ] @
Sada se poruke prikazuju na displeju, samo sto ponekad blinkuje po neki segment, pretpostavljam da je to do hardvera.
[ janko11 @ 24.08.2018. 15:34 ] @
Poruke se prikazuju na displeju. Hvala kolegama bogdan.kecman i uart na savetima i pomoci.
Samo jos jedno pitanje: U kodu za prijem podataka sa serijskog porta, sta treba podesiti da recimo kada se izgubi komunikacija na displeju pise recimo STOP umesto poslednjeg primljenog podatka.
Kod za prijem podataka sa serijskog porta izgleda ovako
Code:

  void serial(void) interrupt 4
  {
     if(RI)
     {
         el=SBUF;
      RI=0;
      switch(el)
      {
        case 0x02:
            prijem=1;
        zavrsen=0;
        tail=0;
        break;
        case 0x03:
          zavrsen=1;
              prijem=0;
        break;
        default:
          if(prijem==1 && zavrsen==0)
              {
           buff[tail]=el;
           tail++;
           if(tail==20)
                tail=0;
           }
           else if(prijem==0 && zavrsen==1)
           {
           buff[tail]=el;
           tail++;
           buff[tail]='\0';
           }
        break;
      }
     }
}
[ uart @ 24.08.2018. 19:12 ] @
Citat:
Samo jos jedno pitanje: U kodu za prijem podataka sa serijskog porta, sta treba podesiti da recimo kada se izgubi komunikacija na displeju pise recimo STOP umesto poslednjeg primljenog podatka.


Koliko vidim podaci stižu u paketima formata 0x02 <podaci> 0x03

Šta tačno znači "da se izgubi komunikacija"? Da stigne deo paketa, a nikad ne stigne 0x03?
Da li paketi stižu stalno, sa nekim vremenskim razmakom ili povremeno?

Nevezano za ovo pitanje: mislim da umesto promenljivih "prijem" i "zavrsen" može da se koristi samo jedna.


[ janko11 @ 24.08.2018. 21:13 ] @
Da, podaci stizu u formatu 0x02 <podaci> 0x03. Pocinje sa 0x02 a zavrsava se sa 0x03. Podaci stizu stalno brzinom 9600 baud/s. Pod pojmom da se izgubi komunikacija znaci da stigne deo paketa, a nikad ne stigne 0x03 ili da jednostavno prestane slanje podataka usled na primer da se iskljuci kabl koji povezuje uredjaj koji salje podatke sa procesorom koji prima podatke i prikazuje na displeju. U tom slucaju na displeju trebalo bi da se prikaze recimo STOP umesto poslednje primljenog podatka. Kada se ponovo uspostavi komunikacija podaci stalno pristizu, smestaju se u bafer i prikazuju na displeju. Kada ponovo prestane slanje paketa, na displeju pise recimo STOP, sve dok ponovo ne pocne slanje podataka.
[ uart @ 25.08.2018. 20:09 ] @
Iskoristiš tajmer. Resetuješ ga svaki put kada stigne 0x02 (početak paketa).
Ako dođe do prekida komunikacije tajmer će okinuti interapt i u tada u bafer za ispis upišeš "STOP".

Za inicijalizaciju tajmera treba znati koliki je vremenski razmak između paketa.