/********************************************************************
* *
* Project: LED 4-Digit 595 *
* Source: LED_4-Digit_595.c *
* Author: Mike McLaren, K8LH *
* (C)2010: Micro Application Consultants *
* Date: 18-Jul-10 *
* Revised: 26-Dec-10, 6-bit gamma corrected brightness control *
* *
* 16F88 + TPIC6C595 + 4-Digit 7-Seg CA Display Demo (5 pin buss) *
* *
* *
* IDE: MPLAB 8.56 (tabs = 4) *
* Lang: SourceBoost BoostC v7.01, Lite/Free version *
* *
********************************************************************/
#include <system.h>
#pragma DATA _CONFIG1, _CCP1_RB0&_LVP_OFF&_MCLR_OFF&_WDT_OFF&_INTRC_IO
#pragma DATA _CONFIG2, _IESO_OFF&_FCMEN_OFF
#pragma CLOCK_FREQ 8000000 // 8 MHz INTOSC
//--< function prototypes >------------------------------------------
//--< typedef and defines >------------------------------------------
typedef unsigned char u08;
typedef unsigned int u16;
#define r08 const rom unsigned char
#define clk portb.1 // the RB1 pin
#define dat portb.2 // the RB2 pin
//--< variables >----------------------------------------------------
u08 colsel = 2; // column select bit mask
u08 colnbr = 0; // colnbr, 0..3
u08 display[] = { 0,0,0,0 }; // display data, 0..9
u08 swnew = 0; // switch sample
u08 swold = 0; // switch state latch
u08 flags = 0; // switch flag bits
u08 work = 0; // isr work variable
r08 segdata[] = { 0b00111111, // "0" -|-|F|E|D|C|B|A
0b00000110, // "1" -|-|-|-|-|C|B|-
0b01011011, // "2" -|G|-|E|D|-|B|A
0b01001111, // "3" -|G|-|-|D|C|B|A
0b01100110, // "4" -|G|F|-|-|C|B|-
0b01101101, // "5" -|G|F|-|D|C|-|A
0b01111101, // "6" -|G|F|E|D|C|-|A
0b00000111, // "7" -|-|-|-|-|C|B|A
0b01111111, // "8" -|G|F|E|D|C|B|A
0b01101111, // "9" -|G|F|-|D|C|B|A
0b00000000, // " " -|-|-|-|-|-|-|-
0b01000000 }; // "-" -|G|-|-|-|-|-|-
r08 gamma[] = { 250,249,248,248,248,247,247,247,246,246,
246,245,245,244,243,243,242,241,240,239,
239,238,236,235,234,233,231,230,228,226,
224,222,220,218,215,213,210,207,204,200,
197,193,189,185,180,175,170,164,158,152,
145,138,131,123,114,105, 95, 85, 74, 63,
51, 38, 25, 10 };
//--< functions >----------------------------------------------------
void brightness(u08 level) // gamma brightness level, 0..63
{ ccpr1l = gamma[level]; // pwm duty cycle, 10..250
} //
//--< main >---------------------------------------------------------
void main()
{
ansel = 0; // a2d off, digital i/o
osccon = 0b01110000; // set INTOSC to 8 MHz
while(!osccon.IOFS); // wait 'til oscillator stable
trisb = 0b11100000; // set RB4..RB0 to outputs
trisa = 0b00000000; // set all pins to outputs
portb = 0b00000000; // set all output latches to '0'
porta = 0b00000000; // set all output latches to '0'
// setup PWM for a 2 msec period (8 MHz Clock) for a 1/4th or 25%
// display duty cycle and a 125 Hz (8 msec) display refresh rate
ccp1con = 0b00001100; // '00------' unimplemented bits
// '--00----' CCP1X:CCP1Y (pwm)
// '----1100' pwm mode, active hi
ccpr1l = 250; // 100% duty cycle, 0% brightness
tmr2 = 0; // clear Timer 2 register
t2con = 0b00000110; // '0-------' unimplemented bit
// '-0000---' TOUTPS<3:0>, postscale 1
// '-----1--' TMR2ON, turn Timer 2 on
// '------10' T2CKPS<1:0>, prescale 16
pr2 = 250-1; // 250 x 8-usec 'ticks' = 2 msecs
pir1 = 0; // clear peripheral interrupt flags
pie1.TMR2IE = 1; // set Timer 2 interrupt enable bit
intcon = 0b11000000; // '1-------' GIE, enable global and
// '-1------' PEIE, peripheral ints
// '--0-----' T0IE, TMR0 ints off
// '---0----' INTE, off
// '----0---' GPIE, IOC disabled
// '-----000' T0IF/INTF/GPIF flags
while(1)
{
brightness(32); // brightness range 0..63
display[0] = 0; // display "0123"
display[1] = 1; //
display[2] = 2; //
display[3] = 3; //
}
}
/********************************************************************
* interrupt service routine *
********************************************************************/
void interrupt() // 2-msec Timer 2 interrupts
{ pir1.TMR2IF = 0; // clear timer 2 interrupt flag
/* *
* retask the column driver lines while PWM is hi (display off) *
* as <clk> and <dat> lines to load the display shift register *
* then write new column select bit pattern to portb before PWM *
* goes lo (display on) to resume RB4-RB1 column driver duties. *
* */
for(u08 i = 0; i < 8; i++) // load the driver shift register
{ clk = 0; dat = 0; // clk = 0, dat = 0
if(work.7) dat = 1; // if bit == 1 then dat = 1
clk = 1; work >>= 1; // send bit, shift 'work' var
}
portb = ~colsel; // select new column
/* *
* sample and debounce each switch at 8-msec debounce intervals *
* *
* swnew ___---___---___---___ sample active lo switches *
* swold ____---___---___---__ switch state latch *
* swnew ___-__-__-__-__-__-__ changes, press or release *
* swnew ___-_____-_____-_____ filter out 'release' bits *
* flags ___------______------ toggle flag bits for main *
* */
swnew = swold | colsel; // set bit to '1' (pressed)
if(portb.5) // if not pressed
swnew ^= colsel; // set bit to '0' (released)
swnew ^= swold; // changes, press or release
swold ^= swnew; // update switch state latch
swnew &= swold; // filter out 'release' bits
flags ^= swnew; // toggle flag bits for main
/* *
* prepare for next column update interrupt *
* */
if(colnbr == 3) // if last column
{ colnbr = 0; // reset column number
colsel = 2; // reset column select for RB1
}
else // else, not last column, so
{ colnbr++; // bump column number, 0..3
colsel <<= 1; // bump column select bit mask
}
work = segdata[display[colnbr]];
}
No experience with the 16F77, but for driving the relays, consider the ULN2003.
Sorry to nitpick Jon, but the ULN2003/2004 has 7 transistors, the ULN2803/2804 has 8 transistors (I thought it was important to mention before the OP buys one).
And I agree it's an ideal solution for driving 8 relays.
I never could figure why they made it with 7 transistors maybe it's just a 5x7 world LOL
They were originally made for driving print heads on impact printers. Back in the olden days of Epson MX80s, the print head had a row of 7 pins. I believe that's why there are 7 drivers in the package.
Go ahead and nitpick RB. My mistake, sorry about that. But 2 ULN2003's is still easier than 8 transistors, 8 base resistors and 8 EMF diodes
Integral suppression diodes for inductive loads
I really don't see why you want to make a big deal Rb pointed out the OP may want one with 8 transistors in it. And I pointed out that the OP needs to make sure it has suppression diodes for inductive loadsIntegral suppression diodes for inductive loads
... I've never written a bit bang routine and I've tried googl'ing serial bit banging for PICs and haven't found what I'm looking for so if someone could direct me to some sample bit bang routine codes and/or reference sites where I could read up on it I would greatly appreciate it.
;******************************************************************
;* *
;* Filename: 16F88 4-Digit.asm *
;* Author: Mike McLaren, K8LH *
;* (C)2010: Micro Application Consultants *
;* Date: 18-Jul-10 *
;* *
;* Mux'd 4-digit display & switch demo for Mosaic *
;* *
;* MPLab: 8.50 (tabs=8) *
;* MPAsm: 5.35 *
;* *
;******************************************************************
#include <p16f88.inc>
errorlevel -302
list st=off
radix dec
__CONFIG _CONFIG1, _CCP1_RB0&_LVP_OFF&_MCLR_OFF&_WDT_OFF&_INTRC_IO
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
;--< variables >---------------------------------------------------
cblock 0x20
disp:4 ; char disp[4]
colnbr ; char colnbr, 0..3
colsel ; char colsel, bit mask
bitctr ; general purpose counter
work ; isr work variable
beep ; beep msec counter
latch ; switch state latch
flags ; switch flag bits
endc
cblock 0x70
w_isr ;
s_isr ;
p_isr ;
f_isr ;
endc
;--< constants >---------------------------------------------------
spkr equ 6 ; speaker bit index (RB6)
#define clk PORTB,1 ; TPIC6C595 <clk> on RB1
#define dat PORTB,2 ; TPIC6C595 <dat> on RB2
#define swx PORTB,5 ; switch matrix input (RB5)
;******************************************************************
; reset vector *
;******************************************************************
org 0x000
vReset
clrf STATUS ; force bank 0, IRP 0 |B0
goto init ; |B0
;******************************************************************
; interrupt vector *
;******************************************************************
org 0x004
vInt
movwf w_isr ; save WREG |B?
swapf STATUS,W ; don't change STATUS bits |B?
movwf s_isr ; save STATUS |B?
clrf STATUS ; bank 0 |B0
movf PCLATH,W ; |B0
movwf p_isr ; save PCLATH |B0
movf FSR,W ; |B0
movwf f_isr ; save FSR |B0
bcf PIR1,TMR2IF ; clear timer 2 interrupt flag |B0
;
; re-task RB4:RB1 column driver lines as <clk> and <dat> lines
; while PWM is high (display off) to load the TPIC6C595 driver
; shift register then write new column select bit pattern onto
; the pins to resume column driver duties before PWM goes low.
;
movlw 8 ; |B0
movwf bitctr ; bitctr = 8 |B0
loadSR bcf clk ; clk = 0 |B0
bcf dat ; dat = 0 |B0
btfsc work,7 ; bit = 1? no, skip, else |B0
bsf dat ; dat = 1 |B0
bsf clk ; clk = 1, shift bit into SR |B0
rlf work,F ; shift 'work' |B0
decfsz bitctr,F ; done? yes, skip, else |B0
goto loadSR ; loop |B0
movlw b'00011110' ; |B0
iorwf PORTB,W ; turn off column select bits |B0
xorwf colsel,W ; active lo column select bit |B0
movwf PORTB ; select new column |B0
;
; beep task (32-msec 500-Hz tone @ 1-msec interrupts)
;
isrBeep
movf beep,W ; beep task running? |B0
bz isrSw ; no, branch, else |B0
movlw 1<<spkr ; speaker pin mask |B0
xorwf PORTB,F ; toggle speaker pin |B0
decf beep,F ; decrement beep msec counter |B0
;
; switch management (sample switch at current selected column)
;
; wreg ___---___---___---____ sample active lo switches
; latch ____---___---___---___ switch state latch
; wreg ___-__-__-__-__-__-___ changes, press or release
; wreg ___-_____-_____-______ filter out 'release' bits
; flags ___------______------- toggle flag bits for main
;
isrSw
movf latch,W ; W = switch state latch |B0
iorwf colsel,W ; set SWn bit to '1' (pressed) |B0
btfsc PORTB,5 ; pressd (0)? yes, skip, else |B0
xorwf colsel,W ; set SWn bit to '0' (released) |B0
xorwf latch,W ; W = changes, press or release |B0
xorwf latch,F ; update switch state latch |B0
andwf latch,W ; filter out "new release" bits |B0
skpz ; a "new press"? no, skip, else |B0
bsf beep,5 ; task a new press beep |B0
xorwf flags,F ; toggle switch flags for main |B0
;
; prep for next column update interrupt
;
isrNext
incf colnbr,F ; bump column number |B0
bcf colnbr,2 ; 0..3 inclusive |B0
clrc ; |B0
rlf colsel,W ; advance column select bit |B0
btfsc colsel,4 ; last column? no, skip, else |B0
movlw b'00000010' ; reset to first column |B0
movwf colsel ; |B0
movlw disp ; W = &disp[0] |B0
addwf colnbr,W ; add column number, 0..3 |B0
movwf FSR ; FSR = &disp[colnbr] |B0
movf INDF,W ; W = disp[colnbr], 0..9 |B0
call SegTable ; get segment data |B0
movwf work ; SR data for next column |B0
;
; restore context
;
movf f_isr,W ; |B0
movwf FSR ; restore FSR |B0
movf p_isr,W ; |B0
movwf PCLATH ; restore PCLATH |B0
swapf s_isr,W ; |B0
movwf STATUS ; restore STATUS |B?
swapf w_isr,f ; don't screw up STATUS |B?
swapf w_isr,W ; restore WREG |B?
retfie ; return from interrupt |B?
;******************************************************************
SegTable
addwf PCL,F ; |B0
retlw b'00111111' ; "0" -|F|E|D|C|B|A |B0
retlw b'00000110' ; "1" -|-|-|-|C|B|- |B0
retlw b'01011011' ; "2" G|-|E|D|-|B|A |B0
retlw b'01001111' ; "3" G|-|-|D|C|B|A |B0
retlw b'01100110' ; "4" G|F|-|-|C|B|- |B0
retlw b'01101101' ; "5" G|F|-|D|C|-|A |B0
retlw b'01111101' ; "6" G|F|E|D|C|-|A |B0
retlw b'00000111' ; "7" -|-|-|-|C|B|A |B0
retlw b'01111111' ; "8" G|F|E|D|C|B|A |B0
retlw b'01101111' ; "9" G|F|-|D|C|B|A |B0
;******************************************************************
; main init *
;******************************************************************
init
bsf STATUS,RP0 ; bank 1 |B1
clrf ANSEL ; turn ADC functions off |B1
movlw b'01110000' ; |B1
movwf OSCCON ; select 8-MHz INTOSC clock |B1
Stable btfss OSCCON,IOFS ; Int Osc Freq Stable bit set? |B1
goto Stable ; no, branch and wait |B1
;
; setup various ISR, Port, Switch, Clock, and Display variables
;
clrf TRISA ; |B1
movlw b'11100000' ; |B1
movwf TRISB ; |B1
bcf STATUS,RP0 ; bank 0 |B0
movlw b'00011110' ; |B0
movwf PORTB ; turn column select lines off |B0
;
; setup CCP/TMR2 "PWM" mode with a 2-msec period (8-MHz INTOSC)
;
clrf TMR2 ; clear TMR2 register |B0
bsf STATUS,RP0 ; select Bank 1 |B1
clrf PIE1 ; mask all peripheral irqs |B1
bsf PIE1,TMR2IE ; except for TMR2 irqs |B1
movlw d'250'-1 ; 250 x 8 usec 'ticks' |B1
movwf PR2 ; for 1-msec interrupts |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf PIR1 ; clear peripheral irq flags |B0
movlw b'00000010' ; pre 16, post 1, TMR2 off |B0
; 0------- unused
; -0000--- postscale 1
; -----0-- TMR2 off
; ------10 prescaler 16
movwf T2CON ; for 8 usec ticks (8-MHz clock) |B0
movlw b'00001100' ; setup CCP module for "PWM" |B0
; 00------ unused
; --00---- DC1B1:DC1B0
; ----1100 PWM mode
movwf CCP1CON ; turn on PWM mode |B0
movlw 120 ; 50% brightness |B0
movwf CCPR1L ; 20% duty cycle |B0
bsf INTCON,GIE ; enable global irqs |B0
bsf INTCON,PEIE ; enable peripheral irqs |B0
;
; initialize program variables
;
clrf disp+0 ; disp[0] = 0 |B0
clrf disp+1 ; disp[1] = 0 |B0
clrf disp+2 ; disp[2] = 0 |B0
clrf disp+3 ; disp[3] = 0 |B0
clrf colnbr ; colnbr = 0 |B0
movlw 2 ; |B0
movwf colsel ; colsel = b'00000010' |B0
clrf bitctr ; bitctr = 0 |B0
clrf beep ; beep = 0 |B0
clrf latch ; |B0
clrf flags ; |B0
bsf T2CON,TMR2ON ; start TMR2 (interrupts) |B0
;******************************************************************
; main loop *
;******************************************************************
loop
goto loop ; |B0
;******************************************************************
end
Hi Jon,
Here's the assembly language version of that program, minus gamma correction. I apologize if the code seems a bit deep.
Good luck on your project. Cheerful regards, Mike
Code:;****************************************************************** ;* * ;* Filename: 16F88 4-Digit.asm * ;* Author: Mike McLaren, K8LH * ;* (C)2010: Micro Application Consultants * ;* Date: 18-Jul-10 * ;* * ;* Mux'd 4-digit display & switch demo for Mosaic * ;* * ;* MPLab: 8.50 (tabs=8) * ;* MPAsm: 5.35 * ;* * ;****************************************************************** #include <p16f88.inc> errorlevel -302 list st=off radix dec __CONFIG _CONFIG1, _CCP1_RB0&_LVP_OFF&_MCLR_OFF&_WDT_OFF&_INTRC_IO __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;--< variables >--------------------------------------------------- cblock 0x20 disp:4 ; char disp[4] colnbr ; char colnbr, 0..3 colsel ; char colsel, bit mask bitctr ; general purpose counter work ; isr work variable beep ; beep msec counter latch ; switch state latch flags ; switch flag bits endc cblock 0x70 w_isr ; s_isr ; p_isr ; f_isr ; endc ;--< constants >--------------------------------------------------- spkr equ 6 ; speaker bit index (RB6) #define clk PORTB,1 ; TPIC6C595 <clk> on RB1 #define dat PORTB,2 ; TPIC6C595 <dat> on RB2 #define swx PORTB,5 ; switch matrix input (RB5) ;****************************************************************** ; reset vector * ;****************************************************************** org 0x000 vReset clrf STATUS ; force bank 0, IRP 0 |B0 goto init ; |B0 ;****************************************************************** ; interrupt vector * ;****************************************************************** org 0x004 vInt movwf w_isr ; save WREG |B? swapf STATUS,W ; don't change STATUS bits |B? movwf s_isr ; save STATUS |B? clrf STATUS ; bank 0 |B0 movf PCLATH,W ; |B0 movwf p_isr ; save PCLATH |B0 movf FSR,W ; |B0 movwf f_isr ; save FSR |B0 bcf PIR1,TMR2IF ; clear timer 2 interrupt flag |B0 ; ; re-task RB4:RB1 column driver lines as <clk> and <dat> lines ; while PWM is high (display off) to load the TPIC6C595 driver ; shift register then write new column select bit pattern onto ; the pins to resume column driver duties before PWM goes low. ; movlw 8 ; |B0 movwf bitctr ; bitctr = 8 |B0 loadSR bcf clk ; clk = 0 |B0 bcf dat ; dat = 0 |B0 btfsc work,7 ; bit = 1? no, skip, else |B0 bsf dat ; dat = 1 |B0 bsf clk ; clk = 1, shift bit into SR |B0 rlf work,F ; shift 'work' |B0 decfsz bitctr,F ; done? yes, skip, else |B0 goto loadSR ; loop |B0 movlw b'00011110' ; |B0 iorwf PORTB,W ; turn off column select bits |B0 xorwf colsel,W ; active lo column select bit |B0 movwf PORTB ; select new column |B0 ; ; beep task (32-msec 500-Hz tone @ 1-msec interrupts) ; isrBeep movf beep,W ; beep task running? |B0 bz isrSw ; no, branch, else |B0 movlw 1<<spkr ; speaker pin mask |B0 xorwf PORTB,F ; toggle speaker pin |B0 decf beep,F ; decrement beep msec counter |B0 ; ; switch management (sample switch at current selected column) ; ; wreg ___---___---___---____ sample active lo switches ; latch ____---___---___---___ switch state latch ; wreg ___-__-__-__-__-__-___ changes, press or release ; wreg ___-_____-_____-______ filter out 'release' bits ; flags ___------______------- toggle flag bits for main ; isrSw movf latch,W ; W = switch state latch |B0 iorwf colsel,W ; set SWn bit to '1' (pressed) |B0 btfsc PORTB,5 ; pressd (0)? yes, skip, else |B0 xorwf colsel,W ; set SWn bit to '0' (released) |B0 xorwf latch,W ; W = changes, press or release |B0 xorwf latch,F ; update switch state latch |B0 andwf latch,W ; filter out "new release" bits |B0 skpz ; a "new press"? no, skip, else |B0 bsf beep,5 ; task a new press beep |B0 xorwf flags,F ; toggle switch flags for main |B0 ; ; prep for next column update interrupt ; isrNext incf colnbr,F ; bump column number |B0 bcf colnbr,2 ; 0..3 inclusive |B0 clrc ; |B0 rlf colsel,W ; advance column select bit |B0 btfsc colsel,4 ; last column? no, skip, else |B0 movlw b'00000010' ; reset to first column |B0 movwf colsel ; |B0 movlw disp ; W = &disp[0] |B0 addwf colnbr,W ; add column number, 0..3 |B0 movwf FSR ; FSR = &disp[colnbr] |B0 movf INDF,W ; W = disp[colnbr], 0..9 |B0 call SegTable ; get segment data |B0 movwf work ; SR data for next column |B0 ; ; restore context ; movf f_isr,W ; |B0 movwf FSR ; restore FSR |B0 movf p_isr,W ; |B0 movwf PCLATH ; restore PCLATH |B0 swapf s_isr,W ; |B0 movwf STATUS ; restore STATUS |B? swapf w_isr,f ; don't screw up STATUS |B? swapf w_isr,W ; restore WREG |B? retfie ; return from interrupt |B? ;****************************************************************** SegTable addwf PCL,F ; |B0 retlw b'00111111' ; "0" -|F|E|D|C|B|A |B0 retlw b'00000110' ; "1" -|-|-|-|C|B|- |B0 retlw b'01011011' ; "2" G|-|E|D|-|B|A |B0 retlw b'01001111' ; "3" G|-|-|D|C|B|A |B0 retlw b'01100110' ; "4" G|F|-|-|C|B|- |B0 retlw b'01101101' ; "5" G|F|-|D|C|-|A |B0 retlw b'01111101' ; "6" G|F|E|D|C|-|A |B0 retlw b'00000111' ; "7" -|-|-|-|C|B|A |B0 retlw b'01111111' ; "8" G|F|E|D|C|B|A |B0 retlw b'01101111' ; "9" G|F|-|D|C|B|A |B0 ;****************************************************************** ; main init * ;****************************************************************** init bsf STATUS,RP0 ; bank 1 |B1 clrf ANSEL ; turn ADC functions off |B1 movlw b'01110000' ; |B1 movwf OSCCON ; select 8-MHz INTOSC clock |B1 Stable btfss OSCCON,IOFS ; Int Osc Freq Stable bit set? |B1 goto Stable ; no, branch and wait |B1 ; ; setup various ISR, Port, Switch, Clock, and Display variables ; clrf TRISA ; |B1 movlw b'11100000' ; |B1 movwf TRISB ; |B1 bcf STATUS,RP0 ; bank 0 |B0 movlw b'00011110' ; |B0 movwf PORTB ; turn column select lines off |B0 ; ; setup CCP/TMR2 "PWM" mode with a 2-msec period (8-MHz INTOSC) ; clrf TMR2 ; clear TMR2 register |B0 bsf STATUS,RP0 ; select Bank 1 |B1 clrf PIE1 ; mask all peripheral irqs |B1 bsf PIE1,TMR2IE ; except for TMR2 irqs |B1 movlw d'250'-1 ; 250 x 8 usec 'ticks' |B1 movwf PR2 ; for 1-msec interrupts |B1 bcf STATUS,RP0 ; bank 0 |B0 clrf PIR1 ; clear peripheral irq flags |B0 movlw b'00000010' ; pre 16, post 1, TMR2 off |B0 ; 0------- unused ; -0000--- postscale 1 ; -----0-- TMR2 off ; ------10 prescaler 16 movwf T2CON ; for 8 usec ticks (8-MHz clock) |B0 movlw b'00001100' ; setup CCP module for "PWM" |B0 ; 00------ unused ; --00---- DC1B1:DC1B0 ; ----1100 PWM mode movwf CCP1CON ; turn on PWM mode |B0 movlw 120 ; 50% brightness |B0 movwf CCPR1L ; 20% duty cycle |B0 bsf INTCON,GIE ; enable global irqs |B0 bsf INTCON,PEIE ; enable peripheral irqs |B0 ; ; initialize program variables ; clrf disp+0 ; disp[0] = 0 |B0 clrf disp+1 ; disp[1] = 0 |B0 clrf disp+2 ; disp[2] = 0 |B0 clrf disp+3 ; disp[3] = 0 |B0 clrf colnbr ; colnbr = 0 |B0 movlw 2 ; |B0 movwf colsel ; colsel = b'00000010' |B0 clrf bitctr ; bitctr = 0 |B0 clrf beep ; beep = 0 |B0 clrf latch ; |B0 clrf flags ; |B0 bsf T2CON,TMR2ON ; start TMR2 (interrupts) |B0 ;****************************************************************** ; main loop * ;****************************************************************** loop goto loop ; |B0 ;****************************************************************** end
Yeah, that's it Jon. Pretty simple, right?.I also pulled up the data sheet on the TPIC6C595. Basically it's not "timing critical" serial, but more like "triggered serial". Every time the clock pin is pulsed it shifts in whatever bit happens to be present on the data pin on the rising edge of the clock pulse.
Yeah, that's it Jon. Pretty simple, right?
;
movlw 8 ; |B0
movwf bitctr ; bitctr = 8 |B0
loadSR bcf clk ; clk = 0 |B0
bcf dat ; dat = 0 |B0
btfsc work,7 ; bit = 1? no, skip, else |B0
bsf dat ; dat = 1 |B0
bsf clk ; clk = 1, shift bit into SR |B0
rlf work,F ; shift 'work' |B0
decfsz bitctr,F ; done? yes, skip, else |B0
goto loadSR ; loop |B0
movlw b'00011110' ; |B0
iorwf PORTB,F ; blank the display |B0
bsf lat ; pulse RCK pin to latch SR |B0
bcf lat ; data onto TPIC6C595 outputs |B0
xorlw colsel,W ; current column select bit |B0
movwf PORTB ; display new column |B0
;
Also...in regards to bit banging...I've never written a bit bang routine and I've tried googl'ing serial bit banging for PICs and haven't found what I'm looking for so if someone could direct me to some sample bit bang routine codes and/or reference sites where I could read up on it I would greatly appreciate it.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?