Understanding the C code of Digital clock.

Go To Last Post
46 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Friends,

 

I am new to the AVR.However, I made projects like water level controller, Timer  using Atmega 8/16 and AVR studio 6.

 

I am planning to do "ATMega16 AVR Microcontroller Seven Segment Digital Clock".When I googled it, I found  link   http://www.avr-tutorials.com/pro...

 

I was going through the code.I could not understand the some codes like;

SegDataPort = DigitTo7SegEncoder(seconds%10,1);
		SegCntrlPort = ~0x01;

SegDataPort = DigitTo7SegEncoder(seconds/10,1); 

 

 

What is the meaning  of %10 , /10...etc

 

May be till now I was writing very basic codes,  that's why I am unable to understand these new functions.

Can you please send me a link which enables me to understand the code used in the above link.

 

This topic has a solution.

Regards,

Prakash

Last Edited: Tue. Dec 22, 2015 - 10:16 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the meaning  of %10 , /10...etc

In C the '/' symbol is used as the operation for "divide". So "13 / 5" would be 2. Now you may be thinking that 13 / 5 is actually 2.6 but unless you go out of your way to change things it will be done as an integer calculation (no fractional parts) to the result is effectively rounded down to 2.

 

In C the '%' operation is "modulus" and returns the remainder after division so in my example using 13 and 5 the result of "13 % 5" would be 3. That is you can divide 5 into 13 twice and have a remainder of 3.

 

So n/10 and n%10 are the classic way to split digits in a decimal number. Say n=47 then "n / 10" is 4 (remember the fractional part is lost) and "n % 10" is 7 because 10 divides into 47 four times with a remainder of 7.

 

So this has split "47" into '4' and '7' which is what you want when you are displaying each digit individually on a 7 segment display.

 

I would suggest you read up about the arithmetic C operators '+', '-', '*', '/' and '%' in your C manual if you didn't know about these.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Moved to general programming.

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:

Can you please send me a link which enables me to understand the code used in the above link.

 

As mentioned above, this is standard C and has nothing specific to AVRs in it.  Indeed, if you aren't familiar with the syntax then won't you as a question when you see >> on the next line, and || on the next page, and so on?

 

So if you are going to program in C, and/or study C app code, you need some kind of a language reference.

 

If you do not have a book, I'd guess there are many many online tutorials and courses "Learn C in 123 Lessons".  But you can start at the top of the "main" forum http://www.avrfreaks.net/forums/... and take the sticky link http://www.avrfreaks.net/forum/f... "Find/Post your Online C Books & Tools here ..."

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The book Programming in ANSI C  by Stephen Kochan is my go to reference for C. I usually get used copies off Amazon delivered to my door in the US for under $5.00. I have given 3 copies to interns I work with and keep a copy at home and work. "Power Coders" mock me at times when they see the book, but I am not a code monkey, I'm an Embedded Engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some more 'C' learning & reference materials: http://blog.antronics.co.uk/2011...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The C bible is "The C Programming Language by K&R"

 

Jim

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Hi,

 

Thanks for the details.

 

I was going through the program in the below link;

 

http://www.avr-tutorials.com/pro...

 

In the ADD Watch I added hours, minutes, seconds.When the switch is pressed (PORTC Pin 6 and Pin 7) the hours and minutes are increasing.But when I continue to debug  seconds,minutes, hours value is not changing at all....

I tried to put value 15625 in OCR1A in the IO view...But it will never execute  ISR(TIMER1_COMPA_vect) and  seconds,minutes, hours  value is always remain unchanged.

 

Am I doing it right...Or is there is something I have to look into..

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But when I continue to debug  seconds,minutes, hours value is not changing at all....

They are probably cached in registers. The code in your link is not very good. The variables:

/*Global Variables Declarations*/
unsigned char hours = 0;
unsigned char minutes = 0;
unsigned char seconds = 0;

should be:

/*Global Variables Declarations*/
volatile unsigned char hours = 0;
volatile unsigned char minutes = 0;
volatile unsigned char seconds = 0;

If the author did not know that then I wonder what else they may not have known?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

normally the interrupt is called once in a program right?

 

