I had a use for the basic kit and wondered how hard it would be to get my old PIC stuff working again, so I bought a couple on eBay. It was a surprisingly pleasant experience, and I was astonished to discover that MPLAB8 still works with my ancient PICSTART PLUS programmer!
The free XC8 compiler associated with MPLABX supports the 16F628A, so here is a simple XC8 program that simply counts up and displays a 16 bit number.
The code leaves two pins (RA5 and RA4) free for I/O, which plenty to allow the module to be used as a dedicated 5 digit, 7 segment display. I borrowed the definitions in the frequency counter assembly code to drive the segments.
Demo program:
#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h> /* For true/false definition */
// display data buffer
unsigned char digits[5]={0};
// digit drive table (left=0 to right=4)
unsigned char digit_drive[5]={0x07, 0x0B, 0x0E,0x0D,0x0F};
// digit drive table (right=0 to left=4)
// unsigned char digit_drive[5]={0x0F,0x0D,0x0E,0x0B,0x07};
// bitmask for segment A , etc ..
#define _A 0x40
#define _B 0x80
#define _C 0x04
#define _D 0x01
#define _E 0x08
#define _F 0x10
#define _G 0x20
#define _DP 0x02
#define BLANK_PATTERN 0
// blank display pattern (7-segment code)
//translate to seven-segments
unsigned char symb[] =
{
(_A+_B+_C+_D+_E+_F ), // ABCDEF. = '0' ( # 0 )
( _B+_C ), // .BC.... = '1' ( # 1 )
(_A+_B +_D+_E +_G), // AB.DE.G = '2' ( # 2 )
(_A+_B+_C+_D +_G), // ABCD..G = '3' ( # 3 )
( _B+_C +_F+_G), // .BC..FG = '4' ( # 4 )
(_A +_C+_D +_F+_G), // A.CD.FG = '5' ( # 5 )
(_A +_C+_D+_E+_F+_G), // A.CDEFG = '6' ( # 6 )
(_A+_B+_C ), // ABC.... = '7' ( # 7 )
(_A+_B+_C+_D+_E+_F+_G), // ABCDEFG = '8' ( # 8 )
(_A+_B+_C+_D +_F+_G), // ABCD.FG = '9' ( # 9 )
(_A+_B+_C +_E+_F+_G), // ABC.EFG = 'A' ( # 10 )
( _C+_D+_E+_F+_G), // ..CDEFG = 'b' ( # 11 )
( _D+_E +_G), // ...DE.G = 'c' ( # 12 )
( _B+_C+_D+_E +_G), // .BCDE.G = 'd' ( # 13 )
(_A +_D+_E+_F+_G), // A..DEFG = 'E' ( # 14 )
(_A +_E+_F+_G), // A...EFG = 'F' ( # 15 )
(_A +_C+_D+_E+_F ), // A.CDEF. = 'G' ( # 16 )
( _B+_C +_E+_F+_G), // .BC.EFG = 'H' ( # 17 )
( _E ), // ....E.. = 'i' ( # 18 )
(BLANK_PATTERN ), // ....... = ' ' ( # 19 )
(0xFF ), // all segments on ( # 20 )
(_A+_B +_E+_F+_G), // AB..EFG = 'P' ( # 21 )
( _E +_G), // ....E.G = 'r' ( # 22 )
( _C+_D+_E +_G), // ..CDE.G = 'o' ( # 23 )
(_A+_B+_C +_F+_G), // ABC..FG = 'Q' ( # 24 )
( _C+_D+_E ), // ..CDE.. = 'u' ( # 25 )
( _D+_E+_F+_G), // ...DEFG = 't' ( # 26 )
(_A +_C+_D +_F+_G), // A.CD.FG = 'S' ( # 27 )
(_A+_B +_D+_E +_G), // AB.DE.G = 'Z' ( # 28 )
( _E+_F ), // ....EF. = 'I' ( # 29 )
( _B+_C+_D ), // .BCD.. = 'J' ( # 30 )
( _D+_E+_F+_G), // ...DEFG = 'k' ( # 31 )
( _D+_E+_F ), // ...DEF. = 'L' ( # 32 )
(_A+_B+_C +_E+_F ), // ABC.EF. = 'N' ( # 33 )
( _C+_D+_E+_F ), // ..CDEF. = 'V' ( # 34 )
( _D +_G), // ...D..G = '=' ( # 35 )
};
/******************************************************************************/
/* Main Program */
/******************************************************************************/
#define _XTAL_FREQ 20000000
#include <xc.h>
unsigned int counter=0;
// separate out the digits of "counter" into display buffer
void update_display(void) {
digits[4] = counter%10;
digits[3] = (counter/10)%10;
digits[2] = (counter/100)%10;
digits[1] = (counter/1000)%10;
digits[0] = counter/10000;
}
void main(void) {
TRISB = 0; //RB as Output
PORTB = 2; //turn on DP
TRISA = 0; //RA as Output
PORTA = 0x0F; //turn on 5th (rightmost) digit
__delay_ms(1000); //test display/DP
unsigned char i,j,k;
// display test, all segments
PORTB = 0xFF; //all segments on
for (j=0; j<5; j++) {
PORTA = digit_drive[j];
__delay_ms(400);
}
PORTB = 0;
while(1) //count up and display result
{
update_display();
for (k=0; k<50; k++) {
for (j=0; j<5; j++) {
PORTA = digit_drive[j];
PORTB = symb[digits[j]];
__delay_ms(1);
}
}
counter++;
}
}
Note: exposure caught the display while the last digit was changing.