|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
brezga1 Član
Pridružen-a: Tor 21 Sep 2010 21:39 Prispevkov: 29 Aktiv.: 0.18 Kraj: Medvode
|
Objavljeno: Pon Apr 30, 2012 10:05 pm Naslov sporočila: Prekinitve PIC v C |
|
|
Pozdravljeni!
Preiskal sem že skoraj celoten forum, pa vseeno nikjer ne najdem razumljivega primera, kako točno nastaviti interrupt, ter ga kasneje uporabiti pri poganjanju točne ure.
Narediti želim uro, ki bo čimbolj točna, saj bom preko nje krmilil nek sistem. Uporabil bom PIC 16f877a, ter zunanji 4Mhz kristal. Za programiranje pa uporabljam microC.
Zanima me, če se je že kdo kdaj ukvarjal s pisanjem programa za uro ali štoparico v C, kajti za ta jezik tega do sedaj še nisem našel.
Lep pozdrav!
|
|
Nazaj na vrh |
|
|
Matej-M Član
Pridružen-a: Čet 14 Maj 2009 18:40 Prispevkov: 87 Aktiv.: 0.48 Kraj: Celje
|
|
Nazaj na vrh |
|
|
hahalolek Član
Pridružen-a: Sob 29 Maj 2010 11:49 Prispevkov: 199 Aktiv.: 1.18 Kraj: Domžale
|
Objavljeno: Tor Maj 01, 2012 1:15 pm Naslov sporočila: |
|
|
Meni je tale primer zelo pomagal, ki ga je objavil uporabnik MvE na moji temi
MvE je napisal/a: |
Vidim, da si že ugotovil. Ne vem pa zakaj imaš v funkciji count, ki se ti povečuje?
Drugače pa imam en kratki program, ki sem ga hotel že prej prilepiti. Če na RA0 priklopiš LED z uporom, bi morala utripati na približno 1 s. Če ni kakšne napake upam, da je razumljivo napisano:
Koda: |
int stevec = 0;
//Tukaj se zacne prekinitvena funkcija, v MikroC se napise tako, v MPLAB-u je nekoliko drugace
void interrupt() {
stevec++;
//Ce je vzrok prekinitve T0IF in ce je stevec vecji ali enak 15 se stanje na izhodu RA0 spremeni
if (INTCON.T0IF == 1 && stevec >= 15) {
PORTA.F0 = ~PORTA.F0;
stevec = 0;
}
INTCON.T0IF = 0; //Izbrisemo T0IF, v nasprotnem primeru bi ponovno vstopili v prekinitveno funkcijo
}
void main() {
TRISA = 0x00000000; //Vsi pini A so izhodi
PORTA = 0x00000001; //Vklopimo samo pin RA0
//Nastavimo prekinitve
INTCON = 0x10100000;
//0x1....... omogoci prekinitve
//0x..1..... T0IE postavimo na 1 da omogocimo vklop prekinitve povzrocenega zaradi timerja 0
//0x.....0.. T0IF postavimo na 0 saj bi nam v nasprotnem primeru takoj sprožil prekinitev, je pokazatelj da se je sprožila prekinitev zaradi timerja 0
//Nastavimo timer 0
OPTION_REG = 0x00001111;
//0x..0..... izberemo notranjo uro
//0x...0.... povečanje pri prehodu iz nizkega stanja na visokega
//0x....1... preddelilnik je namenjen timerju 0
//0x.....111 preddelilnik je nastavljen na 256
while(1) {
}
} |
|
_________________ Lp Blaž
Prvi poklic na svetu je bil električar. Še preden je bog rekel naj bo luč, so oni že kable napeljevali. |
|
Nazaj na vrh |
|
|
Peter123 Član
Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1366 Aktiv.: 7.34 Kraj: Lj.
|
Objavljeno: Sre Maj 30, 2012 8:37 am Naslov sporočila: Podoben problem v drugem compilerju |
|
|
Tudi sam sem naletel na problem z interupti.
In sicer uporabljam CCS compiler verzija 4... .
Opis problema: spremenljivka "seconds" pri izpisu skače med 1 in 0. Kar si ne znam razložiti. Načeloma se interupt sproži na 0,064ms kar pomeni da bi števec moral biti sigurno več kot 1 ali 0.
Neko zadevo sem spregledal a je sam enostavno ne opazim.
Hvaležen za pomoč.
[code]
#include <16F73.h>
#fuses HS,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT
#use delay(clock=16000000)
#include <LCD420.c>
unsigned int cas;
unsigned short seconds, hitrost;
float prevozeni_km;
//unsigned int prevozeni_km;
#define stetje_impulzev 3; //Koliko impulzev naj dobi stevec
//preden zacne z normalnim obratovanjem in vklopi luc.
#define pot_med_2_vijaki "0,2812"; //Pot ki jo opravi guma na cesti med 2 vijaki.
#define Tipka1 PIN_A0
#define Tipka2 PIN_A1
#define Luc PIN_C1
#define Ind_sen PIN_C0
#define Osv_LCD PIN_B3
#define OUT1 PIN_A3
#define POT PIN_A2
//---------------------------------interupt rutina--------------
#define INTS_PER_SECOND 15625 //(16000000/(4*256*1))
//short seconds; //Number of interrupts left
unsigned int int_count; //before a second has elapsed
#int_rtcc //This function is called
clock_isr() //every time the RTCC (timer0)
{ //overflows (255->0)
//For this program this is apx
//61 times per second.
++seconds;
}
//----------------------------------------------------------
void main()
{
//za interupt:
// byte start;//bajt za zacetno vrednost casa
int_count=INTS_PER_SECOND;
set_rtcc(0);
setup_counters (RTCC_INTERNAL, RTCC_DIV_1);
enable_interrupts (GLOBAL);
//zacetek programja
SET_TRIS_A( 0xE0 ); // 11100000
SET_TRIS_B( 0x00 ); //Izhodi 00000000
SET_TRIS_C( 0x80 ); //Izhodi 10000000
output_low(Osv_LCD);
lcd_init();
lcd_putc("\fMerilec hitrosti\n");
lcd_putc("V0.01 By PeterP.\n");
delay_ms(2000);
//-------------------------Stetje impulcev do vklopa luci
output_low(Luc);
cas = stetje_impulzev;
while(cas != 0)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Imp.do vklopa:%02u",cas);
if (!input(Ind_sen))
{
output_high(Osv_LCD); //za signalizacijo
--cas;
delay_ms(500);
output_low(Osv_LCD);
while (input(Ind_sen)==0) //pocakamo da izgubimo signal iz senzorja, ce je slucajno senzor v mirovanju sklenjen
{
//cas=cas;
}
}
output_low(Osv_LCD);
}
output_high(Luc);
lcd_putc("\f");
//-------------------------Stevec je vklopil luc in nadaljuje z programom
cas=0; //Ponovno vpisemo 0 sa vsak primer.
prevozeni_km = 0;
enable_interrupts (INT_RTCC);
seconds = 0;
while (TRUE)
{
if (!input(Ind_sen))
{
prevozeni_km = prevozeni_km + 0.0002812;
while (input(Ind_sen)==0) //pocakamo da izgubimo signal iz senzorja, ce je slucajno senzor v mirovanju sklenjen
{
//cas=cas;
}
}
lcd_gotoxy(1,1);
hitrost = ( 0.2812 / seconds ) * 1000;
seconds = 0;
printf(lcd_putc,"Hitrost: %d km",hitrost);
lcd_gotoxy(1,2);
printf(lcd_putc,"Trip: %3.2f km",prevozeni_km);
lcd_gotoxy(1,3);
printf(lcd_putc,"Cas: %3d ms",seconds);
//clear_interrupt(RTCC); //interupt postavimo na 0 na zacetek za novo merjenje.
//SET_RTCC(0);
// lcd_gotoxy(1,4);
// printf(lcd_putc,"Cas: %3d ms",RTCC);
// delay_ms(300);
}
}
[/code]
Opis: |
|
Download |
Ime datoteke: |
V1.c |
Velikost datoteke: |
3.08 KB |
Downloadano: |
2 krat |
|
|
Nazaj na vrh |
|
|
Tonny Član
Pridružen-a: Sre 23 Dec 2009 11:57 Prispevkov: 289 Aktiv.: 1.66 Kraj: Vrhnika - MS
|
Objavljeno: Sre Maj 30, 2012 9:14 am Naslov sporočila: |
|
|
Pozdravljen,
če testiraš točno to kodo, katero si poslal, potem je v tisti glavni zanki while(TRUE) stavek, ki pravi seconds=0, medtem ko je zakasnitev 300ms kot komentar. Ob tem predvidevam, da je input(Ind_sen) večinoma '1', razen ob obratu kolesa, ki potegne senzor navzdol, tako da je čakanje na ponovno enico (in s tem izvedba celotne if zanke) dokaj kratek čas.
|
|
Nazaj na vrh |
|
|
Peter123 Član
Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1366 Aktiv.: 7.34 Kraj: Lj.
|
Objavljeno: Sre Maj 30, 2012 10:45 am Naslov sporočila: |
|
|
seconds=0 postavim na nulo da mi ni treba računati stari čas - novi čas.
Načeloma časi niso tako kratki. V praksi bo senzor prišel na1 na cca 4ms. Ali več.
Na mizi pa tako ali tako ne dosežem tako hitrih impulzev (z roko). Imam pa tudi zanko, ki nato čaka da se senzor tudi umakne.
Torej tudi če odstranim zakasnitev za 300ms še vedno ne deluje.
|
|
Nazaj na vrh |
|
|
Tonny Član
Pridružen-a: Sre 23 Dec 2009 11:57 Prispevkov: 289 Aktiv.: 1.66 Kraj: Vrhnika - MS
|
Objavljeno: Sre Maj 30, 2012 11:26 am Naslov sporočila: |
|
|
Samo, da razčistiva:
input(ind_sen) je normalno '0', razen takrat, ko se mimo pripelje tvoja roka (zavrti kolo), ali ravno obratno?
Sicer pa, tvoj izpis "Cas" na zaslonu bo skoraj vedno enak 0, ker ravno pred izpisom brišeš svojo spremenljivko "seconds".
V primeru, da ti hitrost kaže neko normalno cifro in je problem samo v času, potem samo premakni "seconds=0;" na konec, ko že izpišeš vse podatke na zaslon.
|
|
Nazaj na vrh |
|
|
Peter123 Član
Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1366 Aktiv.: 7.34 Kraj: Lj.
|
Objavljeno: Sre Maj 30, 2012 11:41 am Naslov sporočila: |
|
|
Senzor deluje na obratno logiko.
Torej ko pride v bližino kovina (induktivni senzor) se vhod v PIC postavi na 0.
Premikanje seconds=0 ne pomaga ker tudi prikaz hitrosti ne deluje. Ravno zato, ker mi ne deluje prikaz hitrosti sem dodal prikaz seconds kjer se vidi da nekaj ni vredu z to spremenljivko. Napake pa enostavno ne vidim/najdem.
|
|
Nazaj na vrh |
|
|
Tonny Član
Pridružen-a: Sre 23 Dec 2009 11:57 Prispevkov: 289 Aktiv.: 1.66 Kraj: Vrhnika - MS
|
Objavljeno: Sre Maj 30, 2012 11:50 am Naslov sporočila: |
|
|
Bomo že prišli nekam počasi, brez skrbi
Ta "seconds" naj bi meril čas med pulzi senzorja, ane?
Kadar senzor nima impulza, se celotna while zanka vrti, kar pomeni, da sproti briše tudi tvoj čas (seconds=0). Poskusi premakniti to vrstico v if zanko, takoj za prevozeni_km = prevozeni_km + 0.0002812; .
|
|
Nazaj na vrh |
|
|
Peter123 Član
Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1366 Aktiv.: 7.34 Kraj: Lj.
|
Objavljeno: Sre Maj 30, 2012 12:25 pm Naslov sporočila: |
|
|
Tudi ni v redu.
Tudi če iz while (TRUE) zanke izbrišem seconds=0 zadeva skače med 1 in 0.
|
|
Nazaj na vrh |
|
|
Tonny Član
Pridružen-a: Sre 23 Dec 2009 11:57 Prispevkov: 289 Aktiv.: 1.66 Kraj: Vrhnika - MS
|
Objavljeno: Sre Maj 30, 2012 1:45 pm Naslov sporočila: |
|
|
Program se ti prevede brez opozoril?
Deljenje z '0' namreč ni dovoljeno (hitrost = ( 0.2812 / seconds ) * 1000;).
Če bi jaz že kdaj kaj resnega delal v CCS-u, bi ti svetoval zagon kakšnega debugerja (verjamem, da ima CCS vgrajenega), pa bi lahko korak za korakom gledal to spremenljivko "seconds" in videl kaj se z njo dogaja tekom tvoje kode.
Kaj ti izpisuje če vstaviš to funkcijo:
while (TRUE)
{
lcd_gotoxy(1,3);
printf(lcd_putc,"Cas: %3d ms",seconds);
delay_ms(1000);
}
Vrednost "seconds" naj bi bila v tem primeru nekaj čez 60, če prekinitvena rutina na števcu deluje tako kot si si zamislil.
|
|
Nazaj na vrh |
|
|
Peter123 Član
Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1366 Aktiv.: 7.34 Kraj: Lj.
|
Objavljeno: Sre Maj 30, 2012 2:33 pm Naslov sporočila: |
|
|
Edino opozorilo:
Warning 208 "V1.c" Line 27(1,10): Function not void and does not return a value clock_isr
Napak ne napiše/najde.
Če probam predlagano kombinacijo potem mi izpisuje 0 in 1 z 1s zamikom. Torej 1s 1 in 1s 0.
|
|
Nazaj na vrh |
|
|
Tonny Član
Pridružen-a: Sre 23 Dec 2009 11:57 Prispevkov: 289 Aktiv.: 1.66 Kraj: Vrhnika - MS
|
Objavljeno: Sre Maj 30, 2012 4:47 pm Naslov sporočila: |
|
|
Potem je problem še v nastavitvi prekinitvene rutine. Tukaj bo pa pomagal kdo, ki je bolj domač s CCS-om. Jaz žal nisem. Morda si lahko pomagaš tudi z "uradnimi" primeri (nekje na sredini je seconds timer). Morda najdeš kakšno spregledano malenkost.
|
|
Nazaj na vrh |
|
|
Peter123 Član
Pridružen-a: Tor 13 Jan 2009 15:34 Prispevkov: 1366 Aktiv.: 7.34 Kraj: Lj.
|
Objavljeno: Čet Maj 31, 2012 11:48 am Naslov sporočila: |
|
|
Ah saj bol enostavno že ne more bit grrr.
Rešitev: byte seconds;
|
|
Nazaj na vrh |
|
|
galjotj Član
Pridružen-a: Pet 02 Nov 2012 15:08 Prispevkov: 231 Aktiv.: 1.65 Kraj: Zgornji Brnik
|
Objavljeno: Sre Feb 27, 2013 10:10 pm Naslov sporočila: Prioritete prekinitev? |
|
|
Dovolite da uletim še z enim problemom okrog PIC prekinitev
V C18 namreč programiram 18F2550 za nemene daljinskega vodenja. Zunanjo prekinitev uporabljam za dekodiranje PPM impulzov, prekinitev dveh timerjev pa za krmiljenje servo motorjev. Stvar sicer kar deluje, vendar se pojavljajo motnje pri funkciji, ki uporablja "Low priority" prekinitev. Nekako sem sumil, da bi se to utegnilo dogajati, saj se obe funkcionalnosti "dogajata" v podobnih "tajmingih" in se lahko "zgodita" v istem trenutku, a sem upal da se to ne bo tako zelo poznalo. Pomaga sicer kakšno "filtriranje", a to ni ravno to....
A kdo ve kaj več o reševanju pojava hkratnih prekinitev, njihovih prioritetah ipd.., da bi se to eventualno dalo najbolje rešit. V nasprotne primeru ne vidim druge rešitve, kot da eno fukcionalnost preselim "ven".
Hvala in Lep pozdrav
_________________ Pa sam programirat sem hotu! |
|
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: 76 dni
Powered by phpBB © 2001, 2005 phpBB Group
|