// Program 5832_1.C (CCS PCM - PIC16F84) // // Illustrates how to interface with four 7-segment LEDs using an // Allegro UCN5832A 32 bit shift register. Note that this is a sink // device and inverts the data in the shift register. // // Note that we sell the UCN5832A, common anode 7-segment LED displays // and 330 Ohm resistors. If you want a drawing showing the connection // of the 5832 to the four 7-seg LEDs, please ask. // // Program assumes the least digit first and the pattern is shifted // out least significant bit first. Decimal point is on most significant // bit. // // This concept might be used with similar Allegro devices such as the // 5841 (8-bit, sink) and 5818 (32-bit source). // // PIC16F84 UCN5832 // // RB.3 -----------------------> DAT // RB.2 -----------------------> CLK // RB.1 -----------------------> STB // RB.0 -----------------------> OE // // Routine displays the characters '0' - 'F' on least significant digit. // Other digits are blanked. The message "HELP is displayed" and flashed // a number of times. // // Illustrates how to display four decimal digits with leading // zero suppression, sign plus three decimal digits and four hexadecimal // digits. // // Illustrates how to insert a decimal point. // // Copyright, Peter H. Anderson, Baltimore, MD, Apr, '99 #case #include <16F84.h> #include <defs_f84.h> #define MINUS 0x01 // display a minus sign #define BLANK 0x00 // blanks LED #define OE rb0 #define STB rb1 #define CLK rb2 #define DAT rb3 void convert_to_dec_patt_unsigned(long val, int *patts); void convert_to_dec_patt_signed(signed long val, int *patts); void convert_to_hex_patt(long val, int *patts); void display(int *patts); long pow_10(int n); void out_8(int patt); // delay routines void delay_ms(long t); void delay_10us(int t); // note that the patts are declared globally as they can not be passed // by reference. That is, pointers to const arrays are not permitted. // a table used in deriving these patterns appears at the end of this // program. int const hex_digit_patts[16]= // 0 1 2 3 4 5 6 7 {0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, // 8 9 A B C D E F 0x7f, 0x7b, 0x77, 0x1f, 0x4e, 0x3d, 0x4f, 0x47}; int const help_patts[4] = {0x37, 0x4f, 0x0f, 0x67}; // H E L P #define ARRAY_TECNIQUE // see note at function pow_10 void main(void) { int disp_patts[4], n; signed long val; TRISB = 0xf0; // lower nibble are outputs STB = 0; CLK = 0; OE = 0; // set STB to 0, CLK to 0 and Output disabled // display 0 - F on least sig 7-seq. Others are balnked. disp_patts[1] = BLANK; //BLANK; disp_patts[2] = BLANK; disp_patts[3] = BLANK;// most sig digit for (n=0; n<0x10; n++) { disp_patts[0] = hex_digit_patts[n]; // least sig digit display(disp_patts); OE = 1; // output enable delay_ms(1000); } // display "HELP" for (n=0; n<4; n++) { disp_patts[n] = help_patts[3-n]; // output least sig digit first } display(disp_patts); for (n=0; n<10; n++) // flash the message on and off ten times { OE = 0; // turn it off delay_ms(100); OE = 1; // turn it on delay_ms(100); } // display 207 in decimal format with leading zero suppression val = 207; convert_to_dec_patt_unsigned(val, disp_patts); display(disp_patts); delay_ms(5000); // display as signed plus 3 digits with leading zero suppression val = -7; convert_to_dec_patt_signed(val, disp_patts); display(disp_patts); delay_ms(5000); // display a value in hexadecimal format, no leading zero suppression val = 0x3f3c; convert_to_hex_patt(val, disp_patts); display(disp_patts); delay_ms(5000); // display 98.6 val = 986; convert_to_dec_patt_unsigned(val, disp_patts); // ele 3 is blank, ele 2 is 9, ele 1 is 8, ele 0 is 6 disp_patts[0] = disp_patts[0] | 0x80; // left hand dec point display(disp_patts); delay_ms(5000); } convert_to_dec_patt_unsigned(long val, int *patts) // converts val to four digits and place corresponding hex digit patterns // in patt[] { int n, suppress_zero = TRUE; long x; for (n=0; n<4; n++) { x = pow_10(3-n); // calculate 1000, 100, 10, 1 if ((val/x == 0) && (suppress_zero) && (n!=3)) { patts[3-n] = BLANK; // leading zero suppression } else { suppress_zero = FALSE; patts[3-n] = hex_digit_patts[val/x]; } val = val%x; } } convert_to_dec_patt_signed(signed long val, int *patts) // patt[3] is for the sign, either MINUS or BLANK // hex patterns for the three digits are paced in elements 2, 1 and 0 { int n, suppress_zero=TRUE; // could have used a short for suppress_zero long x; if (val < 0) { patts[3] = MINUS; } else { patts[3] = BLANK; } val = -val; // convert to a positive number for (n=0; n<3; n--) { x = pow_10(2-n); // compute 100, 10, 1 if ((val/x == 0) && (suppress_zero) && (n!=2)) { patts[2-n] = BLANK; } else { suppress_zero = FALSE; patts[2-n] = hex_digit_patts[val/x]; } val = val%x; } } void convert_to_hex_patt(int val, int *patts) // converts to four nibbles and places corresponding hex patterns // in patts[] { int n; for(n=0; n<4; n++) { patts[n] = hex_digit_patts[val & 0x0f]; // patt[0] is least sig digit val = val >> 4; // next nibble } } long pow_10(int n) // Note the multiply technique was done simply to see if it could be done. // The array technique which uses an array is far more efficient. #ifdef ARRAY_TECHNIQUE { long const v[4] = {1, 10, 100, 1000}; return v[n] } #else { long v=1; while(n) { v = v * 10; --n; } return(v); } #endif void display(int *patts) // outputs the 4 values in patts[], beginning with patts[0]. { int n; STB = 0; // be sure latch is isolated from shift register CLK = 0; for (n=0; n<4; n++) { out_8(patts[n]); } STB = 1; // transfer shift register to latch STB = 0; } void out_8(int patt) // shifts out an 8-bit pattern, least sign bit first { int n; for (n=0; n<8; n++) { DAT = (patt>>7)&0x01; CLK = 1; CLK = 0; patt = patt << 1; } } // delay routines void delay_10us(int t) { #asm BCF STATUS, RP0 DELAY_10US_1: CLRWDT NOP NOP NOP NOP NOP NOP DECFSZ t, F GOTO DELAY_10US_1 #endasm } void delay_ms(long t) // delays t millisecs { do { delay_10us(100); } while(--t); } // The following was used in developing the values for hex_digit_patts[] // and help_patts[] #ifdef XXX P7 P6 P5 P4 P3 P2 P1 P0 Char a b c d e f g HEX 0 1 1 1 1 1 1 0 $7E 1 0 1 1 0 0 0 0 $30 2 1 1 0 1 1 0 1 $6D 3 1 1 1 1 0 0 1 $7F 4 0 1 1 0 0 1 1 $33 5 1 0 1 1 0 1 1 $5B 6 1 0 1 1 1 1 1 $5f 7 1 1 1 0 0 0 0 $70 8 1 1 1 1 1 1 1 $7F 9 1 1 1 1 0 1 1 $7B A 1 1 1 0 1 1 1 $77 B 0 0 1 1 1 1 1 $1F C 1 0 0 1 1 1 0 $4E D 0 1 1 1 1 0 1 $3D E 1 0 0 1 1 1 1 $4F F 1 0 0 0 1 1 1 $47 H 0 1 1 0 1 1 1 $37 E 1 0 0 1 1 1 1 $4F L 0 0 0 1 1 1 1 $0F P 1 1 0 0 1 1 1 $67 - 0 0 0 0 0 0 1 $01 blank 0 0 0 0 0 0 0 $00 #endif