340 likes | 583 Views
Programmet onoffred.c. Processorns konfiguration. Javascript på webben!. #pragma config |= 0x3fB0. Först definitionerna:. /* onoffred.c */ #define ON 1 #define OFF 0 #include "16F628.h" #pragma config |= 0x3f90 #pragma bit lightdiode @ RB0 #pragma bit contact @ RB1.
E N D
Programmet onoffred.c William Sandqvist william@kth.se
Processorns konfiguration Javascript på webben! #pragma config |= 0x3fB0 William Sandqvist william@kth.se
Först definitionerna: /* onoffred.c */#define ON 1 #define OFF 0 #include "16F628.h" #pragma config |= 0x3f90#pragma bit lightdiode @ RB0 #pragma bit contact @ RB1 William Sandqvist william@kth.se
Sedan huvudprogrammet void main(){ /* Init */ TRISB = 0b11111110; while (1) { if (contact == ON) /* Lightdiode ON */ lightdiode = ON; else /* Lightdiode OFF */ lightdiode = OFF; }} William Sandqvist william@kth.se
Kompilera – Ladda ner koden William Sandqvist william@kth.se
Provkör Våra lysdioder har inbyggt ström-begränsnings-motstånd Det långa benet är pluspolen (Anod). William Sandqvist william@kth.se
Cc5x C char är 8 bitar unsigned 0…255int är 8 bitar signed -128…0…+127bit är en bit 0 eller 1. Åtta olika bitvariabler får plats i en Byte William Sandqvist william@kth.se
Aritmetiska operatorer Modulo operatorn ("%") är förmodligen mindre känd än de övriga operatorerna. Den gör en heltals-division, och resultatet blir divisionens rest.Heltalsdivision: 22/3 = 7Modulo, resten: 22%3 = 1 William Sandqvist william@kth.se
Operatorer till vilkorsuttryck C har ingen Boolsk variabeltyp SANT/FALSKT utan använder heltalsvariabler till detta. För C är SANT alla heltal förutom 0 som är FALSKT! William Sandqvist william@kth.se
”bit för bit” operatorer "bit för bit" operatorerna används för att "vaska ut" information om enskilda bitar i en variabel. Eftersom PIC-processorerna har bit-operationer kan man enkelt nå enskilda bitar direkt. Man har då mindre användning för "bit för bit" operationerna. William Sandqvist william@kth.se
Maskning Processorer som saknar bit-instruktioner använder i stället ”Maskning” för att nå enskilda bitar. William Sandqvist william@kth.se
Maskning med AND AND används för att "släcka ut" oönskade bitar. Ofta läser man en Byte, men är bara intresserad utav några av bitarna. En AND-mask är ett binärt tal som har 1:or i de bitpositioner man är intresserad av, och 0:or i övriga bitpositioner.Ett exempel, tal = 10101010 ( AA hex ), mask = 00001111 ( 0F hex ): De fyra sista positionerna av tal bibehölls eftersom masken där hade 1:or, de övriga bitarna där masken hade 0:or 0-ställdes. William Sandqvist william@kth.se
Maskning med AND För PIC-processorerna kan assemblerinstruktionenANDWF f,d användas.I C-program skriver man tal = tal & mask;( eller kortare: tal&= mask; ). En vanlig uppgift är att ta reda på om en viss bit är "1": if( (tal & mask) == mask ) masken innehåller bara 1 i den aktuella bitpositionen. William Sandqvist william@kth.se
Maskning med OR OR används för att "ett-ställa" vissa bitar i ett dataord (och lämna de andra orörda).Ett exempel, tal = 10101010 ( AA hex ), mask = 00001111 ( 0F hex ): De bitpositioner där masken har 1:or blir 1-ställda, de övriga behåller de värden de har. William Sandqvist william@kth.se
Maskning med OR PIC-processorerna har assemblerinstruktionen IORWF f,d. I C-program kan man "slå på" bitar med tal = tal | mask;( eller kortare: tal |= mask; ). Man "slår av" bitar med tal = tal & ~mask;( eller kortare: tal &= ~mask; ). William Sandqvist william@kth.se
Maskning med XOR XOR används för att "toggla" ( byta värde ) on/off på enskilda bitar i en byte. PIC-processorerna har assemblerinstruktionen XORWF f.d I C-program skriver man tal = tal ^ mask;( eller kortare: tal ^= mask; ). William Sandqvist william@kth.se
C, Tilldelning Tilldelningsoperatorn ("=") låter en variabel bli lika med en annan. x = y;I C-språket kan man kombinera tilldelningsoperatorn med de aritmetiska operatorerna, eller "bit för bit" operatorerna, till bekväma förkortningar, för att erhålla speciella tilldelningsoperatorer. William Sandqvist william@kth.se
Increment och Decrement En vanlig uppgift i program är att öka eller minska en variabel med ett. Det går naturligtvis att göra med addition eller subtraktion, men de flesta processorer har även speciella, optimerade, instruktioner för detta. C-språket har därför Increment (öka med ett) och Decrement (minska med ett) -operatorer: x++ ; /* add 1 to x */ x-- ; /* subtract 1 from x */ Operatorerna kan även skrivas ++x och --x. Då utförs ökningen/minskningen av xinnan variabeln används (annars efter). Med dessa fyra varianter kan programmeraren skräddarsy uttryck så att de blir så korta och effektiva som möjligt. William Sandqvist william@kth.se
Mer C ? Typiskt för C är användningen av så kallade pekare. Så långt arkitekturen tillåter, kan man använda pekare i sina PIC-program, men sanningen är att det inte finns speciellt mycket att peka på? - Mer om programspråket C kan man lära sig genom att tex. gå den fristående kvällskursen ID135V. Vägen till CUlf Bilting / Jan SkansholmStudentlitteratur ISBN 91-44-01468-6 William Sandqvist william@kth.se
Pip för fem! William Sandqvist william@kth.se
Initiering Initiering: buzzer = OFF; TRISB = 0b11.0.1.1111; /* RB0 ...RB3 in, RB5 out */ char tal = 0; William Sandqvist william@kth.se
Read hexcode Ledningsdragningen ger fel ordning mellan hex-bitarna och portbitarna. Det fixar programmet! tal.0 = PORTB.3; tal.1 = PORTB.2; tal.2 = PORTB.1; tal.3 = PORTB.0; William Sandqvist william@kth.se
Programmet pip för fem /* cmp5.c Buzz at binary "5" */#include "16F628.h" #pragma config |= 0x3f90 #define ON 1 #define OFF 0 #pragma bit buzzer @ PORTB.5 void main( void) { buzzer = OFF; TRISB = 0b11.0.1.1111; /* RB0-RB3 in, RB5 out */ char tal = 0; while( 1 ) { tal.0 = PORTB.3; tal.1 = PORTB.2; tal.2 = PORTB.1; tal.3 = PORTB.0; if( tal == 5 ) buzzer = ON; else buzzer = OFF; }} Utmaning 1: Pip för udda tal! Utmaning 2: Pip för A…F! William Sandqvist william@kth.se
Radiobutton … Att välja endast ett alternativ bland flera … if(a) b; else if(c) d; else f; William Sandqvist william@kth.se
switch – case Switch( a ){ case 1: b = 5; break; case 2: b = 7; break; case 3: b = 10; break; default : b = 0;} a ska vara en heltalsvariabel. Här sker en omkodning mellan a och b. Break behövs för att inte alla efterföljande alternativen också ska utföras. Cc5x lägger ut mer effektiv kod för switch – case än för if – else if – else if – else William Sandqvist william@kth.se
Kontaktstudsar ! Tänd/Släck lysdioden varannan tryckning (Toggle funktion). Problemet är att när man trycker, eller släpper, en mekanisk kontakt så studsar den ett tag mot kontaktytan innan den lägger sig till ro. PIC-processorn är så snabb att den kan uppfatta varje studs som en ”egen” kontakt-tryckning! Om en kontakt studsar mycket eller lite syns inte på utsidan! William Sandqvist william@kth.se
bounce.c programmet som driver dig till vansinne! void main( void) { TRISB = 0b11111110; /* RB0 out, RB1 in */ while(1) { while( button == OFF) ; /* wait for ON */ lightdiode = ! lightdiode; /* toggles light */ while( button == ON ) ; /* wait for OFF */ } } Programmet är endast användbart som slumpgenerator! William Sandqvist william@kth.se
debounce.c void main( void) { char i, j; TRISB = 0b11111110; /* RB0 out, RB1 in */while(1) { /* - wait for ON - */ while( button == OFF) ; lightdiode = ! lightdiode; /* toggles light */ /* - delay 10 msec - */ for(i =0; i < 40; i++ )for(j =0; j < 250; j++ ) ; /* - wait for OFF - */ while( button == ON ) ; /* - delay 10 msec - */for(i =0; i < 40; i++ )for(j =0; j < 250; j++ ) ; }} Fördröjningsfunktion delay() ? William Sandqvist william@kth.se
C - Funktioner Först i programmet utanför main(). /* en funktionsdeklaration */int differens( int, int); . . . x = differens( 15, 3); /* ett funktionsanrop */ . . . /* funktionsdefinitionen */ int differens(int a, int b) { return a – b; } Funktionen anropasinifrån main(). Funktionsdefinitionen efter main() eller i egen fil. Vad blir x ? William Sandqvist william@kth.se
TIMER0 TIMER0 är en 8-bitars modulo 256-räknare som kan läsas/skrivas med program. Om biten TOCS i OPTION -registret är "0" så räknas var fjärde av processorns klockcykler ( Fosc/4 ). Om biten TOCS är "1" räknas de pulsflanker som inkommer på pinnen T0CKI. Med biten TOSE bestämmer man om det är positiva eller negativa "flanker" som ska räknas. Med biten PSA=0 kan man koppla in en prescaler, en frekvensdelare. Med den inkopplad räknas bara en bråkdel av de inkommande pulserna, och det tar då längre tid innan TIMER0 "räknar runt". Med bitarna PS2PS1PS0 ställer man in prescalerns delningstal. William Sandqvist william@kth.se
Delay-function Fördröjning 1…255 ms. /* Delays a multiple of 1 milliseconds at 4 MHz */ /* (16F628 internal clock) using the TMR0 timer */ void delay( char millisec) { OPTION = 2; /* prescaler divide by 8 */ do { TMR0 = 0;while ( TMR0 < 125) /* 125 * 8 = 1000 */ ; } while ( -- millisec > 0); } För 10 ms fördröjning: delay(10); William Sandqvist william@kth.se
Längre tider … /* Delays a multiple of 10 milliseconds using the *//* TMR0 timer Clock : 4 MHz => period T = 0.25 us *//* 1 IS = 1 Instruction Cycle = 1 us error: 0.16 % */ void delay10( char n) {char i; OPTION = 7;do { i = TMR0 + 39; /* 256 microsec * 39 = 10 ms */while ( i != TMR0) ; }while ( --n > 0); } delay10(250); ger 2,5 s fördröjning. William Sandqvist william@kth.se
Ändå längre tider … /* 255*2,55 c:a 11 min */for(i = 0; i < 255; i++) delay10( 255 ); /* 255*255*2,55 c:a 2 dygn */for(j = 0; j < 255; j++)for(i = 0; i < 255; i++) delay10( 255 ); Delay-funktionerna finns i filen delays.c. Placera en kopia av den filen i ditt arbetsbibliotek och ta med den i programmet: #include ”delays.c” William Sandqvist william@kth.se
Utmaning Ändra programmet debounce.c så att det utnyttjar funktionen delay() i stället för for-slingorna på två ställen! William Sandqvist william@kth.se