In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote: Hi Chris and Guenther; Guenther; I'm afraid I must disagree with you. At the current I indicated, most LEDs give off significant brightness, even when multiplexed 4 to 1. I have a set up here in front of me using 7 segment displays with segment column resistors of 1K Ohm giving plenty of brightness at about 1/2 milliAmp ! Why not try the simplest solution before assuming it's inadequate. After all he is looking for a low cost (and presumably simple) answer. My suggestion is as simple as it gets. For real bright industrial applications, I also have used the 4 NPN "bank" transistors. But using segment column transistors however is way over-designed unless you are really going to silly currents. With the performance of today's LEDs, the extra circuitlry just does does't buy you that much. I have attached the co-operative RTOS (sequencer), multiplexing and counting (seconds and minutes) code...... it's ready to run. [code] id 'LEDMux1' ; Dec 26, 2006 ;for demonstration purposes assume 4 digits of 7 segment display; MM SS ;can be readily expanded to 6 digits of 7 segments; HH MM SS Device SX28, OscHS3, Turbo, Optionx ;new assembler ; Device watchdog ;turn the watchdog on ; Device bor42 ;turn brown-out detect on ; Device carryx ;turn extended carry on ; Device protect ;turn program read protection on Freq 50_000_000 ;default run speed = 50MHz Reset Initialize ;start at label on reset IRC_Cal IRC_Slow ; ;Constants for the Mode register settings ModeComp equ $08 ;mode for port B comparator swap access ModeBPend equ $09 ;mode for port B change detect sawp access ModeBEdge equ $0A ;mode for port B change rising edge selection (0) ModeBEnable equ $0B ;mode for port B change detection enable (0) ModeSchmidt equ $0C ;mode for port BC bit Schmidt trigger enable (0) ModeLevel equ $0D ;mode for port ABC bit CMOS level selection (0) ModePullup equ $0E ;mode for port ABC bit pullup selection (0) ModeTristate equ $0F ;mode for port ABC bit output direction selection (0) ;Constants for the option register ; +---------------------------- 0 for Wreg at address 1 ; |+--------------------------- 0 for RTCC roll over interrupt enable ; ||+-------------------------- 0 for RTCC increment on instruction clock ; |||+------------------------- 0 for RTCC rising edge increment ; |||| +----------------------- 0 for RTCC prescaler assignment ; |||| |+---------------------- Prescaler 2 ; |||| ||+--------------------- Prescaler 1 ; |||| |||+-------------------- Prescaler 0 14kHz watchdog; 000 is 16 mSec ; |||| |||| RTCC_Dis_Ext_H2L__WDT = %1111_1000 ; RTCC_Dis_Int_H2L__WDT = %1101_1000 ; RTCC_Ena_Ext_H2L__WDT = %1011_1000 ; RTCC_Ena_Int_H2L__WDT = %1001_1000 ; Wreg_Dis_Ext_H2L__WDT = %0111_1000 ; Wreg_Dis_Int_H2L__WDT = %0101_1000 ; Wreg_Ena_Ext_H2L__WDT = %0011_1000 ; Wreg_Ena_Int_H2L__WDT = %0001_1000 ; IntConst equ -125 ;2.5 usec base tick SourcePort equ rb ;drives up to 8 simultaneous leds in one bank; 4 banks in parallel SinkPort equ ra ;sinks 4 banks, one bank per bit ZeroPattern equ %0011_1111 ;segments to display a 0 on seven segment display org 8 Flags ds 1 ; IntFlag equ Flags.0 org $10 Timer100uSec ds 1 ;down counts number of 2.5 uSec ticks toward one 100 uSec tick Timer1mSec ds 1 ;downcounts number of 100 uSec ticks toward one 1 mSec tick Timer10mSec ds 1 ;downcounts number of 1 mSec ticks toward one 10 mSec tick Timer100mSec ds 1 ;downcounts number of 10 mSec ticks toward one 100 mSec tick Timer1Sec ds 1 ;downcounts number of 100 mSec ticks toward one 1 Second tick Seconds1 ds 1 ;up count seconds Seconds10 ds 1 ;up count tens of seconds Minutes1 ds 1 ;up count minutes Minutes10 ds 1 ;up count tens of minutes MuxState ds 1 ;round-ribin muliplexer state variable Bank0Leds ds 1 ;Leds to be multiplex activated in bank 0 Bank1Leds ds 1 ;Leds to be multiplex activated in bank 1 Bank2Leds ds 1 ;Leds to be multiplex activated in bank 2 Bank3Leds ds 1 ;Leds to be multiplex activated in bank 3 watch Seconds1,8,udec watch Seconds10,8,udec watch Minutes1,8,udec watch Minutes1,8,udec watch Bank0Leds,8,ubin watch Bank1Leds,8,ubin watch Bank2Leds,8,ubin watch Bank3Leds,8,ubin org 0 ; Interrupt setb IntFlag ;indicate that an interrupt has occurred mov w,#IntConst ; retiw ; Initialize ;Program starts here on power-up and on reset; must be on page 0 ======================================================== InitLevels mov m,#ModeLevel ;Set to 0 for CMOS levels mov !ra,#%0000 ; mov !rb,#%0000_0000 ; mov !rc,#%0000_0000 ; InitPullup mov m,#ModePullup ;Set to 0 for pullups mov !ra,#%0000 ; mov !rb,#%0000_0000 ; mov !rc,#%0000_0000 ; InitTris mov m,#ModeTristate ;Set to 0 for output clr ra ; mov !ra,#%1111_0000 ;sinking port X,X,X,X_Sink3,Sink2,Sink1,Sink0 clr rb ; mov !rb,#%0000_0000 ;source port LED7,LED6,LED5,LED4_LED3,LED2,LED1,LED0 clr rc ; mov !rc,#%1111_1111 ;not used ClrMem clr fsr ;beginning of ram ClrOne setb fsr.4 ;stay in upper half clr ind ;clear location incsz fsr ;next location jmp ClrOne ;continue clearing mov Timer100uSec,#40 ;initialize down counter to 40 * 2.5 uSec = 100 uSec mov Timer1mSec,#10 ;initialize down counter to 10 * 100 uSec = 1 mSec mov Timer10mSec,#10 ;initialize down counter to 10 * 1 mSec = 10 mSec mov Timer100mSec,#10 ;initialize down counter to 10 * 10 mSec = 100 mSec mov Timer1Sec,#10 ;initialize down counter to 10 * 100 mSec = 1 Sec InitRTCC clr rtcc ; mov !option,#RTCC_Ena_Int_H2L__WDT ; clr Flags ; InitMux mov MuxState,#DriveBank0 ;set up the first bank to be driven mov Bank0Leds,#ZeroPattern ;start by showing the pattern for zero mov Bank1Leds,#ZeroPattern ;start by showing the pattern for zero mov Bank2Leds,#ZeroPattern ;start by showing the pattern for zero setb Bank2Leds.7 ;merge in a right hand decimal point mov Bank3Leds,#ZeroPattern ;start by showing the pattern for zero ;MainLine Task Timer ======================================================================================================= Main sb IntFlag ; jmp Main ;wait here until an interrupt has happened clrb IntFlag ;acknowledge the interrupt bank 0 ;point to timer RAM Tick2_5uSec decsz Timer100uSec ;one 2.5 uSec tick off 100 uSec timer jmp Main ;timer has not expired mov Timer100uSec,#40 ;reload 100 uSec down counter with 40 * 2.5 uSec = 100 uSec Tick100uSec decsz Timer1mSec ;one 100 uSec tick off 1 mSec timer jmp Main ;timer has not expired mov Timer1mSec,#10 ;reload 1 mSec down counter with 10 * 100 uSec = 1 mSec Tick1mSec call Multiplexer ;do one bank of 8 LEDs bank 0 ;point to timer RAM decsz Timer10mSec ;one 1 mSec tick off 10 mSec timer jmp Main ;timer has not expired mov Timer10mSec,#10 ;reload 10 mSec down counter with 10 * 1 mSec = 10 mSec Tick10mSec decsz Timer100mSec ;one 10 mSec tick off 100 mSec timer jmp Main ;timer has not expired mov Timer100mSec,#10 ;reload 100 mSec down counter with 10 * 10 mSec = 100 mSec Tick100mSec decsz Timer1Sec ;one 100 mSec tick off 1 Sec timer jmp Main ;timer has not expired call TimeCounter ;do a one second clock tick bank 0 ;point to timer RAM mov Timer1Sec,#10 ;reload 1 Sec down counter with 10 * 100 mSec = 1 Sec jmp Main ;loop in this scheduler; regulated by the interrupt tick ;Multiplexer Routine ================================================================================== Multiplexer mov SinkPort,#%0000_1111 ;drive all bank sinkers high during mux setup to prevent ghosting mov pc,MuxState ;calculated jump to next state DriveBank0 mov SourcePort,Bank0LEDs ;load the led pattern to driver port clrb SinkPort.0 ;turn this group on mov MuxState,#DriveBank1 ;set state variable to do bank1 next retp ;return to mainline scheduler DriveBank1 mov SourcePort,Bank1LEDs ;load the led pattern to driver port clrb SinkPort.1 ;turn this group on mov MuxState,#DriveBank2 ;set state variable to do bank2 next retp ;return to mainline scheduler DriveBank2 mov SourcePort,Bank2LEDs ;load the led pattern to driver port clrb SinkPort.2 ;turn this group on mov MuxState,#DriveBank3 ;set state variable to do bank3 next retp ;return to mainline scheduler DriveBank3 mov SourcePort,Bank3LEDs ;load the led pattern to driver port clrb SinkPort.3 ;turn this group on mov MuxState,#DriveBank0 ;set state variable to do bank0 next retp ;return to mainline scheduler ;Clock Routines ..... assume minutes and seconds of 4 digits of 7 segment LED display ========================= ;there are better, but less obvious ways to tackle this clock function section TimeCounter Seconds inc Seconds1 ;increment the one second time clock counter mov w,Seconds1 ;load one second time clock counter call EncodeW2Seg ;lookup LED pattern for this number mov Bank0LEDs,w ;save it to the multiplexer routine cjbe Seconds1,#9,TimeExit ;test for overflow on nine clr Seconds1 ;reset to 0 mov w,Seconds1 ;one second time clock counter call EncodeW2Seg ;lookup LED pattern for this number mov Bank0LEDs,w ;save it to the multiplexer routine ; TenSeconds inc Seconds10 ;increment the ten second time clock counter mov w,Seconds10 ;load ten second time clock counter call EncodeW2Seg ;lookup LED pattern for this number mov Bank1LEDs,w ;save it to the multiplexer routine cjbe Seconds10,#5,TimeExit ;test for overflow on five clr Seconds10 ;reset to 0 mov w,Seconds10 ; call EncodeW2Seg ;encode this digit according to 7 segment display pattern mov Bank1LEDs,w ;save it to the multiplexer routine Minutes inc Minutes1 ;increment the one minute time clock counter mov w,Minutes1 ;load one minute time clock counter call EncodeW2Seg ;encode this digit according to 7 segment display pattern mov Bank2LEDs,w ;save it to the multiplexer routine setb Bank2Leds.7 ;merge in a right hand decimal point cjbe Minutes1,#9,TimeExit ;test for overflow on nine clr Minutes1 ;reset to 0 mov w,Minutes1 ; call EncodeW2Seg ;encode this digit according to 7 segment display pattern mov Bank2LEDs,w ;save it to the multiplexer routine TenMinutes inc Minutes10 ;increment the ten minute time clock counter mov w,Minutes10 ;load ten minute time clock counter call EncodeW2Seg ;encode this digit according to 7 segment display pattern mov Bank3LEDs,w ;save it to the multiplexer routine cjbe Minutes10,#5,TimeExit ;test for overflow on five clr Minutes10 ;reset to 0 mov w,Minutes10 ; call EncodeW2Seg ;encode this digit according to 7 segment display pattern mov Bank3LEDs,w ;save it to the multiplexer routine TimeExit retp ;retunr to mainline scheduler ;Seven Segment Encoder driven from value held in w =============================================================== EncodeW2Seg and w,#%0000_1111 ;lower nibble only add pc,w ;step into table SegTable ;pgfe_dcba ; Seg0 retw %0011_1111 ;segments for 0 Seg1 retw %0000_0110 ;segments for 1 Seg2 retw %0101_1011 ;segments for 2 Seg3 retw %0100_1111 ;segments for 3 Seg4 retw %0110_0110 ;segments for 4 Seg5 retw %0110_1101 ;segments for 4 Seg6 retw %0111_1101 ;segments for 6 Seg7 retw %0000_0111 ;segments for 7 Seg8 retw %0111_1111 ;segments for 8 Seg9 retw %0110_0111 ;segments for 9 SegA retw %0101_1111 ;segments for a SegB retw %0111_1100 ;segments for b SegC retw %0011_1001 ;segments for c SegD retw %0101_1110 ;segments for d SegE retw %0111_1001 ;segments for e SegF retw %0111_0001 ;segments for f [/code] Cheers, Peter (pjv) ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=162118#m162202 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)