1 / 41

/* FlashingLights.c, m.peshkin 2007-12-24 */ #include <18f4520.h>

/* FlashingLights.c, m.peshkin 2007-12-24 */ #include <18f4520.h> #fuses HS, NOLVP, NOWDT, NOPROTECT #use delay(clock=20000000) // 20 MHz crystal on PCB void main() { int i=0; while (TRUE) { if (i==0) i++; // if i is zero increment it

nellie
Télécharger la présentation

/* FlashingLights.c, m.peshkin 2007-12-24 */ #include <18f4520.h>

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. /* FlashingLights.c, m.peshkin 2007-12-24 */ #include <18f4520.h> #fuses HS, NOLVP, NOWDT, NOPROTECT #use delay(clock=20000000) // 20 MHz crystal on PCB void main() { int i=0; while (TRUE) { if (i==0) i++; // if i is zero increment it output_d(i); // display byte on pins RD0...RD7 i = i<<1; // roll i left one bit (double its value) delay_ms(50); } }

  2. datatypes all variables must be DECLARED and may be INITIALIZED int8 0 to 255 (00000000 to 11111111) int16 0 to 65535 (space required: 2 bytes each) int32 0 to 4294967295 (4 bytes each) signed int8 -128 to 127 (e.g. 11111011 is -4) signed int16 -32768 to 32767 signed int32 ... float is signed, range +/- 10-38 to 10+38 (4 bytes each) floats are much slower there are only 1500 bytes of RAM for variables

  3. int32 Encoder1=1<<31; int32 Encoder2=1<<31; // start counters in the middle int Encoder1state=0; // will contain only 4 relevant bits int Encoder2state=0; signed int DecoderLookup[16] = {0, -1, +1, 0, +1, 0, 0, -1, -1, 0, 0, +1, 0, +1, -1, 0}; int16 LastTime, ThisTime;

  4. Things to watch out for in C or PIC C variable scope - variables declared inside a function (subroutine) are local to that function only. variables declared outside it are common to all functions int j; void FlashRed() { int j; for (j=0; j<10; j++) { output_high(REDLED); delay_us(50); // LED at 5% duty cycle (35mA average) output_low(REDLED); delay_us(950); } }

  5. Things to watch out for in C or PIC C type conversion & overflow int i, j; i = 200; j = 60; if (i + j > 220) will be FALSE if ((int16) i + (int16) j > 220) will be TRUE use lots of parentheses and type declarations to be sure you get what you want

  6. Things to watch out for in C or PIC C assignment when you meant comparison int i, j; i = 200; j = 60; if (i = j) will result in i = 60 ! if (i == j) ... i != j not equal to i >= j greater than or equal to && logical AND || logical OR TRUE always TRUE, e.g. while (TRUE) { do this code forever }

  7. Odd C things i++ means i = i+1; similarly i-- sumup += i means sumup = sumup + i 0xF0 means base 16, here 11110000 j = i << 3 means roll left three bits (multiply by 8), e.g. if i = 1000101101110010, j will be 0101101110010000 result = (i & j) is bit-by-bit AND (e.g. for masking) e.g. i = 00001111 j = 01010101 result = 00000101 result = (i | j) is bit-by-bit OR e.g. i = 00001111 j = 01010101 result = 01011111 example -- if ((value & 1) > 0) is true if value is odd if ((value & 7) == 0) is true if value is divisible by 23

  8. structure of a program /* FlashingLights.c, m.peshkin 2007-12-24 */ #include <18f4520.h> #fuses HS, NOLVP, NOWDT, NOPROTECT #use delay(clock=20000000) void main() { int i=0; while (TRUE) { if (i==0) i++; // if i is zero increment it output_d(i); // display byte on pins RD0...RD7 i = i<<1; // roll i left one bit (double its value) delay_ms(50); } } <-- a whole bunch of definitions <-- turn features of the PIC on/off <-- needs to know the clock speed <-- the main program starts like this <-- and ends like this

  9. /* this is for keeping accurate track of time */ int32 clockticks = 0; // real time clock in 13.1mS increments int flicker=0; #INT_TIMER0 void Timer0isr() { if ((clockticks++ & 511) == 0) flicker++; } void main() { setup_timer_0(RTCC_DIV_1); enable_interrupts(INT_TIMER0); enable_interrupts(GLOBAL); output_low(LED_White1); // turn off the visible LEDs output_low(LED_White2); output_low(IRED_Right); // turn off the IREDs output_low(IRED_Left); output_low(IRED_Middle); <-- global variables declared <-- an interrupt routine <-- the main program

  10. .... ... } int16 ReadLeftBumper() { int16 CollideL, i; set_adc_channel(2); // Left collision sensor, AN2 = pin 4 CollideL = 0; for (i=0; i<10; i++) { delay_us(50); CollideL = CollideL + read_adc(); } return(CollideL); } <-- end of main program <-- a function

  11. void main() { int ix, iy; setup_adc_ports(AN0_TO_AN1); setup_adc(ADC_CLOCK_INTERNAL); while (TRUE) { set_adc_channel(0); delay_us(10); ix = read_adc(); set_adc_channel(1); delay_us(10); iy = read_adc(); if (ix > 128) output_high(PIN_D3); else output_high(PIN_D4); if (iy > 128) output_high(PIN_D6); else output_high(PIN_D7); delay_ms(50); } } using analog inputs and digital outputs

  12. /* Counter0.c m.peshkin 2007-12-24 Use Timer0 as a 16 bit counter of external events; pulses arrive on pin RA4/T0CK1 This also works for Timers 1 and 3 but not 2 */ #include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT #use delay(clock=20000000) int16 count; void main() { setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_1); while (TRUE) { count = get_timer0(); output_D((int8) (count & 255)); // display low order byte delay_ms(10); } }

  13. /* Pololu.c m.peshkin 2008-01-24 Demonstate code for typical robot servo cycle, on a 2 motor robot High priority Timer2 interrupt (at 1mS interval) for software decoding of quadrature signals Low priority Timer3 interrupt (at 13.1 mS interval) for servo calculations Two channels of PWM output, with the PWM2 output moved from pin 16 to pin 36 to avoid conflict with Timer1 input */ #include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT, CCP2B3 // CCP2B3 moves PWM2 output to pin 36 (RB3) rather than pin 16 (RC1) #device HIGH_INTS=TRUE // allow high priority interrupts #use delay(clock=20000000)

  14. signed int32 Encoder1, Encoder2; int Encoder1state, Encoder2state; signed int DecoderLookup[16] = {0, -1, +1, 0, +1, 0, 0, -1, -1, 0, 0, +1, 0, +1, -1, 0}; // interrupt service routine when timer2 overflows, which will be set up in main() to be at 1mS intervals #INT_TIMER2 HIGH // HIGH makes this the one high priority interrupt that can interrupt other ISRs void Timer2isr() { Encoder1state = ((((Encoder1state << 1) + input(PIN_B2)) << 1) + input(PIN_B4)) & 15; // upper encoder, RB2 & RB4 Encoder1 += DecoderLookup[Encoder1state]; Encoder2state = ((((Encoder2state << 1) + input(PIN_B0)) << 1) + input(PIN_B1)) & 15; // lower encoder, RB0 & RB1 Encoder2 += DecoderLookup[Encoder2state]; }

  15. // ISR when timer3 overflows, which will be set up to be at servo rates (e.g. 13.1mS) #INT_TIMER3 void Timer3isr() { if (Encoder1 + Encoder2 < 0) { // is one encoder ahead? set_pwm1_duty(78); set_pwm2_duty(10); output_D(0x0F);// pretty lights show which enc. is ahead } if (Encoder1 + Encoder2 > 0) { set_pwm1_duty(68); set_pwm2_duty(0); output_D(0xF0); } }

  16. void main() { output_D(0); // flash once to say hello delay_ms(50); output_D(255); delay_ms(150); output_D(0); delay_ms(50); Encoder1 = 0; Encoder2 = 0; // 16KHz clock, interrupt every 4*50nS * 4 * 78 * 16 = 1.0mS setup_timer_2(T2_DIV_BY_4, 77, 16); // timer 3 used for 13.1mS interval interrupt setup_timer_3(T3_INTERNAL | T3_DIV_BY_1); enable_interrupts(INT_TIMER2); enable_interrupts(INT_TIMER3); enable_interrupts(GLOBAL);

  17. // PWM output on CCP1/RC2, pin 17 this goes to upper motor, with RC4 setup_ccp1(CCP_PWM); // PWM output on CCP2/RB3, pin 36 this goes to lower motor, with RC5 setup_ccp2(CCP_PWM); // upper motor; fast forward is C4=low & duty=78; Encoder1 counts up output_low(PIN_C4); set_pwm1_duty(78); // lower motor; fast forward is C5=high & duty=0; Encoder2 counts down output_high(PIN_C5); set_pwm2_duty(0); // this is where logic would go while (TRUE) { delay_ms(20); } }

  18. signed int DecoderLookup[16] = {0, -1, +1, 0, +1, 0, 0, -1, -1, 0, 0, +1, 0, +1, -1, 0}; Encoder1state = ((((Encoder1state << 1) + input(PIN_B2)) << 1) + input(PIN_B4)) & 15; Encoder1 += DecoderLookup[Encoder1state]; ABAB 0000  0 1010 previous state 0001  -1 1010 new state: no change 0010  +1 1010 0011  0 *error* 1011 B has gone high 0100  +1 1111 0101  0 1111 0110  0 *error* 1101 A has gone low 0111  -1 0101 1000  -1 0101 1001  0 *error* 0100 B has gone low 1010  0 1011  +1 1100  0 *error* 1101  +1 1110  -1 1111  0

More Related