Why in the above program  it is  ISR(TIMER1_COMPA_vect)   called in 2 places.I am unable to understand why the author used it in 2 places.

 

 

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:
Why in the above program  it is  ISR(TIMER1_COMPA_vect)   called in 2 places.I am unable to understand why the author used it in 2 places.
You don't 'call' an ISR.  You simply define it.

 

The author first declares the prototype:

ISR(TIMER1_COMPA_vect);

Then he defines the function:

ISR(TIMER1_COMPA_vect)
{
	seconds++;
 
	if(seconds == 60)
	{
		seconds = 0;
		minutes++;
	}
	if(minutes == 60)
	{
		minutes = 0;
		hours++;		
	}
	if(hours > 23)
		hours = 0;
}

Strictly, ISRs don't require a prototype, so the declaration can be omitted, but there is no harm it having it.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the program when I debug why it is not executing the ISR function, even though I put OCR1A = 15624 in the IO.

 

I am using Atmel Studio 6.1

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't just link to someone elses code. Show us the code you have. Chances are you inadvertently changed something.

 

If the ISR does not fire then it's either because:

 

  • The interrupt isn't enabled, or

 

  • (if you're debugging in the  simulator) there is a bug in the simulator. (In ancient days this was scommon, especially for timer simulation. Not sure about the state of this today. Debugging on real hardware is most often to prefer, and nowadays it's not even expensive...)

 

(Apart from that I have several things to say about the code you linked to, but I'll refrain. At least until we've got your problems settled.)

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In order for an interrupt to occur, a compare match must occur 'naturally'. That means the timer's TCNT1 register must count up to match the value in OCR1A. Writing to OCR1A won't trigger a compare match. Neither will writing to TCNT1. If you want, you can write TCNT1 to the vale of OCR1A less 2, and wait for the compare match to occur naturally.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good catch, Joey! (Your pre-christmas week seems full of bulls-eyes).

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

Good catch, Joey! (Your pre-christmas week seems full of bulls-eyes).

Yes, it's a Saturnalia miracle.
I'm thinking monkeys, typewriters, Shakespeare, and the law of averages ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Tue. Dec 22, 2015 - 07:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
In order for an interrupt to occur, a compare match must occur 'naturally'.

I had an old girl friend that my friends claimed was an unnatural match, but I guess that is different.

 

At the risk of confusing OP, I was going to mention FOCn bit, for an unnatural match.  But indeed, joey, that will not force the interrupt -- your streak continues.  (I always wondered about that -- is the feature then to be able to put the output pin into a desired state when e.g. starting or stopping CTC?  Or a way to do "bit-banged CTC"?  Or a way to toggle output pin before there were writes to PINx to toggle?  Does the timer even need to be running for the FOCn action to take place?)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. Dec 22, 2015 - 08:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
joeymorin wrote:

In order for an interrupt to occur, a compare match must occur 'naturally'.

I had an old girl friend that my friends claimed was an unnatural match, but I guess that is different.

Do tell :)
theusch wrote:
At the risk of confusing OP, I was going to mention FOCn bit, for an unnatural match.  But indeed, joey, that will not force the interrupt -- your streak continues.
OK now I'm feeling pressure :)

theusch wrote:
(I always wondered about that -- is the feature then to be able to put the output pin into a desired state when e.g. starting or stopping CTC?  Or a way to do "bit-banged CTC"?  Or a way to toggle output pin before there were writes to PINx to toggle?  Does the timer even need to be running for the FOCn action to take place?)

Yes on all counts, except that the timer doesn't need to be running.

 

One use for them:

  • set the compare match mode to set or clear the output as desired
  • strobe the FOCxn bit to force the output to that state
  • then change to your 'running' compare mode (probably toggle)
  • start the timer.

This lets you preconfigure the OCnx pins on one or more timers to a known state, configure the timers to run as desired, and then start them.

 

BTW, these FOCnx bits work only for non-PWM.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Dec 23, 2015 - 06:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I wrote the code for digital clock as below using ATMEGA16.I also attached circuit diagram.I am using 6nos. 4inch common cathode 7 segment display(Supply voltage 12volt).I not yet tested it in the hardware.It works fine  when I compile in Atmel Studio 6.1.Please give your comments.

 

 
#define F_CPU    4000000UL
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 

volatile unsigned char hours = 0;
volatile unsigned char minutes = 0;
volatile unsigned char seconds = 0;
 

