Você está na página 1de 9

Universidade Federal do Amazonas

Instituto de Computação
ICC060 – Sistemas Lógicos (SL) – 2018/2
Prof. Leandro Galvão

Atividade Prática 02 – Representação de Números Inteiros


em Arduino

OBJETIVOS:
• Fixar conhecimento sobre a notação complemento de 2.
• Praticar operações bit a bit.
• Utilizar um display de 7 segmentos para exibir dígitos hexadecimal.

MATERIAIS:
• 01 placa Arduino Uno
• 05 resistores de 330 Ω (laranja – laranja – marrom)
• 04 LEDs difusos
• 13 fios jumper macho-macho
• 01 protoboard
• 01 display de 7 segmentos de catodo comum (ref. LSD056AUE)

ATENÇÃO:
• Primeiro, monte os circuitos. DEPOIS, conecte o Arduino à porta USB do computador.
• Ao encaixar o LED na protoboard, cuidado para não inverter os terminais.

Moral da história: Variáveis int não guardam números inteiros; guardam estados.

Experimento 1: Contador com display de 7 segmentos


O display de 7 segmentos é um mostrador utilizado para exibir informação alfanumérica que possa
ser facilmente compreendida pelo usuário sobre as operações internas de um circuito. Ele é composto

1
Figura 1: Display de 7 segmentos.

por sete LEDs no formato de segmentos (traços), que são identificados, pelas letras a, b, c, d, e, f, g,
a partir do segmento mais alto e no sentido horário, como indicado na Figura 1. Há ainda um oitavo
LED, o ponto decimal, utilizado para separar a parte inteira da parte fracionária de um número. Ele
não será usado nesta Atividade Prática.
O componente LSD056AUE é um display de catodo comum, ou seja, os terminais negativos de
cada um dos sete LEDs do display estão conectados entre si. Dessa forma, você deve ligar o catodo ao
pino GND do Arduino por meio de um resistor. Como mostra a Figura 1, o componente LSD056AUE
oferece dois terminais de catodo: escolha aquele que facilitar a passagem dos fios.

Figura 2: Conexão do display de 7 segmentos com o Arduino. Deixe um espaço no lado direito da
protoboard para acrescentar 4 LEDs nos próximos Experimentos.

2
TAREFAS
1. Na Folha de Respostas, preencha a tabela com 0s e 1s, indicando quais segmentos do display
devem ser acesos (1) ou apagados (0) a fim de exibir o algarismo hexadecimal desejado. A
primeira linha é fornecida como exemplo.

2. Monte o circuito ilustrado na Figura 2. Atenção para a ordem de ligação dos fios: o pino 1 do
Arduino conecta-se ao terminal a do display, o pino 2 ao terminal b, e assim sucessivamente.

3. Abra o Código 1 na IDE Arduino, substituindo os caracteres sublinhados das linhas 5 a 19 por
0s e 1s, conforme o padrão que você preencheu na tabela.

4. Verifique se a porta por onde o Arduino está conectado ao computador está corretamente sele-
cionada.

5. Transfira o programa para o Arduino e verifique o que acontece com o display.

Código 1: Exibe contagem progressiva em um display de 7 segmentos.

1 byte numSegs = 7; / * Qtde. de segmentos no display * /


