tinkerer73
Member level 3
OK, I'm working on a project using a PIC microcontroller and multiple shift registers (74HC595). Right now I'm using a PIC16F1829, but that's not terribly important to my questions, as I'm learning some of this along the way.
Here's the goal: I want the circuit to be able to take a number and display it on a 4 digit 7 segment display, while also displaying a representation on a bar graph to show the number on a scale. I've currently got the circuit running the bar graph with 16 RGB LEDS via 2 shift registers, and the color controlled by a separate PIC12F1501 (for reasons related to another project, I want the color controlled on a separate chip).
I've currently got one 7 segment display hooked directly to the PORTC pins of the microcontroller, and PORTB pins hooked to the shift registers. I can set it to count 0-9, and light up 0-9 LEDs corresponding to the count, always on less than should be (for example, when the number 5 is showing on the counter, 4 LEDs are lit on the bar graph). I tried setting the counter to go to 0-15, but no matter what, I can't get the last LED to light. For some reason, my program is clocking in one extra zero at the end even when my count is at the top. I've attached the pertinent code to see if someone can tell me where my error is. I'm sure there is something minor that I'm missing, but it currently eludes me.
RB4 is connected to serial in on shift register
RB5 is connected to shift register clock
RB6 is connected to storage register clock
As I said, this is basically working, but it seems to clock in an extra zero even when all LEDs should be on.
My second problem is just simply a knowledge issue: I have my 7 segment array set up so that it will load the byte into PORTC according to the current number in my count. How do I set it up to clock in the bits of a byte in memory to the shift registers? My goal is to have one shift register for each digit, so if the count is at, say 750, it will clock in all zeros for the first digit, then the byte for the 7, then the byte for the 5, then the byte for a zero, then latch the storage register. Do I need to break out my array from a single dimension to a two dimensional, and just put in each bit, or is there a way to rotate the bits out to the storage register from a byte? I'm considering using assembly for this, if the microcontroller has a ROR or ROL function, but for starters, my assembly skills are quite rusty. The last time I used it was on a Motorolla 65C816 25 years ago. LOL. I've only been using C for about a month, so I'm still learning what I can do with it. I have a basic grasp of programming structure, but I'm a novice at best right now with either of these languages.
I know some will recommend multiplexing, and I may consider it, but my display will be RGB, behind a dark lens, so I want as much brightness as possible, and multiplexing will automatically cut my max brightness considerably, so I'm going with the control of the numbers and bar graph being constant, using common cathode, and the brightness and color being controlled through the anode via a separate microcontroller.
Any help on these problems is greatly appreciated. I'm having a lot of fun with this project, but I'm a little stuck and could use some expert guidance.
Here's the goal: I want the circuit to be able to take a number and display it on a 4 digit 7 segment display, while also displaying a representation on a bar graph to show the number on a scale. I've currently got the circuit running the bar graph with 16 RGB LEDS via 2 shift registers, and the color controlled by a separate PIC12F1501 (for reasons related to another project, I want the color controlled on a separate chip).
I've currently got one 7 segment display hooked directly to the PORTC pins of the microcontroller, and PORTB pins hooked to the shift registers. I can set it to count 0-9, and light up 0-9 LEDs corresponding to the count, always on less than should be (for example, when the number 5 is showing on the counter, 4 LEDs are lit on the bar graph). I tried setting the counter to go to 0-15, but no matter what, I can't get the last LED to light. For some reason, my program is clocking in one extra zero at the end even when my count is at the top. I've attached the pertinent code to see if someone can tell me where my error is. I'm sure there is something minor that I'm missing, but it currently eludes me.
Code:
size=16;
scale=size-1;
for (count=0; count<scale; count++)
{
for (i=0; i<scale; i++)
{
if (i<=count)
{
PORTB=0b00010000; //set RB4 high
PORTB=0b00110000; //set RB5 high
PORTB=0b00010000; //set RB5 low
}
else
{
PORTB=0b00000000; //set RB4 low
PORTB=0b00100000; //set RB5 high
PORTB=0b00000000; //set RB5 low
}
}
PORTB=0b01000000; //set RB6 high
PORTB=0b00000000; //set RB6 low
for (wait=0; wait<delay; wait++)
{}
}
RB5 is connected to shift register clock
RB6 is connected to storage register clock
As I said, this is basically working, but it seems to clock in an extra zero even when all LEDs should be on.
My second problem is just simply a knowledge issue: I have my 7 segment array set up so that it will load the byte into PORTC according to the current number in my count. How do I set it up to clock in the bits of a byte in memory to the shift registers? My goal is to have one shift register for each digit, so if the count is at, say 750, it will clock in all zeros for the first digit, then the byte for the 7, then the byte for the 5, then the byte for a zero, then latch the storage register. Do I need to break out my array from a single dimension to a two dimensional, and just put in each bit, or is there a way to rotate the bits out to the storage register from a byte? I'm considering using assembly for this, if the microcontroller has a ROR or ROL function, but for starters, my assembly skills are quite rusty. The last time I used it was on a Motorolla 65C816 25 years ago. LOL. I've only been using C for about a month, so I'm still learning what I can do with it. I have a basic grasp of programming structure, but I'm a novice at best right now with either of these languages.
I know some will recommend multiplexing, and I may consider it, but my display will be RGB, behind a dark lens, so I want as much brightness as possible, and multiplexing will automatically cut my max brightness considerably, so I'm going with the control of the numbers and bar graph being constant, using common cathode, and the brightness and color being controlled through the anode via a separate microcontroller.
Any help on these problems is greatly appreciated. I'm having a lot of fun with this project, but I'm a little stuck and could use some expert guidance.
Last edited: