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


Pridružen-a: Pon 31 Mar 2008 8:19 Prispevkov: 1184 Aktiv.: 5.39 Kraj: Koroška-Mežica
|
Objavljeno: Pon Maj 23, 2011 6:12 pm Naslov sporočila: |
|
|
Tudi jaz ne razumem povsem. Sem naredil tako, kot praviš @red_mamba, ampak se mi program zacikla. Uporabljam pa PIC16F88 in PC. _________________ return;
brake; |
|
| 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: Pon Maj 23, 2011 6:51 pm Naslov sporočila: |
|
|
Ok, naredil sem loop-back in s putch(s) poslal na terminal, kar sem iz njega poslal. Očitno mi probleme delajo funkcije za izpis stringa na terminal (puts() in printf()), da se program zacikla - ne vem zakaj . Problem pa je, ker se pojavi prekinitev, ko čip nekaj dobi na RX, kar pa zmede glavni program, ki ne ve kdaj mora začeti brati..(če pošiljamo string).
EDIT: Dobivam neke popačene kopije tistega, kar pošljem čipu:
| Citiram: |
Pošljem: "vklop"
Dobim:"vlolop"
|
| Koda: |
while(1){
//printf("Vnesi komando za vklop LED-ice:\n");
i=0;
while(charAvail()){s[i]=getch();putch(s[i]);i++;}
if(PreveriK(s))
{
//printf("Komanda sprejeta, LED vklopljena!");
RA0=1;
for(;;);
}
//else
//printf("Nepravilna komanda!\n");
} |
Če pa ne shranjujem v string sproti, ampak kar direktno izpisujem na terminal, pa se mi izpiše pravi string.. _________________ return;
brake; |
|
| Nazaj na vrh |
|
 |
red_mamba Član


Pridružen-a: Ned 20 Feb 2005 17:56 Prispevkov: 1486 Aktiv.: 6.01 Kraj: Yogyakarta
|
Objavljeno: Pon Maj 23, 2011 10:22 pm Naslov sporočila: |
|
|
| ljudsko je napisal/a: |
Ok, naredil sem loop-back in s putch(s) poslal na terminal, kar sem iz njega poslal. Očitno mi probleme delajo funkcije za izpis stringa na terminal (puts() in printf()), da se program zacikla - ne vem zakaj . Problem pa je, ker se pojavi prekinitev, ko čip nekaj dobi na RX, kar pa zmede glavni program, ki ne ve kdaj mora začeti brati..(če pošiljamo string).
EDIT: Dobivam neke popačene kopije tistega, kar pošljem čipu:
| Citiram: |
Pošljem: "vklop"
Dobim:"vlolop"
|
| Koda: |
while(1){
//printf("Vnesi komando za vklop LED-ice:\n");
i=0;
while(charAvail()){s[i]=getch();putch(s[i]);i++;}
if(PreveriK(s))
{
//printf("Komanda sprejeta, LED vklopljena!");
RA0=1;
for(;;);
}
//else
//printf("Nepravilna komanda!\n");
} |
Če pa ne shranjujem v string sproti, ampak kar direktno izpisujem na terminal, pa se mi izpiše pravi string.. |
kako imaš pa stringe terminirane? _________________ Bad things happen to good people all the time for no reason!
Blog |
|
| 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: Tor Maj 24, 2011 7:24 pm Naslov sporočila: |
|
|
Katere? Tiste, ki jih s čipa pošiljam vidiš. Tiste, ki pa jih pošiljam s PC-ja pa s CR+LF end. _________________ return;
brake; |
|
| 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: Tor Maj 24, 2011 9:14 pm Naslov sporočila: |
|
|
Že deluje. Preverjati sem moral, ali se na indexu, ki ga trenutno preverjam nahaja 0xd-CR-"carriage return", torej konec stringa. Zdaj deluje vse. Dodal sem še kratke delaye med polnjenje stringa..Izgleda takole:
| Koda: |
while(1){
printf("Vnesi komando za vklop LED-ice:\n");
while(!charAvail());
for(i=0;charAvail();i++)
{
s[i]=getch();
putch(s[i]);
__delay_ms(10);
}
if(PreveriK(s))
{
printf("Komanda sprejeta, LED vklopljena!\n");
GIE=0;
RA0=1;
for(;;);
}
else
printf("Nepravilna komanda!\n");
} |
| Koda: |
bit PreveriK(unsigned char kom[])
{
unsigned char komanda[6]="vklop";
int i;
for(i=0;kom[i]!=0xd;i++)
{
if(i>4 || kom[i]!=komanda[i])return 0;
}
if(i<4)return 0;
return 1;
} |
Program mi sproti izpisuje, kar vnesem v terminal (torej čip pošlje nazaj moj string), nato pa preveri, če je komanda prava in vklopi LED na RA0, če je, drugače pošlje ponovni "prompt".. _________________ return;
brake; |
|
| 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: Sre Maj 25, 2011 1:39 pm Naslov sporočila: |
|
|
Grega, v priliki lahko prideš k meni in še tvojo zadevo "porihtama".. _________________ return;
brake; |
|
| Nazaj na vrh |
|
 |