2 byte displayPins [] = {1, 2, 3, 4, 5, 6, 7}; / * Pinos conectado ao display * /
3 / * Mapeamento dos segmentos que devem acender para formar digitos no display * /
4 byte displayDigits [16][7] = { { 1,1,1,1,1,1,0 }, // = Digito 0
5 { _,_,_,_,_,_,_ }, // = Digito 1
6 { _,_,_,_,_,_,_ }, // = Digito 2
7 { _,_,_,_,_,_,_ }, // = Digito 3
8 { _,_,_,_,_,_,_ }, // = Digito 4
9 { _,_,_,_,_,_,_ }, // = Digito 5
10 { _,_,_,_,_,_,_ }, // = Digito 6
11 { _,_,_,_,_,_,_ }, // = Digito 7
12 { _,_,_,_,_,_,_ }, // = Digito 8
13 { _,_,_,_,_,_,_ }, // = Digito 9
14 { _,_,_,_,_,_,_ }, // = Digito A
15 { _,_,_,_,_,_,_ }, // = Digito B
16 { _,_,_,_,_,_,_ }, // = Digito C
17 { _,_,_,_,_,_,_ }, // = Digito D
18 { _,_,_,_,_,_,_ }, // = Digito E
19 { _,_,_,_,_,_,_ } // = Digito F
20 };
21
22 void setup () {
23 / * Configura todos os pinos do display como OUTPUT * /
24 for (byte i = 0; i < numSegs; i++)
25 pinMode(displayPins[i], OUTPUT);
26 }
27
28 void loop () {
29 / * Laco externo percorre numeros de 0 a 15 * /
30 for (byte cont = 0; cont < 16; cont ++) {
31 / * Imprime caracteres hexa correspondentes a ’cont ’ * /
32 for (byte i = 0; i < numSegs; i++)
33 digitalWrite (displayPins [i], displayDigits [cont ][i]);
34
35 / * Tempo de espera (em ms) entre um numero e outro * /
36 delay (1000);
37 }
38 }

3
Experimento 2: Contador Hexadecimal e Binário
Agora, vamos usar 04 LEDs para mostrar os quatro bits correspondentes à conversão do algarismo
hexadecimal do display para a base binária. Para isso, o Código 2 isola cada um dos quatro bits que
formam um dígito hexadecimal e o exibe no LED correspondente.
Uma máscara de bits é uma sequência de bits elaborada de modo a ler ou alterar bits específicos
de outra sequência de bits, sem modificar os demais bits. Por exemplo, se desejamos ler os dois bits
menos significativos de uma variável de 4 bits, podemos fazer um AND bit a bit (&) entre os bits da
variável e os da máscara 0011, como mostra a Figura 3.

Figura 3: Este exemplo de máscara de bits isola os dois bits menos significativos de uma variável.

Da álgebra booleana, sabemos que um AND entre 0 e qualquer outro valor resulta em zero, e
que um AND entre 1 e outro valor resulta nesse próprio valor. É por meio dessa propriedade que
isolamos bits específicos de uma determinada sequência de bits.
Existem ocasiões em que precisamos acessar os bits que estão no meio da string de bits. Nesse
caso, após aplicar a máscara, devemos deslocar os bits extraídos para a direita, a fim de ler seu valor
absoluto. É o que mostra a Figura 4.

Figura 4: Exemplo de máscara de bits seguida de deslocamento.

TAREFAS
1. Monte o circuito ilustrado na Figura 5.
2. Abra o Código 2 e carregue-o no Arduino, substituindo os caracteres sublinhados das linhas 8
a 22 por 0s e 1s, conforme o padrão que você preencheu na tabela.
3. Verifique o que acontece com o display e os LEDs.
4. Descreva na Folha de Respostas como a linha 30 na função show_bits() escreve nos LEDs os
bits da variável valor, recebida como argumento.

4
Figura 5: Conexão do display de 7 segmentos e dos LEDs com o Arduino.

Código 2: Exibe contagem progressiva em um display de 7 segmentos e em um conjunto de 4 LEDS.

1 byte numSegs = 7; / * Qtde. de segmentos no display * /


