/* //////////////// CharliePlexed Emergency lights v1 : Very basic implementation Matt Casey : 23 Feb 2008 matt@catmacey.com 8 Charlieplexed LEDs on Portb[4-7] Red in one direction : Blue in the other. Could use 12 LEDs if I made a bigger PCB //////////////// */ /* //////////////// Todo: * Use PWM to control output intensity of individual LEDs. * Create patterns to simulate rotation of lightsources by varying intensity of neighbouring LEDS * Simulate inertia of mechanical rotating systems * Simulate power up/power down of real bulbs using pwm * Use Interrupt to drive display : ISR is defined but not used right now //////////////// */ #include #include #include #include #include #include #include //PortA //outputs #define led0 PORTAbits.RA0 //LED ind to show system is running #define btn0 PORTAbits.RA5 //Port B //inputs //outputs #define cp0 PORTBbits.RB4 //Charliplex 0 #define cp1 PORTBbits.RB5 //Charliplex 1 #define cp2 PORTBbits.RB6 //Charliplex 2 #define cp3 PORTBbits.RB7 //Charliplex 3 //Port C #define TX PORTCbits.RC6 #define RX PORTCbits.RC7 #define TRISB_DEF 0b11110000 //setup defs for charlieplexing b7-4 are port state : b3-0 are tris rom char charlieBits[] = { 0b10000011 , 0b01001001 , 0b00101100 , 0b00010110 , 0b01000011 , 0b00101001 , 0b00011100 , 0b10000110 }; //func prototypes void boot_up( void ); void timer_isr (void); void ledOn (unsigned char ledNum); void ledOff (); #pragma code low_vector=0x18 void low_interrupt (void){ _asm GOTO timer_isr _endasm } #pragma code #pragma interruptlow timer_isr void timer_isr (void){ //int signed char rtn; unsigned char tmp; if(INTCONbits.TMR0IF){ //Timer 0 int INTCONbits.TMR0IF = 0; //reset timer 0 } }//func void main(){ unsigned char ctr = 0; //gp counter unsigned char tmp; unsigned char btn = 0; boot_up(); //inti the peripherals Delay1KTCYx(10); INTCONbits.GIE = 0; //halt ints PORTB = 0b10101010; while(1){ btn = 0; //Turn on LED ledOn(ctr); fprintf(_H_USART, "\r\n%.1u : %.8b : %.8b ",ctr, PORTB, TRISB); while(btn < 20){ //wait here for a button press of at least 20K ticks Delay1KTCYx(1); if(btn0 == 0) btn++; else btn = 0; } ctr++; if(ctr > 7) ctr = 0; led0 = ~led0; Delay10KTCYx(30); }//end while } /* Sets all LEDs off by setting chalie pins to high impedance */ void ledOff (){ //reset all charlie pins to high impedance (input) TRISB = TRISB_DEF; } /* Sets a given led on using charlieplexing */ void ledOn (unsigned char ledNum){ //reset all charlie pins to high impedance (input) unsigned char tmp; TRISB = TRISB_DEF; //set output status : use masking to retain b3-0 tmp = (PORTB & 0b00001111) | (charlieBits[ledNum] & 0b11110000); PORTB = tmp; //set tris : Use mask to retain b3-0 tmp = (TRISB & 0b00001111) | ((charlieBits[ledNum] << 4) & 0b11110000); TRISB = tmp; } void boot_up(void){ //Setup Ports CMCON = 0b00000111; //Turn off comparator on RA port ] LATA = 0b00000000; PORTB = 0b00000000; LATC = 0b00000000; TRISA = 0b00100000; // 0= out, 1 = in TRISB = 0b11111111; // 0= out, 1 = in TRISC = 0b00011000; // 0= out, 1 = in ADCON1 = 0b00001111; // set portA bits0-3 to digital IO //Open the USART configured as 8N1, 115200 baud, in polled mode OpenUSART (USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 10); //setup Timer0 : Use for GPIO output OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_4); //Disable ints for the mo INTCONbits.GIE = 0; //Stop ints Delay10KTCYx(10);//wait for stable putrsUSART ((const far rom char *)"\r\n\r\n\r\n\r\n////////////////\r\nBootup completed\r\n"); }