Understanding the C code of Digital clock.

46 posts / 0 new
Author
Message

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.

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.

Moved to general programming.

JIm

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

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

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 https://www.avrfreaks.net/forums/... and take the sticky link https://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.

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.

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

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

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

Jim

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

```
```

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

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?

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

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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]

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

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.)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"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]

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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]

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

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"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]

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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

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

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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

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

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.

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;
}
}```

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"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

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

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

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

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

Attachment(s):

Regards,

Prakash

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...

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Dec 24, 2015 - 10:23 AM

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.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"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]

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...

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

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

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

Regards,

Prakash

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

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.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"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]

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?

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

Or at least a part number.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"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]

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

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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]

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

Regards,

Prakash

Like I said:

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

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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

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.

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." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "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]

I am not going to use DP.

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

Regards,

Prakash

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

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?

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.

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.

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