 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
| Poglej prejšnjo temo :: Poglej naslednjo temo |
| Avtor |
Sporočilo |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Pon Maj 16, 2011 6:36 pm Naslov sporočila: 16F877 in UART |
|
|
Lep pozdrav,
uporabljam 16F877, kolikor razumem moram za UART protokol uporabiti port in pine na mikroprocesorju, ki omogočajo TTL nivoje? Torej PORTD npr. TX -> 0 pin, RX-> 1 pin?
Imam GPS napravo, ki mi preko UART Transmit pošilja NMEA stavke. Sprejet jih moram prav tako z UARTom. _________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
Peter123 Član


Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1500 Aktiv.: 7.14 Kraj: Lj.
|
Objavljeno: Tor Maj 17, 2011 7:15 am Naslov sporočila: |
|
|
Če imaš PIC napajan z 5V so vsi pini TTL kompatibilni.
TTL ti pove da je logična 0 na 0V in logična 1 na +5V.
Vprašanje katere pine moraš vzeti je torej odvisno od tega ali boš uporabil interni HW UART ali boš uporabil SW UART. |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Sre Maj 18, 2011 9:14 am Naslov sporočila: |
|
|
| Peter123 je napisal/a: |
Če imaš PIC napajan z 5V so vsi pini TTL kompatibilni.
TTL ti pove da je logična 0 na 0V in logična 1 na +5V.
Vprašanje katere pine moraš vzeti je torej odvisno od tega ali boš uporabil interni HW UART ali boš uporabil SW UART. |
OK, na PIC16F877, sem v HITECH prevajalniku nastavil registre za prejemanje podatkov - receive, torej. Nastavil sem BaudRate in ostale ter še Asinhroni način.
spodaj je napisan program, program deluje tako da kar dobi v RX pin naj napiše na LCD, problem pa je ker ta izpis ni sinhroniziran na prejemanje.
Namreč če čip večkrat resetiram se mi po določenih številih le pokaže $GPGGA stavek oz prvi stavek od stavkov ki jih bruha GPS prek UART komunikacije.
| Koda: |
#include <htc.h>
#include "lcd.h" //vkljuci knjiznico lcd.h
#include "serio.h"
#include <stdio.h>
#define _XTAL_FREQ 20000000 //frekvenca zunanjega oscilatorja (HS) 20MHz
void main()
{
char *s = 0;
char b;
int i=0;
INTCON=0;
TRISA=0; //registri portA so izhod
TRISB=0; //reg. portB so izhod
PORTB=0; //pini na portB so izhod
PORTA=0; //pini na portA so izhod
serial_init(129,1);
lcd_init();
lcd_puts("Testni izpis na LCD");
lcd_goto(0x40);
while(1)
{
s=gets(b);
if(s != 0)
{
lcd_puts(s);
}else{
lcd_puts("nism dobo");
}
}
} |
V samem projektu imam dodan C file v katerem so spisane funkcije gets itd. _________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
red_mamba Član


Pridružen-a: Ned 20 Feb 2005 17:56 Prispevkov: 1486 Aktiv.: 6.01 Kraj: Yogyakarta
|
Objavljeno: Sre Maj 18, 2011 9:35 am Naslov sporočila: |
|
|
Imaš ciklični buffer narejen pri sprejemu?
Mikrokontroler lahko namreč veliko hitreje sprejema podatke kot jih lahko ti izpisuješ in obdeluješ dalje. Zato shraniš vse v buffer kar dobiš. V glavni zanki pa potem preverjaš samo če imaš kaj v bufferju in izpisuješ na LCD. _________________ Bad things happen to good people all the time for no reason!
Blog |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Sre Maj 18, 2011 12:21 pm Naslov sporočila: |
|
|
Ok to razumem,
kolikor vem je v tej kodi pod funkcijo unsigned char getch napisana koda za prejemanje v buffer?
| Koda: |
#include <htc.h>
#include <stdio.h>
#include "serio.h"
void serial_init(char brg, char hi_speed)
{
TRISC6=1;
TRISC7=1;
if (hi_speed){
TXSTA=0x26;
RCSTA=0x90;
}
else{
TXSTA=0x22;
RCSTA=0x90;
}
SPBRG = brg;
}
void putch(unsigned char byte)
{
while(!TRMT)continue; /* Wait for TX Buffer Empty */
TXREG = byte;
}
unsigned char getch ()
{
// wait until data available
while (!RCIF);
RCIF=0;
return(RCREG);
}
unsigned char getche (void)
{
unsigned char c;
c = getch();
return(c);
}
char* getst()
{
int i=0;
char* s;
do
{
s[i]=getche();
i++;
}while(s[i]!='\n');
return s;
} |
_________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
gumby Član


