1

I am completely new to embedded programming, I'm examining the code below and trying to understand how it work, but I really got stuck.

The program is used to count and print out the numbers from 0 to 9.

So can someone please explain the line const uint8_t ? why do I need an array of heximal number here?

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


const uint8_t segments[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE4,0xFE,0xF6};

int main(void) {
    uint8_t i=0; //s
    int g; 
    init_debug_uart0();
    /* set PORT A pins as outputs */
    DDRA = 0xFF;
    for (;;) {

        PORTA = segments[i]; 
        printf("%d\n\r",i); 
        _delay_ms(1000);

        if (i >=9) {
            fprintf(stderr , "Count Overflow\n\r"); i = 0;
            scanf("%d", &g);
        }else 
            i++;
    }
}

And a final question, does anyone know good sources to read about embedded programming? Currently i'm learning about the IIMatto, 8-bits processor and it has 32-registers, designed in Harvard architecture and has 1 level pipeline.

3
  • Look at your schematic to see what is connected to port A, then look at the bit-patterns of those hex consts. Commented Jan 31, 2014 at 16:34
  • They look to me that they might be bit patterns to illuminate the correct segments in a 7 segment display. Commented Jan 31, 2014 at 16:36
  • @bobmcn - meh - you spoiled the surprise:) Commented Jan 31, 2014 at 16:36

5 Answers 5

4

The const uint8_t segments[10] = {0xFC,0x60,0xDA, ... simple defines a constant 10-byte array of bytes.

Code does not need an array of hexadecimal, it could have been decimal.

But consider the benefit of

0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE4,0xFE,0xF6
// versus
252,96,218,...

A casual inspection shows that the number of bits set in each byte is

6,2,5,5,...

This just happens to match the number of segments set in a 7-segment display of the digits 0,1,2,3 ...
Closer inspection of the bits set will detail which bit activate what segment.

Other methods could be employed to get this mapping of 7-segment to digit, but showing the data in hexadecimal is one step closer than decimal.


Perhaps code could be like (the proper segment mapping is TBD).

typedef enum  {
  LED7_a       = 1 << 0,
  LED7_b       = 1 << 1,
  LED7_c       = 1 << 2,
  LED7_d       = 1 << 3,
  LED7_e       = 1 << 4,
  LED7_f       = 1 << 5,
  LED7_g       = 1 << 6,
  LED7_dp      = 1 << 7
  } LED7_Segment_t;

/* ****************************************************************************
7 Segment Pattern
 Layout
  aaa
 f   b
 f   b
  ggg
 e   c
 e   c
  ddd dp
**************************************************************************** */
const uint8_t segments[] = {
  /*'0*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_e | LED7_f         ,
  /*'1*/          LED7_b | LED7_c                                    ,
  /*'2*/ LED7_a | LED7_b |          LED7_d | LED7_e |          LED7_g,
  /*'3*/ LED7_a | LED7_b | LED7_c | LED7_d |                   LED7_g,
  /*'4*/          LED7_b | LED7_c |                   LED7_f | LED7_g,
  /*'5*/ LED7_a |          LED7_c | LED7_d |          LED7_f | LED7_g,
  /*'6*/ LED7_a |          LED7_c | LED7_d | LED7_e | LED7_f | LED7_g,
  /*'7*/ LED7_a | LED7_b | LED7_c                                    ,
  /*'8*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_e | LED7_f | LED7_g,
  /*'9*/ LED7_a | LED7_b | LED7_c | LED7_d |          LED7_f | LED7_g};
Sign up to request clarification or add additional context in comments.

Comments

1

First of all, ask yourself where is segments used, what is it used for, how is it used?

Hints:

Where: Used to assign a value to PORTA

What: PORTA Is an output from an embedded system. Perhaps to an external device. segments is used to store outputs.

How: Each time around the loop, the value i is incremented. i is used as the index for segments when its value is assigned to PORTA.

Also: A hexadecimal number, specifically 2 digits long, is a byte which is 8 bits. Look on your microcontroller for up to 8 pins labelled "PORTA"

Comments

1

When writing to PORTA (an I/O port) you are concerned with the state of individual I/O lines associated with each bit.

To display a specific set of segments representing a digit on a 7-segment display, you have to write a specific bit pattern - one bit for each segment you wish to light. The segments array is indexed by the digit you want to display, and the value at that index represents the bit pattern on PORTA required to light the segments that represent that digit.

The reason hexadecimal is used is because there is a direct mapping of single hexadecimal digit to exactly four binary digits, so hex is a compact way of representing bit patterns. For an experienced embedded developer, mentally converting a bit-pattern to hex and vice versa becomes second nature. If the values were decimal, the representation would bear no direct relationship to the bit pattern, and the conversion or mental visualisation of the bit pattern less simple.

The hex digit to binary pattern conversion is as follows:

0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

Comments

1
0xFC = 11111100
0x60 = 1100000
0xDA = 11011010
....

you need an array of hex numbers, most probably you have connected some sort of device to portA, and in this device

0xFC or 11111100 means display 0,(when portA pins 7,6,5,4,3,2, are high and 1,0 are low     this device will display 0
 0x60 or 11000000 means display 1(when PortA pins 7,6 are high and the rest low, this device will display 1. 

and so on..

The memory locations in the microcontroller are 8 bits wide so 16 I/O will require two 8 bit registers called PORTA and PORTB. in your case its only 8bits wide ie. 8 I/O pins per PORTA, another 8 for PORTB and so on.

the outputs of these ports are controlled by the 8bits..

Suppose we wish to turn on an LED which we are going to connect to bit 4 on PORTB. We first of all have to instruct the microcontroller to ensure that PORTB bit 4 is an output.(the micro needs to know if ports are outputs are inputs you cant just plug stuff in)

in a pic micro you would say TRIA = 0x00010000 this tell the micro portB4 is an output.Now that we have said its an output, PORTA = 0b00010000 sets this portB4 to a high voltage, in other words this will illuminate the LED or whatever you have connected to the port.

PORTA = 0b00000000 // turns off PORTA outputs, PORTA = 0b10000000 // turns on PORTA pin 7

Comments

0

The hexadecimal values its just a notation, the first letter represents the first 4 bits of your int and the other the other four bits because you are declaring a const uint8 variable wich means an unsigned integer of 8 bits, this is an integer but without sign, the bit of the sign is removed, so it can store 2^8 posibles values.

I'm just answering the first question. Hope it help!!

1 Comment

Well, yes, that's why it's notated in hex. But you might make a try at explaining what the purpose of that table is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.