C Programming an AVR (ATmega328P) to control single seven segment display

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

I'm trying to write a program to output a count on a 7-seg display from zero to nine with a one second delay (1000ms) between each increment.  When the count reaches nine it must loop around to zero again and keep going.

I need to use #defines to make the code readable and sell-documenting.

Can you please help me with the code or point me to a tutorial?  Thanks!

Last Edited: Sat. Sep 30, 2017 - 10:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The way it works here is that you show what you have done first, both hardware and software wise and then people will help.

 

There should be lots of examples on the net but if you fail to find anything you could start with AVR242 application note to get some ideas from.

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Greetings and welcome to AVR Freaks -

 

One of the things that folks emphasize on this board is that, in order to help you, we really need to know something concrete about what you have already done. Do you have something that you have tried? If it does not work (operating assumption here since you probably would not post if it does work), what does it NOT do that it should and what does it DO that it should not.

 

When you post, use the code button "<>" in the editor tool bar. That will give you easier to read (in this forum) code.

 

If you don't have anything yet, then write down a step-by step sequence of operations that it should use to accomplish your task, and show is what you wrote. Your description, above, does NOT do that. It sounds much more like what one would get for a class assignment. If that is the case, we WILL NOT do your class work for you! Help, yes, but nobody will intentionally provide a complete solution.

 

Best wishes

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sat. Sep 30, 2017 - 10:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I googled avr seven segment
First hit was this:
https://www.kanda.com/7segment.php

There was more.
Simple rule: google first, ask questions later. Reason being that your question has probably been asked a zillion times before - especially if it is schoolwork.

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

Thanks for the advice and welcome guys. 

 

Here is my code so far:

#include <avr/io.h>
#include <util/delay.h>


int main(void)
{
    // initialize digital pins 0-7 as outputs
    DDRD = 0xFF; //0b11111111

    // infinite loop
    while(1){

    PORTD = 0x3F;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x06;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x5B;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x4F;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x66;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x6D;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x7D;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x07;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x7F;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);

    PORTD = 0x6F;
    _delay_ms(1000);
    PORTD = 0x00;
    _delay_ms(1000);
    }
}


It works, but as I mentioned I need to use #defines - I'm not sure how best to modify the code to accomodate that.

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

I need to use #defines

Why? You could define display_clear as 0x00 and then use  PORTD = display_clear; the same could be done for other numbers.

 

But there are many ways of doing what you are doing like putting all the data for the numbers in an array and then read them out in sequence with just a single delay statement.

 

Or you could use a timer for the delay and change the numbers every time the timer expires.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

What is 0x3f? What does it mean?

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

Kartman wrote:
What is 0x3f? What does it mean?

 

It's a hex number that switches on the segments required to illuminate the number zero on the 7-seg display.  The digital pins output high voltage levels to those particular segments.

Last Edited: Sun. Oct 1, 2017 - 02:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:

I need to use #defines

Why? You could define display_clear as 0x00 and then use  PORTD = display_clear; the same could be done for other numbers.

 

But there are many ways of doing what you are doing like putting all the data for the numbers in an array and then read them out in sequence with just a single delay statement.

 

Or you could use a timer for the delay and change the numbers every time the timer expires.

 

Thank you John, I appreciate the advice.

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

So 0x3f might be SEVENSEG_0
Therefore
#define SEVENSEG_0 0x3f
You can fill in the rest......
Note that #define just does a simple text substitution.

Last Edited: Sun. Oct 1, 2017 - 03:37 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The way this would normally be done is to have all 10 (or 16 for a hexadecimal display) segment patterns in an array.  Then you index into the array with your 0-9 (or 0-0xF) digit value and display the segments.  Normally also, as mentioned, this would be done with a timer that multiplexes the digits of a multi-digit display so that all digits are refreshed at least 100 times per second.  None of this may be applicable to your immediate goal, but it should be the direction you move in down the road.

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

It works, but as I mentioned I need to use #defines - I'm not sure how best to modify the code to accomodate that.

#define ZERO 0x3F
    PORTD = ZERO;

Can you guess the rest?

"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 C when you see the same code sequence repeated over and over it's almost always crying out for a loop or to be collected into a function. For example :

void display(uint8_t pattern){
    PORTD = pattern;  
    _delay_m(1000 ) ;
    PORTD = 0x00;
    _delay_ms(1000);
}

int main(void){
    DDRD = 0xFF;

    while(1) {
      display(0x3F);  
      display(0x06);
      etc. 
    } 
}

Now replace those 3F, 06 and so on with the #define'd names others have suggested.

 

(and would someone please fix this forum software? Trying to type that small amount of code on a tablet was close to impossible!)

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

Thank you Kartman.

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

kk6gm wrote:

The way this would normally be done is to have all 10 (or 16 for a hexadecimal display) segment patterns in an array.  Then you index into the array with your 0-9 (or 0-0xF) digit value and display the segments.  Normally also, as mentioned, this would be done with a timer that multiplexes the digits of a multi-digit display so that all digits are refreshed at least 100 times per second.  None of this may be applicable to your immediate goal, but it should be the direction you move in down the road.

 

Thank you kk6gm.

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

joeymorin wrote:

It works, but as I mentioned I need to use #defines - I'm not sure how best to modify the code to accomodate that.

#define ZERO 0x3F
    PORTD = ZERO;

Can you guess the rest?

 

Thank you joeymorin.

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

clawson wrote:

In C when you see the same code sequence repeated over and over it's almost always crying out for a loop or to be collected into a function. For example :

void display(uint8_t pattern){
    PORTD = pattern;  
    _delay_m(1000 ) ;
    PORTD = 0x00;
    _delay_ms(1000);
}

int main(void){
    DDRD = 0xFF;

    while(1) {
      display(0x3F);  
      display(0x06);
      etc. 
    } 
}

Now replace those 3F, 06 and so on with the #define'd names others have suggested.

 

(and would someone please fix this forum software? Trying to type that small amount of code on a tablet was close to impossible!)

 

Thank you clawson.