Pridružen-a: Sob 28 Apr 2007 12:32 Prispevkov: 4066 Aktiv.: 17.60
|
Objavljeno: Sre Maj 18, 2011 12:42 pm Naslov sporočila: |
|
|
V tem primeru getch() počaka, da se sprejme znak in ga vrne.
getche() je pa tipičen primer nepotrebne funkcije, ki ne naredi nič.
Ti raje naredi buffer, v katerega vstaviš znak, ko je na voljo. To počneš v prekinitvi.
Koliko znakov je v bufferju pa lahko ugotoviš na več načinov, recimo s kazalci. Enega imaš za pisanje v buffer, drugega za branje (če nista enaka, je na voljo znak v bufferju).
Podobno se lahko naredi tudi pošiljanje znakov. V buffer napišeš string, ki bi ga rad poslal, znake pa potem bereš v prekinitvi in pošiljaš na UART... _________________ Tule nisem več aktiven. |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Sre Maj 18, 2011 6:57 pm Naslov sporočila: |
|
|
Ok razumem, torej lahko naredim takole:
| Koda: |
char bufer[80];
....
zanka{
....
s=gets(bufer);
....
}
.... |
_________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega
Nazadnje urejal/a drVrh Sre Maj 18, 2011 6:57 pm; skupaj popravljeno 1 krat |
|
| Nazaj na vrh |
|
 |
red_mamba Član


Pridružen-a: Ned 20 Feb 2005 17:56 Prispevkov: 1486 Aktiv.: 6.01 Kraj: Yogyakarta
|
Objavljeno: Sre Maj 18, 2011 6:57 pm Naslov sporočila: |
|
|
no tako kot ti je gumby povedal.
uporabljaš direkt branje in pisanje na USART
rabiš:
unsigned char buffer[64];
int head;
int tail;
znake zapisuješ z head
buffer[head++] = RX
if (head != tail) lahko bereš
tmp = buffer[tail++];
nekako v tem duhu, če ne bo šlo bomo pa dalje pomagali  _________________ Bad things happen to good people all the time for no reason!
Blog |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Sre Maj 18, 2011 6:59 pm Naslov sporočila: |
|
|
Aha, hvala RedMamba, toda kolikor razumem tvojo kodo, je to za USART komunikacijo kjer ima paket Glavo in Rep, jaz uporabljam UART, in sprejemam podatke GPS modula, kjer mi vsako sekundo pošlje NMEA stavke. _________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
red_mamba Član


Pridružen-a: Ned 20 Feb 2005 17:56 Prispevkov: 1486 Aktiv.: 6.01 Kraj: Yogyakarta
|
Objavljeno: Sre Maj 18, 2011 7:18 pm Naslov sporočila: |
|
|
ne ne, glava in rep sta samo da veš kam zapisovati bajte in kje jih brati.
in ko prideta glava ali rep do 64 (v tem prmeru) jih moraš postavt na 0 (zato ciklični pomnilnik)
znake zapisuješ v buffer v interupt rutini, vsak sprejeti znak se zapiše v buffer.
Ti imaš potem 1 sekundo časa med vsakim stavkom da obdelaš in izpišeš podatke na LCD kar je več kot dovolj časa, da se ti pomnilnik ne zapolni (ubistvu se ti tako ne zapolni nikoli, dejansko se povozijo podatki, ki jih še nisi obdelal če ne gledaš head in tail pointerjev med vpisovanjem) _________________ Bad things happen to good people all the time for no reason!
Blog |
|
| Nazaj na vrh |
|
 |
gumby Član


