On Wed, Mar 17, 2004 at 10:03:16AM +0200, Andre Miller wrote: > > Hi, > > For the display of my project I'm using four seven segment displays (common > anode), using 8 IO pins for the segments, and another 4 to drive the > individual displays. The four displays are driven through a BC557 transistor > (with a 1K resistor on the gate), and each segment is connected to an IO pin > through a 330 Ohm resistor (all segments are common to all displays, going > through the same resistor. I hope this is all clear :-) Perfectly. > > To drive the displays I repeat the following via a timer interrupt > (Prescaler set to 1:1, 8 bit timer, 4 Mhz clock): > > 1) Turn on display X, turn off all other displays > 2) Set the correct segments for display X > 3) Add one to X > 4) If (X > 4), set X = 1 Typical. > > So each time the ISR executes it turns on the next display, etc. > > Problem is, the segments on the displays are very dim if I do this. Expected for the reason you list below. > If I > only have one display on, then it is the correct brightness. This is > understandable since each display is only on for 1/4 of the time now. I was > thinking maybe I could just use a quarter of the value resistor instead > (replace 330 Ohm with 100 Ohm, for example). But then, won't it draw too > much current even if its only for a fraction of second, or will it all > average out? It'll draw too much current (Somewhere in the ballpark of 30ma). Bad idea. > Also, if something happens which cause the pic to stop > multiplexing the displays, there is the possibility of only one display > being on for a long period of time (clocking stops, transistor failure, > etc). Yup. A dangerous possibility. > > Any suggestions on how to overcome this? The way I'd generally handle this is to add more hardware to the mix. One of my favorites for driving displays is the 7445 BCD to decimal decoder. While you can only drive one segment at a time with it, it'll drive that segment with 80ma of current. So you can hook it up this way: 1) Tie 4 I/O pins to the BC557 via the 1k as you have. But now transfer the current limiting resistor (which can now be 47 ohm) between the collector and the anodes of the display. Keep the emitter tied to Vdd as before. 2) Now wire each segment cathode of the display to a output on the 7445. You'll even have two left over output to tie to individual LEDs or use to read switches if you like. 3) Take the DCBA input of the 7445 and tie to 4 more I/O pins. One reason I like this setup is because you save 4 I/O pin and can drive the entire display from a single 8 bit port. Your algorithm is slightly more complex now. Also to prevent bleed some rearranging is in order: 0) Turn off all displays. Prevents bleed. 1) Set the correct segment for display X by incrementing segment count (SC) on 7445 DCBA input. I'd normally use a shadow register for this but I'm paranoid. 2) Check to see if the segment is supposed to be on. 3) If it's supposed to be on, then turn on the display 4) If SC > 7 then SC = 0 and X = X+1 4) If (X > 4), set X = 1 [You can also do this by shifing a 0 through the 4 bits assigned to the BC557. Clock speed should be fine. Note that you should delay for each segment whether or not it is turned on or off. As for display protection it's harder than you think. The question is if the OSCOUT for the PIC is guaranteed to operate even if the PIC code is wandering in the weeds. If so then you can make an external watchdog using a ripple counter and some OR gates. Clock a counter like a 74HC4020 with the OSCOUT gated through an OR gate (more on this in a minute). Then take an output of the counter that represents the MAX on time you want to allow and tie it to the input of two more or gates, and the OSCOUT OR gate's other input. Next pick a lower output and tie it to the RB0/INT pin of the PIC. Then separate the D and C inputs of the 7445 from the PIC, wire those PIC outputs to the other input of the two OR gates above, and wire the outputs of the OR gates back to the D and C inputs of the 7445. I still have one thing to figure out so I'll come back to it in a minute but presume for the moment that another PIC I/O pin is tied to the active high reset of the counter. Here's how it works. The OSCOUT will clock the counter at 1 Mhz. The MAX output of the counter is the timeout. When it goes high it forces each of the three OR gates that it's connected to to go high. The gated clock will stop and the D and C inputs to the 7445 will go high. The 7445 is designed to ignore invalid inputs. With DC both high the count will be 12 or above. So all of the outputs of the 7445 turn off, turning off the display. The interrupt output of the counter can give you a steady stream of pulses to interrupt the PIC. All you have to do in the interrupt routine is to reset the counter to set up the next interrupt and to reset the external watchdog. The only part I don't have figured out is the fact that reset needs to be edge driven instead of level driven. A flip flop is in order, but I'd like to figure out how to do this without adding another chip to the mix. The behavior should be: the reset I/O pin of the PIC goes high (or low as needed) and the counter resets. Since the interrupt that generated the reset was tied to a high output pin on the counter, that pin will go low. The falling edge of that pin going low should release the reset, so even if the reset from the PIC I/O remains set, the counter doesn't remain in reset. But it's a bit of real estate to pull off. Maybe trusting the PIC watchdog is the right answer. BAJ -- http://www.piclist.com hint: PICList Posts must start with ONE topic: [PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads