Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Counter 0 tp 99 with PIC16F84A and 7 segment display 2 Digit common cathode and decoder 74LS48

Status
Not open for further replies.

MSeghir

Newbie
Joined
Apr 27, 2022
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
41
Hello everyone ..
If I want to make a counter from 0 to 99 with the following code, how can I make a function to do that in proteus??.. Note that I am a beginner in PIC..Thank you
For your information, the following code works as a counter from 0 to 9 only..
Software used:
- Proteus 8.5 Pro
- MikroC
Elements: The diagram is complete:
- Segment Cathode Display
- PIC 16F84A
- Decodeur 74LS48
The code :
C++:
void main() {
 trisa= 0x00; porta=0;
 trisb= 0x00; portb=0;
     for(;;){
            porta=0b00000010;
            portb=0;
            delay_ms(200);
            porta=0b00000010;
            portb=1;
            delay_ms(200);
            porta=0b00000010;
            portb=2;
            delay_ms(200);
            porta=0b00000010;
            portb=3;
            delay_ms(200);
            porta=0b00000010;
            portb=4;
            delay_ms(200);
            porta=0b00000010;
            portb=5;
            delay_ms(200);
            porta=0b00000010;
            portb=6;
            delay_ms(200);
            porta=0b00000010;
            portb=7;
            delay_ms(200);
            porta=0b00000010;
            portb=8;
            delay_ms(200);
            porta=0b00000010;
            portb=9;
            delay_ms(200);
          }
}

The diagram is complete:
1651101142929.png
 

There are parts out there that have not only cpu but a fabric onboard to do
more capable and minimalist solutions,. Here is a case using Verilog on
an arm part to effect the decode -

1651107993542.png



This is single chip, and many resources still unused left for other tasks.



Regards, Dana.
 
@MSeghir - I realise that this is probably test code but the value inn PORTA will not change after you assign to it. Therefore all but the first 'PORTA = 0b00000010;' statements are useless, and you should probably make that assignment outside the 'for' loop.
However your problem description is not very good. What we need to know is what are you seeing when you run that code?
I don't know that simulator but what are you expecting to see, and does the simulator need all of the power, oscillator and \MCLR\ lines set to some appropriate value etc.?
Susan
 
@MSeghir - I realise that this is probably test code but the value inn PORTA will not change after you assign to it. Therefore all but the first 'PORTA = 0b00000010;' statements are useless, and you should probably make that assignment outside the 'for' loop.
However your problem description is not very good. What we need to know is what are you seeing when you run that code?
I don't know that simulator but what are you expecting to see, and does the simulator need all of the power, oscillator and \MCLR\ lines set to some appropriate value etc.?
Susan
The problem is how do I modify the code to have a counter that counts from 0 to 99 and returns the result in 7 segment 2 digit?

And when running the simulation in this case we get a counter from 0 to 9..
 

OK - so there is nothing 'wrong' with your code or your schematic in that you are getting the display to show exactly what your code says it should.
Therefore your problem is how to get it to display 2 digits (apparently) at the same time.
The display will only show 1 of the 2 digits at a time. Therefore you need to know a few things about how to make the display appear to show 2 digits at the same time. For this you need to understand the persistence of the human eye. This is the same thing that allows us to look at movies and TV to see motion where what is really being shown is a series of still images.
The persistence is approximately 1/16th of a second. Therefore you need to find a way to switch between the two digits faster than this. That way the eye will hold the image of one digit while the other one is being shown, and vice versa.
TVs (at least where I live) show a half image every 1/50th of a second and Movies generally show an image every 1/24th of a second.
What you need to do therefore is workout a way of:
- holding the value to be displayed in each digit in a separate variable
- have a function called every (say) 20ms that displays alternate digits (one digit on the first call, the other on the next call, the first one on the call after that.....)
- understand how to update those variables reliably as required (hint: you may need to look at the 'volatile' attribute)
How you do that is part of your design. If you are doing nothing else (as in your test program) then you can use delays or timers that are checked in the main loop. If your code ultimately just needs to display the values while something else goes on then you probably need to look at timers and interrupts.
Susan
 

Hi,

Since this is a school project .. the challange is to find solutions on your own.
This usually starts with defining the requirements (in your case: devices to be used, LED current (limits), counter frequency range, compiler, language ...)
The next step is to divide the whole task into smaller tasks (display task, counter task ....)
The next step is to find ways to fulfill the equirements for the smaller tasks. One by one. Nowadays: internet search for similar projects.
(You will find many thousands of "counter" software examples, and many thousands of 7 segment display examples....)
Reading through these examples may give you new informations like the "multiplexing of the digits"...with all necessary informations about "why" and "how"
Then ... build hardware
Then .. write the first piece of software, and test it thoroughly ... then the next piece.. and test ... then combine them .. and test

I write this, because your post don't tell what you did so far, which internet pages you read, which part is clear for you, which part is not clear.

