#define COMMON_CATHODE
#define BUFFERSIZE 56
//max. 54 chars (and 2 gap space) for scrolling message
char buffer[BUFFERSIZE]; //display buffer: 8 chars + 2 spaces(gap for scrolling)
char FirstPos, NextPos, CharCnt, ScrollTime;
char mode, scrollcnt, charnum, linenum, pattern;
char *ptr, *startptr, *endptr;
#include "bitmap.h"
//pos/speed switch inputs: PORTB<6:3> ;RB2 = SW_1 , sum value *8 !!
#define SPEEDMAX 10
//Mode switch input: PORTA.4 ;RA4 (0: scrolling, 1: static)
#define STATICMODE Porta.F4
//checked at start only
//Line decoder outputs: PORTA<2:0> ;RA0 = LSB
#define DisableLines PORTA = 0b0111 //all 1, decoder outputs are active low
//Clock output: PORTB.0 ;RB0
//Data output: PORTB.7 ;RB7
//Store output: PORTA.3 (RA3), positive clock for shiftregs output storage
#define StorePulse PORTA.F3 = 1; PORTA.F3 = 0
//setup for positive pulses
#define PinInits PORTA.F3 = 0; PORTB.F0 = 0; PORTB.F7 = 0
/*
ClockoutPatternBit(X): Data = pattern.FX followed by an positive clock pulse
I am using here (too) a little asm, this is much shorter as the pure C
*/
#define ClockoutPatternBit(X) asm { btfsc _pattern, X }; \
asm { bsf PORTB, 7 }; \
PORTB.F0 = 1; PORTB.F0 = 0; \
PORTB.F7 = 0
//RX input: PORTB.1 ;RB1
//this is used in IT
void DisplayClear(void) {
DisableLines;
CharCnt = BUFFERSIZE; //init the display buffer with zeroes
do
buffer[--CharCnt] = 0;
while ( CharCnt );
--CharCnt; //= 255, the first received char increments it to zero
ptr = startptr = buffer;
}
void interrupt() {
if ( RCREG < 0x20 ) {
if ( RCREG == 0x0D )
DisplayClear();
}
else if ( ++CharCnt < NextPos && CharCnt >= Firstpos ) {
if ( RCREG > 0x7F )
RCREG = '?';
*((char *)(buffer + (short)(CharCnt-FirstPos))) = RCREG - 0x20;
}
}
void GetPatternAndOut() {
#ifdef COMMON_CATHODE
pattern = ~(bitmap[ (*ptr << 3)+ linenum ]);
#else
pattern = bitmap[ (*ptr << 3)+ linenum ];
#endif
ClockoutPatternBit(4);
ClockoutPatternBit(3);
ClockoutPatternBit(2);
ClockoutPatternBit(1);
ClockoutPatternBit(0);
}
void DisplayLine(void) {
DisableLines;
StorePulse;
PORTA = linenum;
Delay_us(400);
}
void HW_Init(void) {
CMCON = 0b00000111; // switch off comparators
TRISA = 0b10110000; // 7, 5 and 4 PORTA pins are inputs
// Initialize USART module for receive (rx) only:
TXSTA.BRGH = 1; SPBRG = 25; //9600 Bd at 4 M clock
RCSTA = 0b10010000; // 8 bit, no parity
asm {MOVF RCREG, 0}; asm {MOVF RCREG, 0}; //empty rx fifo in asm (short)
TRISB = 0b01111110; // only PORTB.0 and PORTB.7 are outputs
}
void main(void) {
HW_Init();
PinInits;
DisplayClear();
//if ( !( mode = (char) STATICMODE ) ) { // 0 = scrolling mode
FirstPos = 0;
NextPos = BUFFERSIZE;
scrollcnt = 0;
ScrollTime = SPEEDMAX;
//}
// else { //static mode
// NextPos = ( FirstPos = SWITCHVALUE8 ) + 8;
// }
startptr = buffer;
endptr = buffer + BUFFERSIZE;
INTCON = 0xC0; PIE1 = 0x20; //enable global ITs and RX it
for ( ; ; ) { // main loop forever
//scrolling mode (mode = 0) ?
if ( !mode && ++scrollcnt == ScrollTime ) {
scrollcnt = 0;
ScrollTime = SPEEDMAX; //check the speed sw again
//for a gap
INTCON = 0; //disable IT
if ( CharCnt < (BUFFERSIZE - 3) && startptr < ( buffer + CharCnt + 2 ) )
endptr = buffer + CharCnt + 3;
INTCON = 0xC0; //enable IT
if ( ++startptr == endptr )
startptr = buffer;
DisableLines;
}
linenum = 7;
do {
--linenum;
ptr = startptr;
charnum = 8;
do {
GetPatternAndOut();
if (++ptr == endptr )
ptr = buffer;
} while ( --charnum );
DisplayLine();
} while ( linenum );
} // end loop
}