// --- Lab6. ------------------- // // This program impliments PWM controller for the speed of // a DC servo motor. // // I/O Connections: // RC2 = PWM output to the motor // RA0 = analog input to set the speed // RC6,RC7 = SCI input to control the speed via a keybaord // // Debug Lights // RC0 = pulses every time there a byte is read in // RC1 = pulses every INT interrupt (1/1000 rotation) // RC3 = pulses every 10ms // RC4 = pulses every 100ms (sampling rate) // RC5 = heart beat. Pulses each loop through the main routine // // Several interrupts are used // Timer2: every 10ms for timing // Capture1: used for PWM output // RCI: used for receiving serial data (19200 baud) // INT: measure the speed by counting edges / 100ms // // Revision History // April 17, 2005: Intial version - JSG // Total ROM used 850 words (41.5%) // Total RAM used 64 bytes (36.4%) // Global Variables unsigned int Counter1; // total pulses counted so far unsigned int Counter2; // # of TMR2 interrupts seen unsigned int SPEED; // # egdes / 100ms (100*rev/sec) unsigned int REF; // desired speed (100*rev/sec) bank1 unsigned char MSG[10]; // sci message coming in bank1 unsigned char MSG_LENGTH; // length of message bank1 unsigned char TEMP; // temp variable bank1 unsigned char N; // temp length of message bank1 unsigned char FLAG; // 1 means carriage return seen const unsigned char MSG0[10] = "SCI Data: "; const unsigned char MSG1[10] = "Ref: "; const unsigned char MSG2[10] = "Capture1: "; const unsigned char MSG3[10] = "Speed: "; // Subroutine Declarations #include static volatile unsigned int Timer1 @ 0x0E; static volatile unsigned int Capture1 @ 0x15; #include "lcd_20x4.h" #include "function.h" #include "a2d.h" // Subroutines #include "lcd_20x4.c" #include "function.c" #include "bootloader.c" #include "a2d.c" // Interrupt service routine void interrupt IntServe(void) @ 0x10 { if (RCIF) { RC0 = !RC0; // debug info for RCIF interrupts TEMP = RCREG; while(!TRMT); TXREG = TEMP; MSG[N] = TEMP; N += 1; if (N > 9) N = 9; if (TEMP == 13) { FLAG = 1; MSG_LENGTH = N; N = 0; } RCIF = 0; } if (INTF) { RC1 = !RC1; // debug I/O for INT interrupts Counter1 += 1; INTEDG = !INTEDG; INTF = 0; } if (TMR2IF) { RC3 = !RC3; // debug I/O for TMR2 interrupts Counter2 += 1; if (Counter2 > 9) { // every 100ms... SPEED = Counter1; Counter1 = 0; Counter2 = 0; RC4 = !RC4; } TMR2IF = 0; } if (TMR1IF) { RC2 = 1; TMR1IF = 0; } if (CCP1IF) { RC2 = 0; CCP1IF = 0; } } void SCI_Out(unsigned int Data) { unsigned char A[5]; unsigned char i; for (i=0; i<5; i++) { A[i] = Data % 10; Data = Data / 10; } while(!TRMT); TXREG = ascii(A[4]); while(!TRMT); TXREG = ascii(A[3]); while(!TRMT); TXREG = ascii(A[2]); while(!TRMT); TXREG = ascii(A[1]); while(!TRMT); TXREG = ascii(A[0]); while(!TRMT); TXREG = 32; } void LCD_Out(unsigned int DATA) { unsigned char A[5], i; for (i=0; i<5; i++) { A[i] = DATA % 10; DATA = DATA / 10; } lcd_write(ascii(A[4])); lcd_write(ascii(A[3])); lcd_write(ascii(A[2])); lcd_write(ascii(A[1])); lcd_write(ascii(A[0])); lcd_write(' '); } // Main Routine void main(void) { unsigned char i; unsigned int A2D; unsigned char A[5]; TRISB = 0x00; TRISC = 0x00; TRISA = 0x00; ADCON1 = 6; PORTC = 0; PORTB = 0; PORTA = 0; FLAG = 0; Wait_ms(100); lcd_init(); // initialize the LCD Wait_ms(100); lcd_move(0,0); for (i=0; i<10; i++) lcd_write(MSG0[i]); lcd_move(1,0); for (i=0; i<10; i++) lcd_write(MSG1[i]); lcd_move(2,0); for (i=0; i<10; i++) lcd_write(MSG2[i]); lcd_move(3,0); for (i=0; i<10; i++) lcd_write(MSG3[i]); // Initialize Serial Port TRISC = TRISC | 0xC0; TXSTA = 0x22; // 8-bit no parity RCSTA = 0x90; // continuous receive TXIE = 0; // no interrupt on xmit RCIE = 1; // no interrupt on receive BRGH = 1; SPBRG = 64; // 19200 baud @ 20MHz = 64 SYNC = 0; // initialize INT interrupts INTE = 1; INTEDG = 1; // initialize Timer2 interrupts for 10ms T2CON = 0x77; PR2 = 207; TMR2IE = 1; PEIE = 1; // Initialize Timer1. When Timer1 = 0, set RC2. T1CON = 0; TMR1CS = 0; TMR1ON = 1; TMR1IE = 1; // Initialize Timer1 Capture. When Timer1 = Capture1, clear RC2 CCP1CON = 0x0A; CCP1IE = 1; TRISC2 = 0; A2D_Init(); GIE = 1; REF = 0; Capture1 = 100; do { lcd_move(0,10); for (i=0; i<10; i++) lcd_write(MSG[i]); REF = A2D_Read(0); Capture1 += (REF - SPEED); lcd_move(1,10); LCD_Out(REF); SCI_Out(REF); lcd_move(2,10); LCD_Out(Capture1); SCI_Out(Capture1); lcd_move(3,10); LCD_Out(SPEED); SCI_Out(SPEED); while(!TRMT); TXREG = 13; // carriage return while(!TRMT); TXREG = 10; // line feed RC5 = !RC5; // heart beat } while (1>0); }