2 byte numLeds = 4; / * Qtde. de leds * /
3 byte displayPins [] = {1, 2, 3, 4, 5, 6, 7}; / * Pinos conectado ao display * /
4 byte ledPins [] = {11, 10, 9, 8}; / * Pinos conectado aos leds * /
5
6 / * Mapeamento dos segmentos que devem acender para formar digitos no display * /
7 byte displayDigits [16][7] = { { 1,1,1,1,1,1,0 }, // = Digito 0
8 { _,_,_,_,_,_,_ }, // = Digito 1
9 { _,_,_,_,_,_,_ }, // = Digito 2
10 { _,_,_,_,_,_,_ }, // = Digito 3
11 { _,_,_,_,_,_,_ }, // = Digito 4
12 { _,_,_,_,_,_,_ }, // = Digito 5
13 { _,_,_,_,_,_,_ }, // = Digito 6
14 { _,_,_,_,_,_,_ }, // = Digito 7
15 { _,_,_,_,_,_,_ }, // = Digito 8
16 { _,_,_,_,_,_,_ }, // = Digito 9
17 { _,_,_,_,_,_,_ }, // = Digito A
18 { _,_,_,_,_,_,_ }, // = Digito B
19 { _,_,_,_,_,_,_ }, // = Digito C
20 { _,_,_,_,_,_,_ }, // = Digito D
21 { _,_,_,_,_,_,_ }, // = Digito E
22 { _,_,_,_,_,_,_ } // = Digito F
23 };
24
25 void show_bits(byte valor) {
26 byte x; / * Bit a ser impresso nos leds * /
27
28 / * Acende os leds conforme os bits do argumento ’valor ’ * /
29 for (byte i = 0; i < numLeds; i++) {
30 masc = 0b00000001 << i;
31 x = (valor & masc) >> i;

5
32 if (x == 1)
33 digitalWrite (ledPins[i], HIGH);
34 else
35 digitalWrite (ledPins[i], LOW);
36 }
37 }
38
39 void setup () {
40 / * Configura todos os pinos do display como OUTPUT * /
41 for (byte i = 0; i < numSegs; i++)
42 pinMode(displayPins[i], OUTPUT);
43
44 / * Configura todos os pinos dos leds como OUTPUT * /
45 for (byte i = 0; i < numLeds; i++)
46 pinMode(ledPins[i], OUTPUT);
47 }
48
49 void loop () {
50 / * Laco externo percorre numeros de 0 a 15 * /
51 for (byte cont = 0; cont < 16; cont ++) {
52 / * Imprime caracteres hexa correspondentes a ’cont ’ * /
53 for (byte i = 0; i < numSegs; i++)
54 digitalWrite (displayPins [i], displayDigits [cont ][i]);
55
56 / * Chama funcao que imprime padrao de bits nos LEDs * /
57 show_bits(cont);
58
59 / * Tempo de espera (em ms) entre um numero e outro * /
60 delay (1000);
61 }
62 }

Experimento 3: Limites da Representação de Inteiros


Neste Experimento, você usará dois códigos Arduino:

• O Código 3 explora a função sizeof(), que determina o número de bytes ocupados por um
valor passado como argumento; e

• O Código 4 explora a biblioteca <limits.h>, que define um conjunto de macros que informam
os maiores e menores valores representáveis pelos diversos tipos de variáveis inteiras.

TAREFAS
1. Use o Código 3 para preencher a segunda coluna da tabela constante na Folha de Respostas.

2. Na linha 7 do Código 4, troque as constantes CHAR_MAX, CHAR_MIN, UCHAR_MAX, pelas constantes


indicadas na tabela da Folha de Respostas. Preencha a tabela com os valores exibidos pelo
código. Você também vai precisar modificar o tipo do vetor unsigned char para o tipo de
variável pedido na tabela.

Código 3: Imprime tamanho (em bits) ocupado em memória pelos diversos tipos Arduino.

1 void setup () {
2 Serial.begin (9600);

6
3
4 Serial.println("Char: ");
5 Serial.println(sizeof(char) * 8);
6
7 Serial.println("Byte: ");
8 Serial.println(sizeof(byte) * 8);
9
10 Serial.println("Int: ");
11 Serial.println(sizeof(int) * 8);
12
13 Serial.println("Short int: ");
14 Serial.println(sizeof(short int) * 8);
15
16 Serial.println("Long int: ");
17 Serial.println(sizeof(long int) * 8);
18
19 Serial.println("Long long int: ");
20 Serial.println(sizeof(long long int) * 8);
21 }
22
23 void loop () {
24 }

