Första program PIC
> Så är någon en fin länk som beskriver detta utförligt i c eller basic?
Det skulle inte hjälpa dig ett smack !!
Du börjar i helt fel ände, så att säga. Du ska läsa *allt* i databladet för den
PIC du använder som handlar om interrupt (det är bara ett par sidor).
Glömt allt om C eller BASIC tillsvidare.
Sedan, när du förstår hur det fungerar, kan du kolla hur det
är löst i C eller BASIC. Om inte databladet räckte till så finns det säkert
en del "turorials" som handlar om interrupt som man kan leta reda på.
Men, interrupt på PIC är väldigt enkelt igentligen, det är uppenbartligen
bara någon liten "tröskel" du har fastnat på.
Slutligen så är interrupt en central funktion i mikrokontrollers, det är inte
mycket som man kan göra utan att använda dom. Själva koden blir
mycket renare och välstrukturerad dessutom.
Det skulle inte hjälpa dig ett smack !!
Du börjar i helt fel ände, så att säga. Du ska läsa *allt* i databladet för den
PIC du använder som handlar om interrupt (det är bara ett par sidor).
Glömt allt om C eller BASIC tillsvidare.
Sedan, när du förstår hur det fungerar, kan du kolla hur det
är löst i C eller BASIC. Om inte databladet räckte till så finns det säkert
en del "turorials" som handlar om interrupt som man kan leta reda på.
Men, interrupt på PIC är väldigt enkelt igentligen, det är uppenbartligen
bara någon liten "tröskel" du har fastnat på.
Slutligen så är interrupt en central funktion i mikrokontrollers, det är inte
mycket som man kan göra utan att använda dom. Själva koden blir
mycket renare och välstrukturerad dessutom.
hmm.. av någon konstig anledning så såg jag inte att det fanns nya posts på denna tråd så tur att jag skulle dubbelchecka en sak här, skumt...
Men som du säger det kanske är fel ände och börja i. Jag har laddat hem databladet nu och nu ska jag leta upp och läsa det.
Och jag har förstått att interrupts är mycket användbart så jag får hoppas bara att detta inte blir för komplicerat, men men så ska man inte tänka det är bara att läsa o läsa o läsa tills man förstår. Någon gång måste man ju förstå det hela så det blir värt besväret
Edit: nu har jag kollat igenom lite snabbt och jag märkte att det bara fanns en sida om detta, men detta hjälpte mig att förstå mitt första exempel iaf!
så om man nu ska göra det första exemplet lite bättre genom att ha en check så ska man skriva såhär istället?
Men som du säger det kanske är fel ände och börja i. Jag har laddat hem databladet nu och nu ska jag leta upp och läsa det.
Och jag har förstått att interrupts är mycket användbart så jag får hoppas bara att detta inte blir för komplicerat, men men så ska man inte tänka det är bara att läsa o läsa o läsa tills man förstår. Någon gång måste man ju förstå det hela så det blir värt besväret
Edit: nu har jag kollat igenom lite snabbt och jag märkte att det bara fanns en sida om detta, men detta hjälpte mig att förstå mitt första exempel iaf!
så om man nu ska göra det första exemplet lite bättre genom att ha en check så ska man skriva såhär istället?
Kod: Markera allt
void interrupt() {
if(INTCON == 0x4)
{
cnt++; // Increment value of cnt on every interrupt
TMR0 = 96;
INTCON = 0x20; // Set T0IE, clear T0IF
}
}//~
Jag vet inte vad syftet är med koden, men...
> if(INTCON == 0x4)
Jag antar att det där är för att kolla någon xxIF flagga ?
Bättre att skriva ut i koden vilken det är!
> INTCON = 0x20; // Set T0IE, clear T0IF
Samma sak här.
Använd bit-operationer och sätt den aktuella biten (T0IF) direkt.
> Set T0IE,
Onödigt. Det ska vara gjort långt tidigare.
Och om den inte var satt tidigare så hade du aldrig kommit hit i alla fall...
> if(INTCON == 0x4)
Jag antar att det där är för att kolla någon xxIF flagga ?
Bättre att skriva ut i koden vilken det är!
> INTCON = 0x20; // Set T0IE, clear T0IF
Samma sak här.
Använd bit-operationer och sätt den aktuella biten (T0IF) direkt.
> Set T0IE,
Onödigt. Det ska vara gjort långt tidigare.
Och om den inte var satt tidigare så hade du aldrig kommit hit i alla fall...
Ytterligare ett tips vad gäller C-programeringen, undvik "magic numbers".
Dvs rader som:
INTCON = 0x20;
Utan i stället skriva:
#define SOME_THING_MEANINGFUL 0x20
.
.
.
INTCON = SOME_THING_MEANINGFUL;
För om en vecka eller två så har du glömt vad 0x20 betydde...
Jag kan inte PIC så jag vet inte vad raden direkt innebär, men
INTCON = 0x20;
gör att 5:te biten sätts i INTCON, övriga blir noll,
Dvs rader som:
INTCON = 0x20;
Utan i stället skriva:
#define SOME_THING_MEANINGFUL 0x20
.
.
.
INTCON = SOME_THING_MEANINGFUL;
För om en vecka eller två så har du glömt vad 0x20 betydde...
Jag kan inte PIC så jag vet inte vad raden direkt innebär, men
INTCON = 0x20;
gör att 5:te biten sätts i INTCON, övriga blir noll,
Det var mer "magic numbers" som åsnyftades.
INTCON = 0x20 tolkar jag som en variabel som sätts till värdet 0x20.
INTCON != (1<<BIT_5) och , INTCON &= ~(1<<BIT_5) är att en bit ändras, då #define BIT_5 5. Samt INTCON != BIT_5 och , INTCON &= ~BIT_5 är att en bit ändras, då #define BIT_5 0x20.
Om INTCON antas vara 8 bitar och man nödvändigtvis ska använda "magic numbers" så bör man skriva if(INTCON == 0x04), inte if(INTCON == 0x4), för att övertydligt visa att man har tänkt på alla bitarna. Det samma gäller define's.
INTCON = 0x20 tolkar jag som en variabel som sätts till värdet 0x20.
INTCON != (1<<BIT_5) och , INTCON &= ~(1<<BIT_5) är att en bit ändras, då #define BIT_5 5. Samt INTCON != BIT_5 och , INTCON &= ~BIT_5 är att en bit ändras, då #define BIT_5 0x20.
Om INTCON antas vara 8 bitar och man nödvändigtvis ska använda "magic numbers" så bör man skriva if(INTCON == 0x04), inte if(INTCON == 0x4), för att övertydligt visa att man har tänkt på alla bitarna. Det samma gäller define's.
"BIT_5" är ingefär lika dåligt som det tidigare.
Biten heter "T0IE", ingenting annat, och det är det som ska användas.
Om inte den använda kompilatorn har dessa bitar definierade, så ska den i soptunnan...
Man ska *inte* behöva bry sig om vilket *fysiskt* bitnummer det gäller.
Det är det man har kompilatorerna till...
Biten heter "T0IE", ingenting annat, och det är det som ska användas.
Om inte den använda kompilatorn har dessa bitar definierade, så ska den i soptunnan...
Man ska *inte* behöva bry sig om vilket *fysiskt* bitnummer det gäller.
Det är det man har kompilatorerna till...
Det var mer för att visa att det var just bit 5, det är att jag fortsatte att använda INTCON som var fel. Nu kan jag inte PIC men principen är ändå densamma.
Det kan även bli bekvämt att utveckla med mera defines.
tex
#define MIN_PORT PORTB /* AVR Vet ej på PIC*/
#define MIN_SIGNAL PB4
.
.
.
MIN_PORT PORTB |= MIN_SIGNAL;
Då blir programmet mer lättläst.
Det kan även bli bekvämt att utveckla med mera defines.
tex
#define MIN_PORT PORTB /* AVR Vet ej på PIC*/
#define MIN_SIGNAL PB4
.
.
.
MIN_PORT PORTB |= MIN_SIGNAL;
Då blir programmet mer lättläst.
> det är att jag fortsatte att använda INTCON som var fel.
Nej, *det* var rätt!