MvE Član


Pridružen-a: Ned 04 Jan 2009 12:24 Prispevkov: 146 Aktiv.: 0.69 Kraj: MB
|
Objavljeno: Sob Dec 17, 2011 5:24 pm Naslov sporočila: |
|
|
Da ne odpiram nove teme bom kar tukaj vprašal:
Torej z PC in PIC18F14K50 poiskušam vzpostaviti serijsko komunikacijo (UART). Mikrokrmilnik lepo pošilja podatke na računalnik, obratno pa ne. Ko pošljem katerikoli podatek na mikrokrmilnik ne reagira (ne skoči v prekinitveno rutino in ne spremeni stanja na LED). Imel sem tudi v glavni zanki izdelan program kjer bi z določeno črko prižigal in ugašal LED diodo ampak ni deloval. Po vsej verjetnosti je napaka v nastavitvi registrov, zato bi prosil nekoga, ki se na to spozna, da mi pomaga najti napako.
| Koda: |
//UART: 16 MHz HS kristal, Baud rate 9600
char prejeto;
void interrupt(void)
{
//Izbriši TMR0 interrupt flag
if(INTCON.TMR0IF == 1) INTCON.TMR0IF = 0;
//UART prejemanje
if(PIR1.RCIF == 1)
{
if(RCSTA.OERR) //Če je prišlo do overrun
{
RCSTA.CREN=0;
RCSTA.CREN=1;
}
prejeto = RCREG; //preberi prejet podatek
PIR1.RCIF = 0; //Izbriši interrupt flag
}
//Za vsako prekinitev premeni stanje na LED
PORTB.F6 = ~PORTB.F6;
}
void main()
{
TRISB.B6 = 0; //LED signal
TRISB.B5 = 1; //RX input
TRISB.B7 = 0; //TX output
PORTB.F6 = 1;
INTCON = 0b11100000; //Omogočeni GIE,PEIE,TMR0IE
PIE1 = 0b00100000; //Omogočen RCIE
T0CON = 0b10000101; //Nastavitev TMR0 - prekinitev na 1 sekundo
//Inicializacija UART
TXSTA = 0b00100000;
RCSTA = 0b10010000;
BAUDCON = 0b01100000;
SPBRG = 25;
delay_ms(300);
for(;;)
{
//Vsako sekundo pošlji preko UART
delay_ms(1000);
TXREG = 'H';
}
} |
|
|
| Nazaj na vrh |
|
 |
Highlag Član


Pridružen-a: Pet 23 Jan 2004 20:42 Prispevkov: 4034 Aktiv.: 16.33 Kraj: Črnuče
|
Objavljeno: Sob Dec 17, 2011 5:36 pm Naslov sporočila: |
|
|
Ne vem kakšen prevajalnik uporabljaš, vem pa da je potrebno pri interuptu shraniti kar nekaj registrov, in jih po interuptu restavrirati, če hočeš, da delujejo. Imaš to urejeno pravilno? _________________ If at first you don't succeed, destroy all evidence that you tried. |
|
| Nazaj na vrh |
|
 |