Código 4: Imprime os limites de representação de variáveis do tipo char na memória do Arduino.

1 #include <limits.h>
2
3 void setup () {
4 / * NA LINHA ABAIXO , ALTERE:
5 1) O TIPO DO VETOR
6 2) AS MACROS CONTIDAS NO VETOR * /
7 unsigned char vec [] = {CHAR_MAX , CHAR_MIN , UCHAR_MAX };
8 String labels [] = {"MAX", "MIN", "UMAX"}; / * Indica a macro impressa * /
9
10 Serial.begin (9600);
11
12 / * Cada iteracao imprime os valores de uma das 03 macros * /
13 for (byte i=0; i < 3; i++) {
14 Serial.println(labels[i]);
15 Serial.println(vec[i], DEC);
16 Serial.println(vec[i], HEX);
17 Serial.println(vec[i], BIN);
18 Serial.println("");
19 }
20 }
21
22 void loop () {
23 }

Experimento 4: Deslocamento de bits


O deslocamento de bits é uma operação realizada sobre a cadeia de bits que formam um valor do tipo
inteiro. Essa sequência de bits pode ser movida para a esquerda ou para direita. Operações aritméti-
cas como a adição e a divisão transformam os valores operados. Já as operações de deslocamento de
bits transformam a cadeia de bits [1].
Neste experimento, abordaremos três tipos de deslocamento de bits [2]:

7
• Deslocamento à esquerda: indicado por x << k, desloca os bits da variável x em k posições
para a esquerda. Desse modo, os k bits mais significativos de x são descartados e a extremidade
direita de x é preenchida com k zeros.

• Deslocamento à direita: indicado por x >> k, desloca os bits da variável x em k posições para
a direita. A extremidade esquerda de x pode ser preenchida de duas maneiras:

– No modo lógico, a extremidade esquerda é sempre preenchida com k zeros.


– No modo aritmético, a extremidade esquerda é preenchida com k repetições do bit mais
significativo (MSB) da variável x original. Essa convenção pode parecer estranha, mas ela
preserva o sinal do operando, na notação complemento de 2.

O sinal usado pela Linguagem C para o deslocamento à direita (>>) não distingue o modo lógico
do aritmético. O tipo da variável deslocada é que determina qual dos dois modos será aplicado:

• Para variáveis não sinalizadas (unsigned, ou byte do Arduino), é aplicado o modo lógico.

• Para variáveis sinalizadas (signed, explícito ou omitido), é aplicado o modo aritmético.

Aplicações do deslocamento de bits. Multiplicações e divisões por 2n ficam mais rápidas quando
aplicamos o deslocamento de bits, da mesma forma que multiplicações e divisões por dez na base
decimal são mais fáceis de se fazer. Além disso, o deslocamento de bits pode ser usado para isolar um
grupo de bits de interesse, localizados no meio da sequência de bits, para uma de suas extremidades.

TAREFAS
1. Carregue o Código 5 no Arduino.

2. Na Folha de Respostas, preencha a tabela com o resultado das operações indicadas.

3. Responda as questões da Folha de Respostas.

Código 5: Trecho de código que desloca os bits da variável a.

1 void setup () {
2 byte a = 0b00011010;
3 byte b;
4
5 Serial.begin (9600);
6
7 for (byte i = 1; i < 5; i++) {
8 b = a << i;
9 Serial.println(b, BIN);
10 Serial.println(b, DEC);
11 Serial.println("");
12 }
13 }
14
15 void loop () {
16 }

8
Referências
[1] Bryant, R. E., and O’Hallaron, D. R. Computer Systems: A Programmer’s Perspective, 3 ed.
Addison-Wesley, 2016.

[2] Carvalho, L. S. G. Apostila de ICC060 Sistemas Lógicos, 0.6 ed. Universidade Federal do Amazo-
nas, 2017.