Det var att inte kalla *biten* vid sitt symboliska namn som var fel...
I PIC assembler skull man skriva :
BCF INTCON, T0IE ; nollar ("Clear") bit T0IE i register INTCON
BSF INTCON, T0IE ; sätter ("Set") bit T0IE i register INTCON
Vilket alltså är betydligt bättre än :
BCF INTCON, 5 ; nollar (clear) bit 5 i register INTCON
BSF INTCON, 5 ; sätter bit 5 i register INTCON
eller :
#define BIT_5 5
BCF INTCON, BIT_5 ; nollar (clear) bit 5 i register INTCON
BSF INTCON, BIT_5 ; sätter bit 5 i register INTCON
även om det i praktiken får exakt samma resultat...
Nej, *det* var rätt!


Det var att inte kalla *biten* vid sitt symboliska namn som var fel...

I PIC assembler skull man skriva :
BCF INTCON, T0IE ; nollar ("Clear") bit T0IE i register INTCON
BSF INTCON, T0IE ; sätter ("Set") bit T0IE i register INTCON
Vilket alltså är betydligt bättre än :
BCF INTCON, 5 ; nollar (clear) bit 5 i register INTCON
BSF INTCON, 5 ; sätter bit 5 i register INTCON
eller :
#define BIT_5 5
BCF INTCON, BIT_5 ; nollar (clear) bit 5 i register INTCON
BSF INTCON, BIT_5 ; sätter bit 5 i register INTCON
även om det i praktiken får exakt samma resultat...
Jo, men jag försökte vara lite generell.
Och det är C det är skrivet i.
Dessutom så så var raden
INTCON = 0x20; // Set T0IE, clear T0IF
otydlig, vilket syftar 0x20 på? T0IE eller T0IF?
Men nu vet jag!
I C:
INTCON != (1<<T0IE);
Tydlighet är en dygd i kodningen!
Efter några veckor (eller var det timmar?) så kommer man inte
ihåg vad som görs, hur ska man då begära att någon annan
ska förstå vad man skrivit?
Men det är inte alltid man lyckas helt, men har man försökt så
brukar man ha kommit en bra bit på vägen!
Och det är C det är skrivet i.
Dessutom så så var raden
INTCON = 0x20; // Set T0IE, clear T0IF
otydlig, vilket syftar 0x20 på? T0IE eller T0IF?
Men nu vet jag!
I C:
INTCON != (1<<T0IE);
Tydlighet är en dygd i kodningen!
Efter några veckor (eller var det timmar?) så kommer man inte
ihåg vad som görs, hur ska man då begära att någon annan
ska förstå vad man skrivit?
Men det är inte alltid man lyckas helt, men har man försökt så
brukar man ha kommit en bra bit på vägen!
> Dessutom så så var raden
> INTCON = 0x20; // Set T0IE, clear T0IF
>
> otydlig, vilket syftar 0x20 på? T0IE eller T0IF?
Japp, en *korrekt* (och tydlig!) kommentar hade varit :
> INTCON = 0x20; // Set T0IE, clear GIE, PEIE, INTE, RBIE, T0IF, INTF och RBIF

