I am trying to multiplex two seven segment displays, once a switch input is detected.
- If a switch is pressed then the seven segment displays should show
1
- If pressed again,
2
, then3
and so on.
My problem arises when I reach number 9
since the next switch input will show 10
. 1
on the first SSD and 0
on the second SSD. Below is a snippet of my code with regards to how I am detecting inputs from 1 – 9.
int k = 0;
unsigned int SW1;
PINSEL0 = 0; //Set P0.0 - P0.15 as GPIOS
PINSEL1 = 0; //Set P0.16 - P0.31 as GPIOS
IO0DIR = 0xFFFFF9FF; //Setting P0.9 as input for SW1
while (1)
{
SW1 = IO0PIN & 0x00000200; //switch connected on P0.9
if ( SW1 != 0x00000200 ) //when pressed
{
k++;
IO0SET = T1;
IO0SET = T2;
if (k == 1){
IO0SET = T1; //switching on left seven segment display
IO0CLR = T2; //clearing the right seven segment display
IO0CLR = a;
IO0SET = b;
IO0SET = c;
IO0CLR = d;
IO0CLR = g; //displaying number 1
IO0CLR = e;
IO0CLR = f;
small_delay();
}
}
I am following the same structure for the 10th switch press:
else if (k == 10){
IO0CLR = 0x000000FF; //turn off all the segments as well as both common anodes. Then your outputs will be ready for the new segment patterns to be set up.
IO0SET = T2; //switching on first display
IO0SET = b;
IO0SET = c; //displaying number 1
small_delay(); //calling short delay
IO0CLR = 0x000001FF;
IO0SET = a;
IO0SET = b;
IO0SET = c;
IO0SET = d; //displaying number 0
IO0SET = e;
IO0SET = f;
IO0SET = T1;
small_delay();
IO0CLR = 0x000000FF;}
The problem with the second code I provide is that the seven segment display only displays 10
once. That is, first 1
is shown on the left display and then 0
on the second display as required, however this is performed only once and does not go on until the next switch input is detected.
One solution this problem which I have come up with is that I included a while statement after the if else
such that:
else if (k == 10){
while (k == 10) { //rest of code
This actually does what I want it to do, and keeps multiplexing both seven segments, showing number 10
, however the problem in this case is that it does not step out of the while loop to accommodate for the next switch input.
How can I multiplex both displays until the next switch input is detected? Any ideas/suggestions would be greatly appreciated.
Best Answer
Two options:
The correct way to do this would be that your counting code just counts, it doesn't set the display it sets a variable. You then have code running on a timer interrupt that reads the count variable and displays the number. If the number is over 9 then this timer can switch between digits as needed.
The second way is to only set one digit each time through your loop
I've assumed a few functions,
bool buttonPress(void)
which returns tru if the button has been pressed,void setDisplay(int value)
which sets the correct IO pins active to display the given value from 0 to 9 andvoid setDisplayOff(void)
which turns off all the leds.By setting the IO lines in a separate function you keep the big messy switch command (or if...else if...else if...) away from your core logic, this makes the logic a lot easier to follow since it now all fits on the screen at the same time.
Update -
Just in case your dislike of functions and switch commands is due to a lack of familiarity with using them here are the function definitions. These either need to go before main() or you need to declare them in advance and then put the code after main(). I also moved the display select into a function so that all of the IO is out of the main code.
You'd need to fill in the remaining values of the switch but it should be fairly obvious how.