Tag Archives: software

The incident with the microwave

I found a beat up microwave in the trash the other day. Looks like the neighborhood kids had fun smashing it up. I took the opportunity to rip the display module from it.

In the FPGA projects I’m working on, it would be useful to have a simple hex display and some buttons for input, so I built one. It takes bytes in from a serial connection and displays them on a 4 segment LED module. Below is a picture of the assembled device.

serialhexAnd here is the schematic:

serhexled

Here is the device in action:

And here is the source code:

// This program reads bytes from an RS232 port and displays them in
// hex on a 4 segment LED module. It relies on the UART library that is
// included with the mikroC compiler. This program targets a PIC16f917.
// Source released as Public Domain
// 2013 Brian Miller

// segment commons
const segz = 0b01111111;
const segw = 0b10111111;
const segy = 0b11011111;
const segx = 0b11101111;

// segment pieces
const pa = 0b10000000;
const pb = 0b00000010;
const pc = 0b01000000;
const pd = 0b00000001;
const pe = 0b00000100;
const pf = 0b00100000;
const pg = 0b00001000;

// glyph definitons
const d0 = pa + pb + pc + pe + pf + pg ;
const d1 = pc + pf ;
const d2 = pa + pc + pd+ pe + pg ;
const d3 = pa + pc + pd + pf + pg ;
const d4 = pb + pc + pd + pf ;
const d5 = pa + pb + pd + pf + pg ;
const d6 = pa + pb + pd + pe + pf + pg ;
const d7 = pa + pb + pc + pf ;
const d8 = pa + pb + pc + pd + pe + pf + pg ;
const d9 = pa + pb + pc + pd + pf ;
const da = pa + pb + pc + +pd + pe + pf ;
const db = pb + pd + pe + pf + pg ;
const ddc = pa + pb + pe + pg ;
const dd = pc + pd + pe + pf + pg ;
const de = pa + pb + pd + pe + pg ;
const df = pa + pb + pd + pe ;

// returns the glyph code for the specified nybble in the word
unsigned char retchar ( unsigned int a, unsigned int pos){
         unsigned int tst ;
         switch (pos){
                case 0 :
                     tst = ( a << 12 ) >> 12 ;
                     break;
                case 1:
                     tst = ( a << 8 ) >> 12 ;
                     break;
                case 2:
                     tst = ( a << 4 ) >> 12 ;
                     break;
                case 3:
                     tst = a >> 12 ;
                     break;
         }
         switch ( tst){
                case 0 : return d0 ;
                case 1 : return d1 ;
                case 2 : return d2 ;
                case 3 : return d3;
                case 4 : return d4 ;
                case 5 : return d5 ;
                case 6 : return d6 ;
                case 7 : return d7 ;
                case 8 : return d8 ;
                case 9 : return d9 ;
                case 10 : return da ;
                case 11 : return db ;
                case 12 : return ddc ;
                case 13 : return dd ;
                case 14 : return de ;
                case 15 : return df ;
         }
}

void main() {
     // serial input
     unsigned int inDat;
     
     // individual display digits
     unsigned char s0, s1, s2, s3;
     
     // kp limits button sampling, i selects the digit to be refreshed
     unsigned char i;
     unsigned char kp;
     
     ANSEL = 0 ; // AN pins as digital
     CMCON0 = 0 ; // turn off comparators

     // Segment port
     TRISA = 0 ;
     // Commons port
     TRISB = 0 ;
     // Button inputs
     TRISD = 0xFF;
     
     // lib doc suggests waiting 100ms to allow serial port to settle
     UART1_Init(19200); // 19200 baud
     Delay_ms(100);
     
     // set all digits to 0 on startup
     s0 = d0;
     s1 = d0;
     s2 = d0;
     s3 = d0;
     
     inDat=0;
     i = 0 ;
     kp = 0;

     for (;;){
         // shift in a byte if there is one waiting
         if (UART1_Data_Ready()){
            inDat = inDat << 8 ;
            inDat = inDat + UART1_Read();
            s0 = retchar (inDat, 0);
            s1 = retchar (inDat, 1);
            s2 = retchar (inDat, 2);
            s3 = retchar (inDat, 3);
         }
         // if one or more buttons is pressed and sample limiter is 0
         // then write the button state to the serial port
         if ( kp++ == 0 && PORTD != 0 ) {
            UART1_Write(PORTD);
         }
         // we only update one segment per iteration so that each segment
         // stays lit an equal ammount of time.
         switch (i++){
                case 0:
                     PORTB = 0xFF;
                     PORTA = s0 ;
                     PORTB = segx;
                     break;
                case 1:
                     PORTB = 0xFF;
                     PORTA = s1 ;
                     PORTB = segy;
                     break;
                case 2:
                     PORTB = 0xFF;
                     PORTA = s2;
                     PORTB = segw;
                     break;
                case 3:
                     i=0;
                     PORTB = 0xFF;
                     PORTA = s3 ;
                     PORTB = segz;
                     break;
         }
     }
}