Thus it seems (we can't be sure if it is the case) that you just want us to do your job.
We will be more motivated to help you if you show us your effort..

Klaus
 
Hi,

I´d say:
* use a counter variable
* or two: one for digit0 and one for digit1

Klaus
 

Hi,

Since this is a school project .. the challange is to find solutions on your own.
This usually starts with defining the requirements (in your case: devices to be used, LED current (limits), counter frequency range, compiler, language ...)
The next step is to divide the whole task into smaller tasks (display task, counter task ....)
The next step is to find ways to fulfill the equirements for the smaller tasks. One by one. Nowadays: internet search for similar projects.
(You will find many thousands of "counter" software examples, and many thousands of 7 segment display examples....)
Reading through these examples may give you new informations like the "multiplexing of the digits"...with all necessary informations about "why" and "how"
Then ... build hardware
Then .. write the first piece of software, and test it thoroughly ... then the next piece.. and test ... then combine them .. and test

I write this, because your post don't tell what you did so far, which internet pages you read, which part is clear for you, which part is not clear.

Thus it seems (we can't be sure if it is the case) that you just want us to do your job.
We will be more motivated to help you if you show us your effort..

Klaus
thank you all
I tried to run 2 segments together to do the counting but it didn't work.
Edited the code again :
C++:
unsigned short i,j,d_1,d_2;
void setup() {
    // set both ports to output
    trisa = 0;
    trisb = 0;
    // clear both ports
    porta = 0;
    portb = 0;

}

void main() {
    setup();

    i = 0;
     j = 0;

    // pick a digit
    d_1 = 1;
    d_2 = 0;

    // try to loop through every segment
    while(1) {
        portb = i;

        i++;
        if (i > 10){
            i = 0;
        }
        delay_ms(250);
    }
}
 

Hi,

J is never used
d_1 is never used
d_2 is never used

What do you mean with
I tried to run 2 segments together to do the counting but it didn't work.
A "segment" is one LED in one digit.

***
So what do you expect?
And what is not like expected?

Klaus
 

Hi,

J is never used
d_1 is never used
d_2 is never used

What do you mean with

A "segment" is one LED in one digit.

***
So what do you expect?
And what is not like expected?

Klaus
I expect it to display in both digit but neither the result says something else + I don't know how to use both d1 and d2 ??

Seghir
 

Hi,

let´s say d_1 is the value for the right digit and D2 the value for the left digit.

Without programming:
Write a table with two columns. One column is d_2, the other is d_1
Now each line should represent a single loop run.

please draw the first 12 lines of the table.

Klaus
 
We are trying to show you the principle rather than the solution so you can learn how it is done.

Think of it this way:
You have two digit LEDs and bits 0 and 1 of PORTA decide which is lit up.
You have four bits 0,1,2 & 3 of PORTB that decide what number will be shown on the lit digit.
You need to count two numbers to go from 00 to 99, that will fit in a single 8-bit variable.

So you have to use PORTA to turn on the first LED at the same time as PORTB sends the number to show on it and then use PORTA to turn off the first digit and turn on the second digit while PORTB sends the number to show on it. You repeat the process.

Switching between the LEDs quickly enough and sending the number to show on each digit as it is enabled will make it look as though both digits are lit at the same time.

For working out what number to show, increment a single 8-bit variable and send either the low 4-bits or the high 4-bits to PORTB. Note that incrementing a variable will count in binary so you have to 'carry' after 9 in software to the high 4-bits and set the low bits to zero or else strange segment patterns will show.

Brian.
 
Hi,

The video in post#9 is a classical software test situation.
The software is faulty.
I think there is no programmer that makes no mistakes.

Thus the software test is a very important part in writing software.
But testing means to compare "expectation" with the "software output".
Thus it's so important to define the "expectation". This needs to be focussed on one item...and it needs to be complete.
Our brain is not optimized for this, thus it's hard work. One likes to avoid it.

The given task is to count from 0 ... 99 (note 1).
But one has two digits. Thus one has to divide the 0..99 task into the "one digit task". Let's focus on the right digit.

So how should the right digit look like.
One may say: it should show this: 0_1_2_3_4_5_7_8_9 (note 2). It looks like a simple task. One does this every day. No need for testing.
But indeed this is not complete. It misses one important point: What does happen after the "9"?
After the "9" there needs to follow the "0" (note 3)

Back to the video:
* focus on one item: the right digit
* use your expectation...best when written on a sheet of paper.
* check first condition "0" --> correct. Checked
* 1, 2, 3 ...9 ... all correct (see note 2)
* but don't forget to go on. After the "9" there needs to follow the "0" (see note 3). --> but there is a "c" in the video. Not correct. Fail.

Here is where the human brain is not good. It sees what it expects to see while it tends to ignore the rest.
This it's likely to ignore the "c" in the display.

An example: "Tihs is a smaple snetecne to tset yuor brian's abiltiy to corrcet mitskaes!"
Or "sample" vs "sarnple",
or "TEST" vs "TE5T".

One needs to learn not to focus on a whole task ... but on each detail.
Btw: did you notice the missing "6" at note 2? ;-)

... and maybe now find out that the "task of post#1" misses some informations:
* how fast does it has to count (frequency)
* what happens after "99" (restart with 0, stop, ring a bell, ...)
* does it need to display "00" or " 0"

Back to software testing.
As soon as you find a mistake ... you may stop further testing. Review your code. Correct it and start the test anew.

After the right digit focus on the left digit.
What does it need to do?
Indeed not much different to the right digit.
0, 1, ...9, 0, 1...
But it should only increment when the right digit switches from 9 to 0 --> thus it's rather clear "where" in the code you need to add the command for incrementation...

But how to test it? Since you are not able yet to display two different digits at the same time...
My recommendation: do it "instead of the right digit" (since you already know that this works).
So the expectation is: 0-0-0-0-0-0-0-0-0-0-1-1-1-1-....9-9-9-0-0-0-....

At least this is my way. Every one may have his/her own way...
And: I don't think that I am perfect. I'm far from perfect. I guess there are a lot of mistakes in this post... sdaly ;-)

Klaus
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top