unsigned char DigitTo7SegEncoder(unsigned char digit, unsigned char common);
 

int main(void)
{
    DDRB = 0xFF;
    DDRC = 0x3F;
    PORTC = 0xFF;
 
    TCCR1B = (1<<CS12|1<<WGM12);
    OCR1A = 15625-1;
    TIMSK = 1<<OCIE1A;
    sei();
 
 
    while(1)
    {
        /* Set Minutes when PORTC Pin 6 Switch is Pressed*/
        if((PINC & 0x40) == 0 )
        {    
            _delay_ms(200);
            if(minutes < 59)
                minutes++;
            else
                minutes = 0;
        }
        /* Set Hours when PORTC Pin 7 Switch is Pressed*/            
        if((PINC & 0x80) == 0 )
        {    
            _delay_ms(200);
            if(hours < 23)
                hours++;
            else
                hours = 0;
        }            
 
        PORTB = DigitTo7SegEncoder(seconds%10,1);
        PORTC = ~0x01;
        PORTB = DigitTo7SegEncoder(seconds/10,1); 
        PORTC = ~0x02;
        PORTB = DigitTo7SegEncoder(minutes%10,1);
        PORTC = ~0x04;
        PORTB = DigitTo7SegEncoder(minutes/10,1); 
        PORTC = ~0x08;
        PORTB = DigitTo7SegEncoder(hours%10,1); 
        PORTC = ~0x10;
        PORTB = DigitTo7SegEncoder(hours/10,1);
        PORTC = ~0x20;
 
    }
    return 0;
}
 

unsigned char DigitTo7SegEncoder(unsigned char digit, unsigned char common)
{
    unsigned char SegVal;
 
    switch(digit)    
    {    
        case 0:    if(common == 1)    SegVal = 0b00111111;
                else            SegVal = ~0b00111111;
                break;
        case 1:    if(common == 1)    SegVal = 0b00000110;
                else            SegVal = ~0b00000110;
                break;
        case 2:    if(common == 1)    SegVal = 0b01011011;
                else            SegVal = ~0b01011011;
                break;
        case 3:    if(common == 1)    SegVal = 0b01001111;
                else            SegVal = ~0b01001111;
                break;
        case 4:    if(common == 1)    SegVal = 0b01100110;
                else            SegVal = ~0b01100110;
                break;
        case 5:    if(common == 1)    SegVal = 0b01101101;
                else            SegVal = ~0b01101101;
                break;
        case 6:    if(common == 1)    SegVal = 0b01111101;
                else            SegVal = ~0b01111101;
                break;
        case 7:    if(common == 1)    SegVal = 0b00000111;
                else            SegVal = ~0b00000111;
                break;
        case 8:    if(common == 1)    SegVal = 0b01111111;
                else            SegVal = ~0b01111111;
                break;
        case 9:    if(common == 1)    SegVal = 0b01101111;
                else            SegVal = ~0b01101111;        
    }        
    return SegVal;
}
 

ISR(TIMER1_COMPA_vect)
{
    seconds++;
 
    if(seconds == 60)
    {
        seconds = 0;
        minutes++;
    }
    if(minutes == 60)
    {
        minutes = 0;
        hours++;        
    }
    if(hours > 23)
        hours = 0;
}

 

Attachment(s): 

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A uln2003 has 16pins , i think you meant a uln2803. There's no resistors for your led displays. No crystal - your clock won't be too accurate.

I have a feeling of deju-vu. This stuff was discussed recently and code posted.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:
Please give your comments.

The DigitTo7SegEncoder is

  1. un-necessary clumpsy,
  2. has redundant literal constants, and
  3. has a badly named parameter: The parameter governs "common anode" v/s "common cathode" but it actually a false/true value, and for the true case it's "common cathode". It is customary to name such parameter/variables after their true case.

 

Re the clumpsiness, a lookup-table seems a lot more handy.

 

Re the redundancy, every binary literal is named twice. Redundancy in code is a bad habit, a source of countless bugs, and should be avoided at almost all costs. Every time you see something stated twice in your code you should react, and ponder what to do to get rid of  this doubly stated thing. In the current case it is easy. First determine the segment values. Then, if it's common cathode negate that established value.

 