MvE Član


Pridružen-a: Ned 04 Jan 2009 12:24 Prispevkov: 146 Aktiv.: 0.69 Kraj: MB
|
Objavljeno: Sob Dec 17, 2011 5:40 pm Naslov sporočila: |
|
|
Hm... mislim, da tega nimam. Mi lahko malo natančneje opišeš kaj bi bilo potrebno? To samo okoli UARTa ali še česa?
Programiram v mikroC, bi pa delovalo tudi v MPLABu z nekaj manjšimi spremembami. |
|
| Nazaj na vrh |
|
 |
Highlag Član


Pridružen-a: Pet 23 Jan 2004 20:42 Prispevkov: 4034 Aktiv.: 16.33 Kraj: Črnuče
|
Objavljeno: Sob Dec 17, 2011 7:34 pm Naslov sporočila: |
|
|
Mislim, da mikroC to naredi namesto tebe. Vsaj Mikrobasic naredi to.
Bo treba kaj drugega pogledat. Najprej preglej če imaš med primeri kakšen košček kode, pa seveda primere uporabe v helpu in podobnih zadevah.
Glede interuptov, če prav razumem tvojo kodo prekinitev izvede timer.
Koda za prejem ne služi pogoju za prižiganje led.
Dolžino timerja si nastavil samo enkrat. Postaviti ga moraš na želeno dolžino vsakič, ko se izvede prekinitev. Tako je možno, da je prekinitev prehitra, da bi ti videl utripanje.
Pa mogoče še prehitro brišeš zastavico za interupt. To pomeni, da je lahko takoj nato ponovno interupt, kar pomeni, da se koda za njim ne izvede.
Najprej kodo napiši tako, da ti bo delal timer interupt, nato pa dodajaj ostalo.
Tole je sicer v basicu in imam detekcijo dveh interuptov. Prvi interupt povzroči vhodni pin, drugi pa timer, tako da lahko izmerim čas do naslednjega signala na vhodu (merim obrate motorja - vhod da signal za 1 obrat, timer pa čas)
| Koda: |
sub procedure interrupt
if intcon.RBIF=1 then ' each time motor turns 1 revolution
stevec=stevec+1 ' generates 1 interupt and increases stevec
test = PortB
intcon.RBIF=0
PortE= NOT PortE
end if
if Pir1.TMR1IF=1 then ' timer runs for 100ms
stevec_izpis = stevec ' counts number ov turns in that time
stevec = 0 ' clears stevec for another cycle
TMR1H = Timer_H ' preset for timer1 MSB register -> ponovno nastavim čas timerja
TMR1L = Timer_L ' preset for timer1 MSB register
Pir1.TMR1IF = 0 ' Clear TMR1IF interupt tule šele omogočim interupt za čas
PORTD=NOT PORTD
end if
end sub |
_________________ If at first you don't succeed, destroy all evidence that you tried. |
|
| Nazaj na vrh |
|
 |
MvE Član


Pridružen-a: Ned 04 Jan 2009 12:24 Prispevkov: 146 Aktiv.: 0.69 Kraj: MB
|
Objavljeno: Ned Dec 18, 2011 12:58 am Naslov sporočila: |
|
|
Timer je 16 bitni s prescalerjem 64. Pri 16 MHz kristalu sproži prekinitveno zastavico samo približno vsako 1 s,
tako da mu ni potrebno nastavljati začetne vrednosti. Glede prižiganja LED je pa tako, njeno stanje spremeni
katerakoli prekinitev saj je stavek? "PORTB.F6 = ~PORTB.F6" napisan v prekinitveni rutini. Vsako sekundo to
naredi TMR0, moral bi pa tudi UART ob prejemu podatka ampak se RCIF (receive interrupt flag) ne sproži.
Malo je zakomplicirano napisano, upam da se razume. Težava je v glavnem samo v RCIF, kateri se ne sproži.
V mikroC knjižnicah je UART lepo pojasnjen, tisti primeri delujejo vendar sam delam z registri. |
|
| 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: 233 dni
Powered by phpBB © 2001, 2005 phpBB Group
|