Pridružen-a: Sob 28 Apr 2007 12:32 Prispevkov: 4066 Aktiv.: 17.60
|
Objavljeno: Sre Maj 18, 2011 9:07 pm Naslov sporočila: |
|
|
Takole nekako:
| Koda: |
#define BUFLEN 32
char buffer[BUFLEN];
volatile int rxb=0;
void __interrupt rx_isr(void)
{
buffer[rxb++]=UART_RX;
if(rxb==BUFLEN)
rxb=0;
}
char getchr(void)
{
static int rb=0;
char ch;
if(rxb==rb)
ch=0;
else
{
ch=buffer[rb++];
if(rb==BUFLEN)
rb=0;
}
return(ch);
}
|
getchr() vrne znak iz bufferja, če je kaj not (ali 0, če je prazen). _________________ Tule nisem več aktiven. |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Čet Maj 19, 2011 3:09 pm Naslov sporočila: |
|
|
Kar veliko Errorjev mi izpiše, ob kodi od Gumby-ja:
 _________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Čet Maj 19, 2011 3:18 pm Naslov sporočila: |
|
|
Sedaj sem zbrisal podpičje pir #define BUFLEN in ga dodal pri unsigned char buffer[BUFLEN].
Rezultat:
| Koda: |
Error [288] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 9.17 only functions may be void
Error [372] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 9.17 "," expected
Error [314] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 10.1 ";" expected
Error [285] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 12.1 no identifier in declaration
Warning [374] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 12.1 missing basic type; int assumed
Error [314] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 12.1 ";" expected
Error [285] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 14.1 no identifier in declaration
Warning [374] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 14.1 missing basic type; int assumed
Error [314] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 14.1 ";" expected |
_________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
drVrh Član



Pridružen-a: Sre 20 Feb 2008 20:17 Prispevkov: 918 Aktiv.: 4.15 Kraj: Slovenija-Koroska-Prevalje-Lese
|
Objavljeno: Čet Maj 19, 2011 3:24 pm Naslov sporočila: |
|
|
SEdaj sem zbrisal presledek v funkciji interupt ...
Prej:
| Koda: |
| void __interrupt _rx_isr(void) |
Zdaj:
| Koda: |
| void __interrupt_rx_isr(void) |
Napaka:
| Koda: |
| Error [192] C:\Users\Grega\Documents\MPLAB_projekti\LCD877\serio.c; 11.15 undefined identifier "UART_RX" |
Za to pa ne vem kako si mislil Gumby? je ta UART_RX kakšen register ali kaj drugega? _________________ Iz dneva v dan sem se spraševal kaj je to elektrika, vendar nisem našel odgovora ... in še vedno si postavljam to vprašanje
LP
Grega |
|
| Nazaj na vrh |
|
 |
ljudsko Član


Pridružen-a: Pon 31 Mar 2008 8:19 Prispevkov: 1184 Aktiv.: 5.39 Kraj: Koroška-Mežica
|
Objavljeno: Čet Maj 19, 2011 6:38 pm Naslov sporočila: |
|
|
| gumby je napisal/a: |
V tem primeru getch() počaka, da se sprejme znak in ga vrne.
getche() je pa tipičen primer nepotrebne funkcije, ki ne naredi nič. |
Sploh ni res. getche() je funkcija v hi-tech, ki jo kliče funkcija gets(). Zato je potrebna. Lahko bi dal v getche() to, kar je v getch() in bi prihranil čas.
Grega, interrupt rutine se v hitech prevajalniku pišejo takole:
| Koda: |
| void interrupt ImeFunkcije(){..koda..} |
In ne kopiraj dobesedno Gumbyjeve kode, ker on uporablja drug prevajalnik, torej ti koda nikoli ne bo delovala. Uporabi samo njegov princip oz. logiko. Pisati boš moral sam.
Gumby, lahko razložiš svojo kodo, ker ccs mi nekako ni poznan najbolje. Zakaj se to dogaja v prekinitveni rutini? Ali se prekinitev pojavi, ko se bit RCIF postavi na 1? Je za to potrebno posebej vklopiti prekinitve? _________________ return;
brake; |
|
| Nazaj na vrh |
|
 |
|
|
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: 232 dni
Powered by phpBB © 2001, 2005 phpBB Group
|