Taking care of all those in one go, here's my suggestion (not tested):

 

 unsigned char segmentValues[] = {
    //-GFEDCBA
    0b00111111,
    0b00000110,
    0b01011011,
    0b01001111,
    0b01100110,
    0b01101101,
    0b01111101,
    0b00000111,
    0b01111111,
    0b01101111
};

unsigned char DigitTo7SegmentEncoder(unsigned char digit, unsigned char commonCathode)
{
    unsigned char SegmentValue = segmentValues[digit];

    if (commonCathode) {
        SegmentValue = ~SegmentValue;
    }

    return SegmentValue;
}

Re the ISR:

 

When incrementing variables with carry I dislike to test for equalness. In the ISR you do this for seconds and minutes, but surprisingly not for hours where an inequality test is actually used. I would prefer the inequality to be used in all three cases.

 

I would also not reset to zero, but subtract the exact amount of seconds that was carried over to minutes. In your current code this might not make any difference, but getting into that habit will possibly have you avoid nasty bugs in the future.

 

I dislike the mixing of how you give the "wrap values": 60 secs, 60 minutes but 23 hours rather than 24. This is no bug but makes the code inconsistent for any reader. Use the same principle all the way - either 59/59/23 or 60/60/24. The  latter seems more natural for me.

 

Finally, be consistent with "gullwing bracketing". My recommendation is to use it always for if's and while's. Good habit for avoiding spurious bugs in the future. (You are free to dislike how I place those gullwings, but note that I'm consistent with it.)

 

Here's my suggestion, again untested:

 

ISR(TIMER1_COMPA_vect)
{
	seconds++;

	if(seconds >= 60) {
		seconds -= 60;
		minutes++;
	}

	if(minutes >= 60) {
		minutes -= 60;
		hours++;
	}

	if(hours >= 24) {
		hours -= 24;
	}
}

 

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Wed. Dec 23, 2015 - 01:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
 a lookup-table seems a lot more handy.

Indeed: http://www.8052.com/forum/read/5...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the comments.

 

I modified the program from your suggestions.

 

But,I get below errors/Warnings while compiling in Atmel Studio 6.1.Sorry if i am asking some very simple questions.I tried to google it but could not fix it.

 

Warning    1    #warning "This file has been moved to <util/delay.h>." [-Wcpp]    
Warning    2    unused variable 'segmentValues' [-Wunused-variable]    
Error         3    'segmentValues' undeclared (first use in this function)   
Warning    4    each undeclared identifier is reported only once for each function it appears in    

 

 

 

 

#define F_CPU    4000000UL
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char hours = 0;
volatile unsigned char minutes = 0;
volatile unsigned char seconds = 0;

unsigned char DigitTo7SegEncoder(unsigned char digit, unsigned char commonCathode);

int main(void)
{
    DDRB = 0xFF;
    DDRC = 0x3F;
    PORTC = 0xFF;
    unsigned char segmentValues[] = {0x3F,0x06,0x5B,0X4F,0X66,0x6D,0x7D,0x07,0x7F,0x6F};
    TCCR1B = (1<<CS12|1<<WGM12);
    OCR1A = 15625-1;
    TIMSK = 1<<OCIE1A;
    sei();
    
    
    while(1)
    {
        /* Set Minutes when PORTC Pin 6 Switch is Pressed*/
        if((PINC & 0x40) == 0 )
        {
            _delay_ms(200);
            if(minutes < 59)
            minutes++;
            else
            minutes = 0;
        }
        /* Set Hours when PORTC Pin 7 Switch is Pressed*/
        if((PINC & 0x80) == 0 )
        {
            _delay_ms(200);
            if(hours < 23)
            hours++;
            else
            hours = 0;
        }
        
        PORTB = DigitTo7SegEncoder(seconds%10,1);
        PORTC = ~0x01;
        PORTB = DigitTo7SegEncoder(seconds/10,1);
        PORTC = ~0x02;
        PORTB = DigitTo7SegEncoder(minutes%10,1);
        PORTC = ~0x04;
        PORTB = DigitTo7SegEncoder(minutes/10,1);
        PORTC = ~0x08;
        PORTB = DigitTo7SegEncoder(hours%10,1);
        PORTC = ~0x10;
        PORTB = DigitTo7SegEncoder(hours/10,1);
        PORTC = ~0x20;
        
    }
    return 0;
}

unsigned char DigitTo7SegmentEncoder(unsigned char digit, unsigned char commonCathode)
{
    unsigned char SegmentValue = segmentValues[digit];

    if (commonCathode) {
        SegmentValue = ~SegmentValue;
    }

    return SegmentValue;
}

ISR(TIMER1_COMPA_vect)
{
    seconds++;

    if(seconds >= 60) {
        seconds -= 60;
        minutes++;
    }

    if(minutes >= 60) {
        minutes -= 60;
        hours++;
    }

    if(hours >= 24) {
        hours -= 24;
    }
}

 

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I incorporated the resistors in the circuit.Let me know whether I chosen the right value of resistance

Attachment(s): 

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:
I get below errors/Warnings while compiling in Atmel Studio 6.1.Sorry if i am asking some very simple questions.I tried to google it but could not fix it.

Google will not magically "fix" anything - it will help you find information, but it is up to you to think about that information, and apply it

 

The messages you posted are really quite clear and explicit - just read them, and think what they are telling you:

 

Warning    1    #warning "This file has been moved to <util/delay.h>." [-Wcpp]    

The complete message would tell you which file this refers to, and where it was referenced - just take note of what it's saying, and update your project accordingly to specify the new place.

Warning    2    unused variable 'segmentValues' [-Wunused-variable]    

Again,  the complete message would tell you where, exactly, the unused declaration appears - so look at it, and think why it is not used.

 

Error         3    'segmentValues' undeclared (first use in this function)   

And again, the complete message would tell you where, exactly, 'segmentValues'  appears to be undeclared - so, again, look at it, and think why the compiler sees no declaration at that point.

 

Hint: do you understand the concept of scope in a block-structured language such as 'C' ... ?

(if you don't, then look it up in your 'C' textbook).

 

Another Hint: You have a Warning that  'segmentValues' is unused in one place, and an Error that it is undefclared in another place - don't you think the to might be related ... ?

 

Warning    4    each undeclared identifier is reported only once for each function it appears in    

Just informs you that the compiler is not going to list each and every subsequent use of  'segmentValues'

 

Note that the errors listed in the 'Problems' window in AS are "processed" by the IDE and can sometimes lose some context - so it may help to look at the actual compiler output in the 'Console' windows...

 

 

Last Edited: Thu. Dec 24, 2015 - 10:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:
Warning 2 unused variable 'segmentValues' [-Wunused-variable]

Error 3 'segmentValues' undeclared (first use in this function)

Variables local to a function can not be seen in other functions. The segmentValues variable local to main() is not used anywhere in main(). Thus the first (warning) message.

 

Since variables local to a function can not be seen in other functions the segmentValues variable local to main() can not be seen in DigitTo7SegmentEncoder(). In the second (error) message the compiler finds attempted usage of a variable segmentValues that it can not see within the current scope, and reports that there is no such variable.

 

I did not suggest that segmentValues wshould be local to main. Place it a file scope (outside any function, e.g. just before DigitTo7SegmentEncoder() ), just as I did.

 

I agree with awneil - it is time for you to pick up a good text on the C programming language and read it.

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
 it is time for you to pick up a good text on the C programming language and read it.

Here are some 'C' learning & reference resources - including a free online textbook: http://blog.antronics.co.uk/2011...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do we know what the resistance should be? We have no idea of what led display you are using.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using 4 inch 12volt common cathode 7 segment display

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

I placed the segmentValues just before the DigitTo7SegmentEncoder(), but i get below error after compiling,

 

Error    1    undefined reference to `DigitTo7SegEncoder'    C:\D\prakash\microcontroller\Clock\GccApplication5\GccApplication5\Debug/.././GccApplication5.c    42    1    GccApplication5
Error    2    undefined reference to `DigitTo7SegEncoder'    C:\D\prakash\microcontroller\Clock\GccApplication5\GccApplication5\Debug/.././GccApplication5.c    44    1    GccApplication5
Error    3    undefined reference to `DigitTo7SegEncoder'    C:\D\prakash\microcontroller\Clock\GccApplication5\GccApplication5\Debug/.././GccApplication5.c    46    1    GccApplication5
Error    4    undefined reference to `DigitTo7SegEncoder'    C:\D\prakash\microcontroller\Clock\GccApplication5\GccApplication5\Debug/.././GccApplication5.c    48    1    GccApplication5
Error    5    undefined reference to `DigitTo7SegEncoder'    C:\D\prakash\microcontroller\Clock\GccApplication5\GccApplication5\Debug/.././GccApplication5.c    50    1    GccApplication5
Error    6    ld returned 1 exit status    collect2.exe    0    0    GccApplication5

 

 

 

 

 

#define F_CPU    4000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char hours = 0;
volatile unsigned char minutes = 0;
volatile unsigned char seconds = 0;
unsigned char DigitTo7SegEncoder(unsigned char digit, unsigned char commonCathode);
int main(void)
{
    DDRB = 0xFF;
    DDRC = 0x3F;
    PORTC = 0xFF;
    TCCR1B = (1<<CS12|1<<WGM12);
    OCR1A = 15625-1;
    TIMSK = 1<<OCIE1A;
    sei();
    
    
    while(1)
    {
        /* Set Minutes when PORTC Pin 6 Switch is Pressed*/
        if((PINC & 0x40) == 0 )
        {
            _delay_ms(200);
            if(minutes < 59)
            minutes++;
            else
            minutes = 0;
        }
        /* Set Hours when PORTC Pin 7 Switch is Pressed*/
        if((PINC & 0x80) == 0 )
        {
            _delay_ms(200);
            if(hours < 23)
            hours++;
            else
            hours = 0;
        }
        
        PORTB = DigitTo7SegEncoder(seconds%10,1);
        PORTC = ~0x01;
        PORTB = DigitTo7SegEncoder(seconds/10,1);
        PORTC = ~0x02;
        PORTB = DigitTo7SegEncoder(minutes%10,1);
        PORTC = ~0x04;
        PORTB = DigitTo7SegEncoder(minutes/10,1);
        PORTC = ~0x08;
        PORTB = DigitTo7SegEncoder(hours%10,1);
        PORTC = ~0x10;
        PORTB = DigitTo7SegEncoder(hours/10,1);
        PORTC = ~0x20;
        
    }
    return 0;
}

unsigned char segmentValues[] = {0x3F,0x06,0x5B,0X4F,0X66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char DigitTo7SegmentEncoder(unsigned char digit, unsigned char commonCathode)
{
    unsigned char SegmentValue = segmentValues[digit];
    if (commonCathode) {
        SegmentValue = ~SegmentValue;
    }
    return SegmentValue;
}
ISR(TIMER1_COMPA_vect)
{
    seconds++;
    if(seconds >= 60) {
        seconds -= 60;
        minutes++;
    }
    if(minutes >= 60) {
        minutes -= 60;
        hours++;
    }
    if(hours >= 24) {
        hours -= 24;
    }
}

 

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:
I placed the segmentValues just before the DigitTo7SegmentEncoder(), but i get below error after compiling, Error 1 undefined reference to `DigitTo7SegEncoder' C:\D\prakash\microcontroller\Clock\GccApplication5\GccApplication5\Debug/.././GccApplication5.c 42 1 GccApplication5

Because you call it before you define it.

 

Either put a prototype somewhere before the call, or move the whole definition up to before the function(s) that call it.

 

The second quote in my sig is beginning to apply now.

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

prakash_kadri wrote:
I am using 4 inch 12volt common cathode 7 segment display

 

That tells us very little. Do you have a data sheet for the said display?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Do you have a data sheet for the said display?

Or at least a part number.

 

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

7 segment LED display Specifications as below.

Please let me know how you arrive at the particular resistance value, so that it will be useful for me in the future.

 

 

Specifications
Display

  Digit Size: 4.0"

  Material: GaAlAs/GaAs

  Emitted Color: Hi-Red

  Dominant Wavelength: 660 nm

Absolute Maximum Ratings

  Reverse Voltage(Vr): 5 V

  Reverse Leakage Current (Ir): 20 µA

  Forward Current (If): 25 mA

  Peak Forward Current (Ifp): 150 mA

  Power Dissipation (P): 60 mW per Segment

  Operating Temperature (Topr): -40°C to +80°C

  Storage Temperature (Ttsg): -40°C to +85°C

  Lead Soldering Temperature : 260°C

Electro-Optical Data (@20mA)

  Forward Voltage - Typical: 9.25V

  Forward Voltage - Maximum: 11.00V

  Luminous Intensity - Minimum per Segment: 288.0 mcd

  Luminous Intensity - Typical per Segment: 432.0 mcd

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Many of the specifications are self-contradictory:

Absolute Maximum Ratings

  Reverse Voltage(Vr): 5 V

Electro-Optical Data (@20mA)

  Forward Voltage - Typical: 9.25V

  Forward Voltage - Maximum: 11.00V

 

This suggests that each 'segment' is perhaps more than one LED in series.

 

Just tell us the part number, or provide a link to the datasheet.  Clearly, you have it since you were able to partially quote the specs above.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I could able to fix the error.

 

I issue was spell mistake.In one place I was referring as DigitTo7SegmentEncoder() and in another place I was referring it as DigitTo7SegEncoder(). 

Also, I changed the line as, if (commonCathode==0) {
        SegmentValue = ~SegmentValue;

 

I tested the program in 1 inch display it is working fine(Photo attached), but  the segments which is supposed to be OFF is glowing lightly.May be, the driver circuit will eliminate this issue.

However, I  am trying to use  4 inch 7 segment display...

Attachment(s): 

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Like I said:

joeymorin wrote:
This suggests that each 'segment' is perhaps more than one LED in series.

 

7-Segment LED Display Circuit Diagram

 

So there are in fact 5 LEDs in series for each of the 7 segments.

 

So, the typical forward voltage for one segment (all 5 of its LEDs in series) is 9.25V.  This rating is at 20 mA.  You calculate the resistors like this:

 

R = (VDRIVE - VF) / I

  = (12 - 9.25) / 0.02

  = 2.75 / 0.02

  = 137.5 ohms

 

The nearest higher common resistor value is 150 ohms.

 

The DP is a single LED, and the resistor for it must be calculated separately.  Assuming they are the same type of LED:

 

R = (VDRIVE - VF) / I

  = (12 - (9.25 / 5)) / 0.02

  = (12 - 1.85) / 0.02

  = 10.15 / 0.02

  = 507.5 ohms

 

The nearest higher common resistor value is 510 ohms.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Dec 27, 2015 - 05:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Those calcs are good for a static display, but will be rather dim when multiplexing. You're running a 4:1 multiplex, so divide the values by 4.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, they'll be dimmer, but the difference in perceived brightness for 5 mA average vs. 20 mA average won't be that much.  The risk of using a 20 mA average for a 4:1 is that if anything ever goes wrong with the multiplexing and the scan cycle halts, you'll be driving one of of the digits at 80 mA.  They're absolute maximum is 25 mA.

 

If this is a learning project, I'd err on the side of caution until I was certain that the hardware and code were stable.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not going to use DP.

 

R=150 Ohm should I use on either side of ULN and UDN IC?

Regards,

Prakash

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Segment side. Ie: one resistor per segment (7 in total)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i used atmega16a to create 7 segment led digital clock as mentioned below.

http://www.avr-tutorials.com/pro...

Everything is okay but it is working very slow. the seconds are incrementing in only 5 secs once. F_CPU is defined to 4000000UL. But clock is working slow. Why?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From your link:

Important Note: In order for our digital clock to work correctly the internal oscillator of the ATMega16 AVR microcontroller must be enabled and set to 4MHz.
 

Hint.   Read about clock fuses.   Think before you change them.

 

If you ever have "timing" problems,   do careful measurement e.g. with your wristwatch.   How long does it actually take to display 10 minutes.   (or 60 seconds)

 

David.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mahesh4u wrote:
the seconds are incrementing in only 5 secs once. F_CPU is defined to 4000000UL.

Yup, its DEFINED

 

mahesh4u wrote:
But clock is working slow. Why?

 

Is your M16 brand new out of the Tube?  Is it running on the internal RC clock with the DIV8 fuse programmed, or is it running on an external source with the DIV8 fuse programmed?

 

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
with the DIV8 fuse programmed?
Just to note that mega16 do not have DIV8 fuse (they are "old school" and have the four separate intRC oscillators at 1, 2, 4, and 8 MHz).

Last Edited: Mon. Aug 21, 2017 - 08:24 AM