![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
I am working on my first somewhat "elaborate" PIC project, a 7 segment display library on a PIC16F877A.
The display I am using is a 99¢ 9 digits 7 segments LED display (with small clear bubbles over the LEDs wich presumably act as lenses to magnify the tiny LEDs?) The digits share a common anode, so that I need to select them one-by-one by connecting their cathode to ground, and applying a small +5V current to each segment needed to display digits. 9 digits, so that makes 9 pins for selecting digits, and 8 pins for the 7 segments and the dot. 17 pins total. Still following? In order to avoid using 17 pins on the PIC, I use a 16 pin 4028 BCD decoder, so that I can choose digits using only 4 pins on the PIC. The BCD takes the decimal value from the 4 pins and outputs the binary value on 10 different pins. Got it? I need to sink current (remember, to select a digit, I need to connect its cathode to ground), and while the PIC can do that, the 4028 cannot, so I take the 4028's output and feed it to 9 different 2SC2458 transistors, which in turn let current flow through ground when they get the signal from the 4028. The segments on the other hand simply get their current from the PIC's PORTD pins (all 8 of them, 1 for each segment). My code does the following : 1- turn all segments off 2- select active digit 3- turn segments on 4- loop for all digits Now, my problem is : something in the circuit is not acting fast enough. If I let my code run at full speed, I get all 8s (with dots) on the display. I have to insert a sgnificant delay between steps 3 and 4 to get a proper display. I think the 4028 is at fault here. The PIC's oscillator is 8MHz, so it's running at 2MHz in "instruction cycles". The 2SC2458 can switch at a rate of 80MHz. The 4028, at 5V, 25 degrees Celsius has a "Max Propagation Delay Time" of 480ns and "Max Transition Time" of 350ns, which if I read this correctly translates to a total switching rate (off-on-off) of 1.2MHz. So my theory is that the 4028, when the PIC's pin goes low, is still feeding the transistor for a few ns, which translates into 2 digits being lit at the same time for a few ns. When I insert a delay time long enough to let the 4028 go low, everything's fine. What do you think? Am I right or mistaken? Is there something else that could explain my "problem"? Thanks for bearing with me, that's a seriously long *ss post! |
|
|
|
|
|
|
(permalink) |
|
Update : :roll: :lol:
I do not necessarily get all segments lit (all 8s) when there's no delay. As I suspected, I get the previous LED's segments lit in the next digit which I can see with an intermediate delay time, which is fast enough to display proper digits brightly and unwanted segments very dim. But still, my 4028 theory might not be entirely true... Any thoughts? |
|
|
|
|
|
|
(permalink) |
|
Just add in the delays. VGA monitors refresh at typical rates of 80fps and the human eye is often comfortable with that. There is no point in having ultra-high refresh rates.
|
|
|
|
|
|
|
(permalink) | |
|
Quote:
In any case, I am not looking for a solution as much as an explanation. I prefer to understand something that doesn't work, than not understand something that works, if that makes any sense The elegant solution would be to replace the delays with timer reads. If < x cycles have passed, do not refresh, else refresh. The very elegant solution would first check if the desired timer is already started, as to not tie up that particular timer solely for LCD-display purposes. If already used, fine, just read values and compute elapsed time, if not start timer, read and compute. I just need to learn how to use/start/read timers on the PIC :wink: But I am still wondering whose guilty here? The 4028? The transistors? My ignorance? |
||
|
|
|
|
|
(permalink) |
|
What you are doing is called LED multiplexing, a common trick in microcontroller programming. When I said delays, I don't mean the uC doing nothing but waiting for the specified number of cycles to pass. You could use a timer. Or you could carry on normal processing, and update the display at the end of every process, as long as the processes don't take too long. The refresh interval doesnt even have to be strictly the same.
The crux is, as long as the display is refreshed at reasonable refresh intervals, it will look fine. The human vision has memory effect. You can't see the axles of a spinning wheel. |
|
|
|
|
|
|
(permalink) | ||
|
Quote:
This frees the processor to do other work, and the display is taken care of transparently by the interrupts. |
|||
|
|
|
|
|
(permalink) | |||
|
Quote:
I am not looking for a solution as much as an explanation. :wink: :wink: :wink: |
||||
|
|
|
|
|
(permalink) | |
|
Quote:
Thanks to your input, I now know this is called multiplexing. But really, that is not what I am asking in this thread! :wink: :wink: :wink: The software part, I can deal with. It's the electrical/electronics part that I'm pretty clueless about... Anyone? |
||
|
|
|
|
|
(permalink) | |
|
Quote:
Well, you have already stated out the problem, which is the PIC requires one instruction cycle to select the 7-segment, then update it's value in the next. It cannot do both tasks in the same instruction cycle, which is the reason why the display looks strange as your process gets shorter. So, what else do you exactly need to be explained about? |
||
|
|
|
|
|
(permalink) | |
|
Quote:
If you look back through previous posts you will find that I'm NOT a believer in using interrupts just because they are there, but for this use it gives tremendous advantages and no disadvantages. Check my tutorial for how simple it is!. You also ask about hardware?, again check my tutorial hardware, although it's only two digits the principle is the same. Because it's only two, I use a single pin to select either one, this obviously can't be done with more than two digits - so you would need a seperate I/O pin for each digit. |
||
|
|
|
|
|
(permalink) | ||
|
Quote:
As I said, I do not want to add that overhead in a library. Quote:
Here's what my code does, in your terms this time : 1- set all segments value to 0 2- select 7 segment 3- update value 4- loop What I want to understand is why I need a delay between steps 3 and 4. I don't think your theory's right. My theory is that the 4028 isn't switching fast enough. What do you think? |
|||
|
|
|
|
|
(permalink) | |
|
Quote:
|
||
|
|
|
|
|
(permalink) | ||
|
Quote:
Quote:
I haven't read the datasheet for 4028, but I'm pretty sure that the 4028 can operate at much higher frequencies than the PIC itself. |
|||
|
|
|
|
|
(permalink) | ||
|
Quote:
Using a timer and sitting waiting for it to time out wastes the entire time period of the timer, which should be in the 10's of milliseconds - a few 10's of microseconds are around a thousand times more efficient. The display should multiplex at a fast enough rate to eliminate visible flicker, but it doesn't want to go too fast - my tutorial code uses a 16mS refresh rate. You may well have to increase the refresh rate because of your higher number of digits, but it's as simple as altering one byte written to the timer. With interrupts you should have well in the high 90% of free processor time for your main program. It's important (VERY important) that the display refresh is both regular, continuous, and the same all the time (to prevent flicket and uneven brightness across the display). The timer interrupt routine provides this, it's VERY difficult to arrange it otherwise, if you want the program to do anything else. |
|||
|
|
|
|
|
(permalink) | ||
|
First of all, thanks for not losing your patience
Quote:
Quote:
Maybe I should have started this thread simply by asking what those numbers mean! |
|||
|
|
|