> I C:
> INTCON != (1<<T0IE);
Är OK, om den *enbart* "rör" T0IE och låter de andra 7 bitarna vara som de är...
> INTCON = 0x20; // Set T0IE, clear T0IF
>
> otydlig, vilket syftar 0x20 på? T0IE eller T0IF?
Japp, en *korrekt* (och tydlig!) kommentar hade varit :
> INTCON = 0x20; // Set T0IE, clear GIE, PEIE, INTE, RBIE, T0IF, INTF och RBIF

> I C:
> INTCON != (1<<T0IE);
Är OK, om den *enbart* "rör" T0IE och låter de andra 7 bitarna vara som de är...
Jepp, och vill man pilla på några till:
INTCON != (1<<T0IE) | (1<<NEXTONE);
MEN, den blir lurig vid clear:
INTCON &= ~((1<<T0IE) | (1<<NEXTONE));
Håller på att kika på "Variadic macros", har bara använt det utan att testat begränsningarna, skulle vilja driva det ännu längre:
setBits(INTCON, T0IE, NEXTONE, ...); /* NEXTONE är påhittad
) */
Men det verkar som det blir ett funktionsanrop hur jag än bär mig åt,
har iofs inte kollat hur mycket det gör när kompilatorn har joxat!
Ska se om jag hinner i helgen.
INTCON != (1<<T0IE) | (1<<NEXTONE);
MEN, den blir lurig vid clear:
INTCON &= ~((1<<T0IE) | (1<<NEXTONE));
Håller på att kika på "Variadic macros", har bara använt det utan att testat begränsningarna, skulle vilja driva det ännu längre:
setBits(INTCON, T0IE, NEXTONE, ...); /* NEXTONE är påhittad

Men det verkar som det blir ett funktionsanrop hur jag än bär mig åt,
har iofs inte kollat hur mycket det gör när kompilatorn har joxat!
Ska se om jag hinner i helgen.
Näe, inte C99 iaf, jag vet inte om tex avr-libc har något, jag har faktiskt inte kollat
!
Men
#define BIT(b) (1<<b)
#define SET(r, bv) r|=(bv)
ger
SET(myreg, BIT(5) | BIT(6) );
blir
myreg|=((1<<5) | (1<<6));
vilket är ganska tydligt..., dock inte perfekt!
Nu ska jag hinka malt dryck i svart plåtburk och kika på "På Spåret"!

Men
#define BIT(b) (1<<b)
#define SET(r, bv) r|=(bv)
ger
SET(myreg, BIT(5) | BIT(6) );
blir
myreg|=((1<<5) | (1<<6));
vilket är ganska tydligt..., dock inte perfekt!
Nu ska jag hinka malt dryck i svart plåtburk och kika på "På Spåret"!