www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

LPC2138-ŠARM - dvojni znaki pri izpisu na uart z ISR

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.65
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Pet Jun 01, 2007 1:33 am    Naslov sporočila:  LPC2138-ŠARM - dvojni znaki pri izpisu na uart z ISR Odgovori s citatom

Srečno.

Cel dan me že muči tole:
Imam en preprost program, ki ima definirana dva ISR-ja, za vsak UART na čipu. Program preprosto počaka na sprejem preko UARTa, ki sproži prekinitveno rutino, ta pa znak pošlje preko drugega UARTa.

Problem je v tem, da namesto enega znaka na drugem koncu zmeraj dobim dva, ravno tako če gre znak v drugo smer.

Tukaj je funkcija za nastavitev prekinitve:

Koda:

void vic_uart0(void)
{
  VICIntSelect &= ~(1 << VIC_UART0);
  VICVectCntl1 = VIC_ENABLE | VIC_UART0;
  VICVectAddr1 = (unsigned long) uart0ISR;
  VICIntEnable = 1 << VIC_UART0;
  U0IER = 0x01;
}


Tukaj pa sama prekinitvena rutina:
Koda:

void uart0ISR(void)
{
  char c;
  c = U0LSR;
  c = U0RBR;
  U0IIR;
  uart1_putchar(c);
  lcd_char(c);
  VICVectAddr = 0x00000000;
}


Med drugim mi ni čisto jasno, kako točno 'pobrišeš' interrupt. Po dokumentaciji sodeč bi moralo biti dovolj to, da prebereš vsebino U0RBR in pišeš v VICVectAddr, vendar če imam v ISR-ju samo to, mi neprestano izpisuje prvi znak.
Kaj točno naj bi tam počel ukaz U0IIR (ki je v bistvu naslov -- sem pa to videl v enem primeru na internetu), mi pa sploh ni jasno, vendar pomaga, da je ponovitev znaka malo manj Smile

Če ima kdo kako idejo, bi bil hvaležen ...

Lahko pošljem tudi cel program, če bo komu to pomagalo ...


Lep pozdrav!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.65
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Pet Jun 01, 2007 5:19 pm    Naslov sporočila:   Odgovori s citatom

Da odgovorim sam sebi -- ISR dela normalno, če je napisan v tejle obliki:
Koda:

void uart0ISR(void)
{
  volatile char c, tmp;
  while(U0LSR_bit.RDR) {
    c = U0RBR;
    tmp = U0LSR;
    uart1_putchar(c);
    lcd_char(c);
  }
 
  VICVectAddr = 0x0;
}

Zakaj to dela, zgornja verzija pa ne, mi pa sploh ni jasno. Saj če pošlješ samo en znak, naj ne bi bilo potrebno brati U0LSR v zanki ... A mi zna to kdo razložiti?

LP!

p.s.: a se mogoče U0LSR.RDR nastavi prepozno??
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
blueH2O
Član
Član



Pridružen-a: Sob 30 Sep 2006 9:23
Prispevkov: 71
Aktiv.: 0.31

PrispevekObjavljeno: Čet Jun 07, 2007 10:39 am    Naslov sporočila:   Odgovori s citatom

Lahko pripneš še funkcijo za nastavitev UART? Si preveril nastavitev v U0FCR, kjer izbiraš na koliko sprejetih znakov se sproži prekinitev?

Citiram:
Kaj točno naj bi tam počel ukaz U0IIR (ki je v bistvu naslov -- sem pa to videl v enem primeru na internetu), mi pa sploh ni jasno, vendar pomaga, da je ponovitev znaka malo manj


Mogoče s klicem U0IIR pridobiš nekaj časa, da se znak do konca sprejme. V drugem ISR je while zanka - sklepam, da je počaka do konca prenosa znaka. Torej, ali se prekinitev izvrši ko se začne sprejemanje znaka ali ko je sprejem že končan?

Sam se izogibam prekinitvam in uporabljam funkcijo, ki preverja če je znak sprejet, in če je, ga prebere in obdela...

Primer:
Koda:

int U1BytesToRead()
{
  if((U1LSR & 0x01) == 0) return 0; //U1RBR is empty
  else return 1; //U1RBR contains valid data - there is an unread char in buffer
}

void ifByteReceived()
{
  if(U1BytesToRead() == 1)
  {   
     char b;
     b = U1ReadByte();
     //...
  }
}

int main()
{
  while(1)
  {
     ifKeyPressed();
     ifByteReceived();
     //...
  }
  return 0;
}


Pri takšnem načinu imaš več nadzora kot pri prekinitvah - veš kje se proži, vendar lahko tudi izgubiš znake pri daljšem izvajanju drugih funkcij... Toliko za nasvet.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
RokO
Član
Član



Pridružen-a: Čet 23 Nov 2006 11:14
Prispevkov: 120
Aktiv.: 0.53
Kraj: Kranj

PrispevekObjavljeno: Sre Jun 13, 2007 12:20 am    Naslov sporočila:   Odgovori s citatom

Pozdravljeni, to temo bi izkoristil za svoj problem:
Oj,
Delam na ŠARMu (LPC2138 in WinIdea)- s serijsko komunikacijo...UART mi sicer dela (lahko pošiljam), sprejemanje mi dela bolj tako-tako, to je pa tudi vse.
Problem pri sprejemanju je ta, da moram vedno predvideti, kdaj se bo stvar poslala, da lahko takoj za tem poženem funkcijo za branje. In to mi dela težave, saj če poženem branje par trenutkov prepozno znaka ni več oz. se pojavi drug (če pošiljam string).
Sam se že par dni mučim z UART interrupti pa mi nikakor ne gre. V bistvu s prekinitvami želim doseči, da bi se vsebina, ko pride na uart shranila npr v eno polje char[].
Delam na zelo podoben način, kot ti v primeru, ki ga je chaos poslal na forum - pa ni uspeha.
Zato me zanima, če bi mi lahko prosim kdo poslal kakšen delujoč example, ali pa kakšen projekt (lahko oskubljen) - z delujočim UART interruptom. Za celoten projekt bi prosil zato, ker samo kodo ISR, main in inicializacijo imam pomoje pravilno.
Poskusil sem že res veliko stvari, vendar brez uspeha, se pa mi vse bolj dozdeva, da sem pozabil na kakšno osnovno stvar - mogoče kaj v startup datoteki.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
alessio
Član
Član



Pridružen-a: Pon 04 Dec 2006 8:39
Prispevkov: 363
Aktiv.: 1.61
Kraj: Ljubljana

PrispevekObjavljeno: Sre Jun 13, 2007 7:58 am    Naslov sporočila:   Odgovori s citatom

Tukaj je delujoč primer interrupt-driven UART.

Aleš
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
RokO
Član
Član



Pridružen-a: Čet 23 Nov 2006 11:14
Prispevkov: 120
Aktiv.: 0.53
Kraj: Kranj

PrispevekObjavljeno: Sre Jun 20, 2007 4:20 pm    Naslov sporočila:   Odgovori s citatom

Končno mi je supelo rešiti probelm...kot se mi je zdelo že na začetku, problem ni bil v kodi ampak v USB-RS232 pretvorniku.
Upam, da bo to komu prihranilo živce:)
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 3 dni


Powered by phpBB © 2001, 2005 phpBB Group