////////////////////////////////////////////////////////////////////// // A3968 DRIVER // NUTS AND VOLTS // Author: Peter Best // Version: 1.0 // Date: 09/22/06 ////////////////////////////////////////////////////////////////////// #include #include //****************************************************************** //* Configuration Fuse Setings //****************************************************************** // Settings for PIC18F252 __CONFIG(1,OSCSDIS & HS); __CONFIG(2,BORDIS & PWRTDIS & WDTDIS); __CONFIG(3,CCP2RB3); __CONFIG(4,DEBUGEN & LVPDIS & STVREN); __CONFIG(5,UNPROTECT); __CONFIG(6,WRTEN); //****************************************************************** //* Function Prototypes //****************************************************************** void BRAKE (char motor); void FWD (char motor); void REV (char motor); void speed (char motor); void motors_init(void); //****************************************************************** //* Global Variables //****************************************************************** char days,hours,mins, secs,secs_timer; //****************************************************************** //* Real Time Clock Interrupt Handler //* This routine runs every second //****************************************************************** void interrupt TIMERS(void) { if((TMR1IF) && (TMR1IE)) { TMR1H = 0x80; TMR1IF = 0; if(60 == ++secs) { secs = 0; ++mins; } if(60 == mins) { mins = 0; ++hours; } if(24 == hours) { hours = 0; ++days; } ++secs_timer; //this value increments every second } } //****************************************************************** //* Motor Functions //****************************************************************** void BRAKE (char motor) { switch(motor) { case 1: CCP1CON &= 0b11110000; //disable PWM LATC2 = 1; LATB0 = 1; LATB1 = 1; break; case 2: CCP2CON &= 0b11110000; //disable PWM LATB3 = 1; LATB2 = 1; LATB4 = 1; break; } } void REV (char motor) { switch(motor) { case 1: CCP1CON |= 0b00001111; //enable PWM LATB0 = 0; LATB1 = 1; break; case 2: CCP2CON |= 0b00001111; //enable PWM LATB2 = 0; LATB4 = 1; break; } } void FWD (char motor) { switch(motor) { case 1: CCP1CON |= 0b00001111; //enable PWM LATB0 = 1; LATB1 = 0; break; case 2: CCP2CON |= 0b00001111; //enable PWM LATB2 = 1; LATB4 = 0; break; } } void speed(char motor) { unsigned char x; x = 200; while(x--); switch(motor) { case 1: CHS0 = 0; //select ADC channel 0 GODONE = 1; //start the 10-bit conversion while(GODONE); //wait for conversion to complete CCP1CON &= 0b00001111; //clear bits 4 and 5 CCP1CON |= ADRESL >> 2; //load bits 4 and 5 from conversion value CCPR1L = ADRESH; //load upper 8 bits of conversion value break; case 2: CHS0 = 1; GODONE = 1; while(GODONE); CCP2CON &= 0b00001111; CCP2CON |= ADRESL >> 2; CCPR2L = ADRESH; break; } } void motors_init(void) { TRISB = 0b00000000; TRISC = 0b00000011; } //****************************************************************** //* Application Code //****************************************************************** void main(void) { unsigned int x; motors_init(); //****************************************************************** //* CONFIGURE ADC //****************************************************************** ADCON0 = 0b01000001; //ADC ON ADCON1 = 0b01000000; //all analog - Fosc/32 //****************************************************************** //* CONFIGURE AND START TIMER1 //* SET TO OVERFLOW EVERY 1S //****************************************************************** TMR1ON = 0; //turn TMR1 OFF TMR1H = 0x80; //set TMR1 to overflow every second TMR1L = 0x00; T1CON = 0b00001110; //1:1 prescale-enable TMR1 osc-TMR1 on TMR1IE = 1; //enable TMR1 interrupt days = 0x00; //initialze time of day counters hours = 0x00; mins = 0x00; secs = 0x00; TMR1ON = 1; //turn TMR1 on //****************************************************************** //* CONFIGURE AND START TIMER2 //****************************************************************** T2CON = 0x7A; //set prescaler and postscaler to 16 PR2 = 0xFF; //set pwm period to maximum TMR2ON = 1; //turn on TMR2 //****************************************************************** //* ENABLE GLOBAL INTERRUPTS //****************************************************************** PEIE = 1; //enable all unmasked peripheral interrupts GIE = 1; //enable all unmasked interrupts //****************************************************************** //* INITIALIZE PWM DUTY CYCLES //****************************************************************** CCPR1L = 0x80; //set pwm duty cycle for 50% CCPR2L = 0x80; //****************************************************************** //* APPLICATION AREA //****************************************************************** while(1) { FWD(1); x = secs_timer; while(secs_timer < x+2); BRAKE(1); x = secs_timer; while(secs_timer < x+2); REV(1); x = secs_timer; while(secs_timer < x+2); } }