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.

[PIC] Programming a 2 Digit 7 Segment Led in Embedded C

Status
Not open for further replies.

dexanu

Newbie level 3
Joined
Jul 21, 2015
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
53
Hello guys!
I started to learn programming PICs a couple of days ago using Myke Predko's "123 Microcontroller Experiments for the Evil Genius" and Proteus 8.
I reached an experiment where the author shows how to program a 2 digit 7 segment led, so I decided to do something more challenging for me: to read the value of ADRESH and display it on the 7 segment leds. The problem is that even the code is okay for me and I tried to debug it and it worked fine, when I have a number bigger than 9 both 7 segment leds wil display the same number(e.g. 11,22,33...) instead of the real value of ADRESH.

Here is the code:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <htc.h>
#include <pic.h>
 
__CONFIG( IESODIS & PWRTEN & WDTDIS  & MCLRDIS & BOREN);
 
const char Digit[10]={1,0b1001111,0b0010010,0b0000110,0b1001100,0b0100100,0b0100000,0b0001111,0,4};
 
main(){
   int ADCValue,a,b;
   TRISC=0;
   TRISA=0b00010000; 
   ADCON0=0b1101;
   ADCON1=0b1100000;
   ANSEL=0b1000;
    while(1){
    __delay_us(500);
    GODONE=1;
    while(!GODONE);
    ADCValue=ADRESH>>2; //size down the value
    if(ADCValue<=9){
        RA2=1;
        RA1=0;
        PORTC=Digit[ADCValue%10];
        if(ADCValue==1 || ADCValue==4)
            RA0=1;
        else
            RA0=0;
    }//if1
    if(ADCValue>=10){
        RA2=1;
        RA1=0;
        a=ADCValue%10;
        PORTC=Digit[a];
        if(a==1 || a==4)
            RA0=1;
        else
            RA0=0;
        __delay_ms(30);
        
        RA2=0;
        RA1=1;
        b=ADCValue/10;
        PORTC=Digit[b];
        if(b==1 || b==4)
            RA0=1;
        else
            RA0=0;
        __delay_ms(30);
        
        
    }//if2
        
}//while
}//main


I also attach the circuit diagram.
Any help is appreciated and thank you!

circuit.png
 
Last edited by a moderator:

Add [cοde] [/cοde] tags.
Add some notes

eg. why you test all the time:
Code:
if(x==1 || x==4)
 RA0=1;
 else
 RA0=0;

What is GODONE used for?

You could have names with a meaning,
eg #define RAx=1 LeftDisplayON


Code:
b=ADCValue/10;
Are you sure it will always return value <10?
 

What is GODONE used for?

GODONE is actually a predefined macro provided in some device specific header files of various compilers and refers to the GO/DONE' bit of the ADCON0 register of the ADC module.



BigDog
 
  • Like
Reactions: xenos

    xenos

    Points: 2
    Helpful Answer Positive Rating
One question is, which digit is being displayed in both displays, is it the 1's digit or the 10's digit?
 

GODONE is actually a predefined macro ...
Thanks bigdogguru for the info.

Althow I prefer mcc18/xc8 syntax with bitfields
Code:
ADCON0bits.GO_DONE = 1;
my question was about the wrong usage of this bit:
Code:
    GODONE=1;
    while(!GODONE);
Go/Not DONE is set to 1 to start conversion
and ends with 0 on conversion completion.
The provided code is wrong and has false results.
Should be:
Code:
    GODONE=1;
    while(GODONE)
            ;
    //adc conversion is over
 
my question was about the wrong usage of this bit:
Code:
    GODONE=1;
    while(!GODONE);
Go/Not DONE is set to 1 to start conversion
and ends with 0 on conversion completion.
The provided code is wrong and has false results.
Should be:
Code:
    GODONE=1;
    while(GODONE)
            ;
    //adc conversion is over

Good point!

I only briefly examined the thread, saw you actively participating and you had posted a reply.
 

Sorry guys, I should had explained my code.
If ADRESH is a 2 digit number, I made the code so that it sends on the 2nd 7 segment led the last figure of that number and the first figure on the 1st led; both with a delay for about 10 ms so it could give a visual effect of both being on at the same time
@FenTrac both the 7 segment display the same number; e.g., if ADRESH=78, the number 77 is displayed and if I modify the potentiometer until ADRESH is, lets say, 89, the number displayed is 88.
@xenos you're right, but for experimenting I keep the value of ADRESH between 0 and 99 ( I introduced ADCValue=ADRESH>>2; so I couldbe easily)
And with the condition: the book which I read uses pic16f684, which has only 14 pins, 6 for port C and 6 for port A; all pins for port C I use them for the 7 segment led, but I need one more, so I use RA0, which is connected to "a" led and apart from 1 and 4, the led must be on for the rest of the numbers.
Probably you will say why I don't use another pic; will I want to stay true to the book until I learn at least the basics of the PICs and than I could the stuff more complicated.
 

The problem appears to be with the configuration of PORTA. Refer to "example 4-1 initializing PORT A" in the PIC16F684 datasheet. If PORTA is set to digital, the display seems to work, otherwise it behaves as you described. You will have to read whether this interferes with your analog input on PORTA.
 

Try just adding CMCON0 = 7, in addition to your ANSEL= 0b1000 command;
 

Thx for the suggestions, but I've figured out the problem: the transistors don't work, or at least as it's supposed to work. I'm new to proteus so I dont know if I have to edit some properties for the transistors or I take them as granted. The reason for why the both of the 7 segment leds are displaying the same figures is that both of them are connected to the ground, even if I don't command them( I made new circuits to test everything that I have knowledge of).
So my question is another: you guys ,when making a circuit, are modifying something at the transistor's properties or leave them as they are?
 

I've figured out the problem: the transistors don't work, or at least as it's supposed to work.

What transistors?

There does appear to be any included in the original design you previously posted.

View attachment 119804

Perhaps you should post an updated screen shot of the current design.


BigDog
 

You are right about the 2 displays being connected to ground. I had the same issue when I wired up your circuit and tested it. The reason they are connected to ground is the state of PORTA on power up or reset. It resets to analog and comparator mode. To be able to turn the transistors on and off, the PORTA pins you are using, A1 and A 2, have to be reconfigured to digital mode. To do that takes 2 instructions: CMCON0 = 7, and ANSEL= 0b1000. Your program already has ANSEL = 0b1000, so with the added instruction CMOMO = 7, it the should work as needed. It did with the circuit I tested.
 
  • Like
Reactions: dexanu

    dexanu

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top