Академический Документы
Профессиональный Документы
Культура Документы
UNIVERSIDADE FEDERAL DE UBERLÂNDIA
FACULDADE DE ENGENHARIA ELÉTRICA ‐ FEELT
LASEC
FEELT
APOSTILA DE SISTEMAS EMBARCADOS
Última Atualização 15/07/2014
1° Edição 03/2011
Sumário
Introdução ..................................................................................................................................... 3
Microcontrolador ARM ................................................................................................................. 6
Descrição dos softwares utilizados ............................................................................................... 9
LED_Blink ..................................................................................................................................... 10
Exercício Proposto ................................................................................................................... 10
Programa LED_Blink Comentado ............................................................................................ 12
Configurando o Clock da CPU ...................................................................................................... 14
Operadores Lógicos Bit a Bit ....................................................................................................... 15
Display de 7 Segmentos .............................................................................................................. 17
Exercício Proposto ................................................................................................................... 18
Números mágicos em programação ........................................................................................... 20
Portabilidade e o Pré‐processador C ........................................................................................... 27
Tipos Primitivos em C .................................................................................................................. 29
Exercício Proposto ................................................................................................................... 35
Teclado Matricial ......................................................................................................................... 36
Exercício Proposto ................................................................................................................... 38
Display de Cristal Líquido ............................................................................................................ 39
Exercício Proposto ................................................................................................................... 42
Interface de Comunicação SPI ..................................................................................................... 43
Operações “ATOMIC” .................................................................................................................. 44
“STRUCTURE PADDING” E SERIALIZAÇÃO ................................................................................. 49
BOAS PRÁTICAS EM PROGRAMAÇÃO ......................................................................................... 57
Escolher Bons Nomes .............................................................................................................. 57
Variáveis e Modificadores de Tipo .......................................................................................... 57
Exemplo: .................................................................................................................................. 58
REGRAS MISRA ............................................................................................................................ 59
Constantes ............................................................................................................................... 59
Chaves ..................................................................................................................................... 59
Exercício Proposto ................................................................................................................... 60
PROGRAMAÇÃO EM LINGUAGEM C USANDO MÁQUINA DE ESTADO ....................................... 60
Referências .................................................................................................................................. 61
Página 2
1° Edição 03/2011
Introdução
Figura 1- Primeiro computador a usar eletricidade, inventado por John Vincent Atanasoff
e Clifford Berry em 1939.
Página 3
1° Edição 03/2011
Página 4
1° Edição 03/2011
Página 5
1° Edição 03/2011
Microcontrolador ARM
Página 6
1° Edição 03/2011
Página 7
1° Edição 03/2011
Características do ARM7:
Arquitetura RISC de 32-bit com conjunto de instruções ARM e Thumb;
Pipeline de 3 estágios (arquitetura von Neumann);
Performance de até 130 MIPs (Dhrystone 2.1) num típico processador
de 0.13µm;
Baixíssimo consumo de energia;
Amplo SO e suporte RTOS – incluindo Windows CE, Palm OS, Symbian
OS, Linux;
Excelente suporte de debug para desenvolvimento SoC, incluindo
interface ETM;
Disponibilidade de processos de 0.25µm, 0.18µm e 0.13µm;
Código é compatível com processadores ARM9 e permitem a
reutilização dos códigos de aplicação;
Migração e suporte para novas tecnologias de processadores.
Página 8
1° Edição 03/2011
Página 9
1° Edição 03/2011
LED_Blink
Exercício Proposto
Página 10
1° Edição 03/2011
C1
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
P0.8/TxD1/PW M4/AD1.1
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
37
P0.11/CTS1/CAP1.1/SCL1
38
47k P0.12/DSR1/MAT1.0/AD1.3
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5
46
P0.16/EINT0/MAT0.2/CAP0.2
47
P0.17/CAP1.2/SCK1/MAT1.2
53
P0.18/CAP1.3/MISO1/MAT1.3
54
P0.19/MAT1.2/MOSI1/CAP1.2
55
P0.20/MAT1.3/SSEL1/EINT3
1
P0.21/PWM5/AD1.6/CAP1.3
2
P0.22/AD1.7/CAP0.0/MAT0.0
58
P0.23
9
P0.25/AD0.4/AOUT
10
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1
13 3.3V
P0.28/AD0.1/CAP0.2/MAT0.2
P0.29/AD0.2/CAP0.3/MAT0.3
14 U2:B D3
15 R7
P0.30/AD0.3/EINT3/CAP0.0
17 3 4
P0.31
300
16 LED-GREEN
P1.16/TRACEPKT0 74HCT04
3.3V 12
P1.17/TRACEPKT1
49 8
VBAT P1.18/TRACEPKT2
4
P1.19/TRACEPKT3
63 48
VREF P1.20/TRACESYNC
7 44
V3A P1.21/PIPESTAT0
51 40
V3 P1.22/PIPESTAT1
43 36
V3 P1.23/PIPESTAT2
23 32
V3 P1.24/TRACECLK
28
P1.25/EXTIN0
59 24
VSSA P1.26/RTCK
50 64
VSS P1.27/TDO
42 60
VSS P1.28/TDI
25 56
VSS P1.29/TCK
18 52
VSS P1.30/TMS
6 20
VSS P1.31/TRST
LPC2138
C1
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PW M3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
P0.8/TxD1/PW M4/AD1.1
34
R1 C3 P0.9/RxD1/PW M6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
37 3.3V
P0.11/CTS1/CAP1.1/SCL1
47k P0.12/DSR1/MAT1.0/AD1.3
38 U2:D LED 4
100pF 39 R4
P0.13/DTR1/MAT1.1/AD1.4
41 13 12
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5 300
LED-GREEN 3.3V
74HCT04
46
P0.16/EINT0/MAT0.2/CAP0.2
P0.17/CAP1.2/SCK1/MAT1.2
47 U2:C LED 3
53 R3
P0.18/CAP1.3/MISO1/MAT1.3
54 5 6
P0.19/MAT1.2/MOSI1/CAP1.2
55
P0.20/MAT1.3/SSEL1/EINT3 300
1 LED-GREEN 3.3V
P0.21/PW M5/AD1.6/CAP1.3 74HCT04
2
P0.22/AD1.7/CAP0.0/MAT0.0
P0.23
58 U2:B LED 2
R2
9 3 4
P0.25/AD0.4/AOUT
10 300
P0.26/AD0.5
11 LED-GREEN
P0.27/AD0.0/CAP0.1/MAT0.1 74HCT04
13 3.3V
P0.28/AD0.1/CAP0.2/MAT0.2
P0.29/AD0.2/CAP0.3/MAT0.3
14 U2:A LED 1
P0.30/AD0.3/EINT3/CAP0.0
15 R7
17 1 2
P0.31
300
16 LED-GREEN
P1.16/TRACEPKT0 74HCT04
3.3V 12
P1.17/TRACEPKT1
49 8
VBAT P1.18/TRACEPKT2
4
P1.19/TRACEPKT3
63 48
VREF P1.20/TRACESYNC
7 44
V3A P1.21/PIPESTAT0
51 40
V3 P1.22/PIPESTAT1
43 36
V3 P1.23/PIPESTAT2
23 32
V3 P1.24/TRACECLK
28
P1.25/EXTIN0
59 24
VSSA P1.26/RTCK
50 64
VSS P1.27/TDO
42 60
VSS P1.28/TDI
25 56
VSS P1.29/TCK
18 52
VSS P1.30/TMS
6 20
VSS P1.31/TRST
LPC2138
Página 11
1° Edição 03/2011
#include "LPC214x.h" // A diretiva #include informa ao compilador que ele deve incluir
o arquivo LPC214x.h, pois este arquivo contém endereços de memória e de registradores
que serão utilizados no programa.
/*------------------------------------------------------------------------------------*/
/* FUNCTION IMPLEMENTATION */
/*------------------------------------------------------------------------------------*/
int main (void) // A função main() é a primeira função a ser executada, todo programa
deve possuir uma.
{
int j = 0; // Declara a variável j como inteiro de 32bit, porque a arquitetura do ARM
é de 32bit, por isso, a faixa de valores de j é de -2.147.483.648 a +2.147.483.647
while(1){
Página 12
1° Edição 03/2011
int main(void)
{
...
Página 13
1° Edição 03/2011
//--------------------------------------------------------------------------------------
//--- A frequência da CPU deve ser configurada aqui!!! ---------------------------------
//--------------------------------------------------------------------------------------
//--- A frequência do barramento dos periféricos deve ser configurada aqui!!! ----------
Onde:
CCLK: valor da freqüência do CLOCK do processador;
M: valor do multiplicador do PLL que controla a da freqüência do CLOCK do processador;
Fosc: frequência do oscilador a cristal/oscilador externo.
M = CCLK / Fosc
M = 60 MHz / 12 MHz
M= 5
Página 14
1° Edição 03/2011
Para que apenas um BIT seja forçado a assumir nível lógico alto ( 1 ), em
um determinado registrador, é necessário utilizar o operador lógico OU e uma
máscara que possua apenas o bit desejado em nível lógico alto ( 1 ).
A Figura 6 mostra como forçar para nível alto o bit 10 de um registrador
denominado Registrador_X.
BIT: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Registrador_X: 1 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0
Operador OU ou ou ou ou ou ou ou ou ou ou ou ou ou ou ou ou
Máscara: 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
Registrador_X: 1 0 0 0 0 1 0 0 1 1 1 1 0 1 1 0
Figura 6 – Operador Lógico OU
uint16_t Mascara = 1 << 10; //inicializa uma Mascara de 16 bits com o bit 10 igual a 1
Registrador_X |= Mascara; // Esta linha de código realiza os três passos descritos abaixo:
1) Lê o valor do Registrador_X;
2) Realiza uma operação lógica OU bit a bit do valor lido com a Mascara;
3) Armazena o resultado no Registrador_X.
Página 15
1° Edição 03/2011
Para que apenas um BIT seja forçado a assumir nível lógico baixo ( 0 ),
em um determinado registrador, é necessário utilizar o operador lógico E e uma
máscara que possua apenas o bit desejado em nível lógico baixo ( 0 ).
A Figura 7 mostra como forçar para nível alto o bit 10 de um registrador
denominado Registrador_X.
BIT: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Registrador_X: 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0
Operador E E E E E E E E E E E E E E E E E
Máscara: 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
Registrador_X: 1 0 1 1 1 0 1 1 1 1 1 1 0 1 1 0
Figura 7 – Operador Lógico E
uint16_t Mascara = ~(1 << 10); //inicializa uma Mascara de 16 bits com o bit 10 igual a 1 e
em seguida inverte todos os bits, isto é, os bits igual a 1 são convertidos em 0 e os bits igual a
0 são convertidos em 1
Registrador_X &= Mascara; // Esta linha de código realiza os três passos descritos abaixo:
1) Lê o valor do Registrador_X;
2) Realiza uma operação lógica E bit a bit do valor lido com a Mascara;
3) Armazena o resultado no Registrador_X.
Para que apenas um BIT seja negado, isto é, se for nível lógico alto ( 1 )
seja forçado a assumir nível lógico baixo ( 0 ) e vice-versa, em um determinado
registrador, é necessário utilizar o operador lógico XOR (OU Exclusivo) e uma
máscara que possua apenas o bit desejado em nível lógico alto ( 1 ).
A Figura 7 mostra como negar o bit 10 de um registrador denominado
Registrador_X.
BIT: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Registrador_X: 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0
Operador XOR XOR XOR XOR ... ... ... ... ... .. .. ... ... ... ... XOR XOR
Máscara: 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
Registrador_X: 1 0 1 1 1 0 1 1 1 1 1 1 0 1 1 0
Figura 8 – Operador Lógico XOR (OU Exclusivo)
uint16_t Mascara = 1 << 10; //inicializa uma Mascara de 16 bits com o bit 10 igual a 1
Registrador_X ^= Mascara; // Esta linha de código realiza os três passos descritos abaixo:
1) Lê o valor do Registrador_X;
2) Realiza uma operação lógica XOR bit a bit do valor lido com a Mascara;
3) Armazena o resultado no Registrador_X.
Página 16
1° Edição 03/2011
Display de 7 Segmentos
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
3.3V
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
P0.8/TxD1/PWM4/AD1.1
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
P0.11/CTS1/CAP1.1/SCL1
37 R2
38 2k2
47k P0.12/DSR1/MAT1.0/AD1.3
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41
P0.14/DCD1/EINT1/SDA1
45 3.3V
P0.15/RI1/EINT2/AD1.5
46
P0.16/EINT0/MAT0.2/CAP0.2
47
P0.17/CAP1.2/SCK1/MAT1.2
P0.18/CAP1.3/MISO1/MAT1.3
53 U2:B
54 R7
P0.19/MAT1.2/MOSI1/CAP1.2
55 3 4
P0.20/MAT1.3/SSEL1/EINT3
1
P0.21/PWM5/AD1.6/CAP1.3 300
2
P0.22/AD1.7/CAP0.0/MAT0.0 74HCT04
P0.23
58 U2:A
R3
9 1 2
P0.25/AD0.4/AOUT
10 300
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1 74HCT04
P0.28/AD0.1/CAP0.2/MAT0.2
13 U2:C
14 R4
P0.29/AD0.2/CAP0.3/MAT0.3
15 5 6
P0.30/AD0.3/EINT3/CAP0.0
17 300
P0.31
U2:D
74HCT04
16 R5
P1.16/TRACEPKT0
3.3V 12 13 12
P1.17/TRACEPKT1
49 8 300
VBAT P1.18/TRACEPKT2
4
P1.19/TRACEPKT3 74HCT04
63
VREF P1.20/TRACESYNC
48 U2:E
7 44 R6
V3A P1.21/PIPESTAT0
51 40 11 10
V3 P1.22/PIPESTAT1
43 36 300
V3 P1.23/PIPESTAT2
23
V3 P1.24/TRACECLK
32 U2:F
74HCT04
28 R8
P1.25/EXTIN0
59 24 9 8
VSSA P1.26/RTCK
50 64 300
VSS P1.27/TDO
42 60
VSS P1.28/TDI 74HCT04
25
VSS P1.29/TCK
56 U3:A
18 52 R9
VSS P1.30/TMS
6 20 1 2
VSS P1.31/TRST
300
LPC2138
74HCT04
Figura 9 - Display de 7 Segmentos acionado pelos pinos P1.25, P1.26, P1.27, P1.28,
P1.29, P1.30 e P1.31
Página 17
1° Edição 03/2011
a
b
f
g Anodo
Comum
c
e
(a) (b)
Figura 10 – (a) Display de 7 seguimentos catodo comum (b) display de 7 seguimentos
anodo comum.
Exercício Proposto
Página 18
1° Edição 03/2011
Programa:
#include "LPC214x.h" // Informa ao compilador que ele deve incluir o arquivo LPC214x.h.
#include "cpu_init.h" // Informa ao compilador para incluir o arquivo cpu_init.h
while(1){
if (!(IOPIN0 & (1<<15))) //Verifica se o Botão foi pressionado
{
IOCLR1 = 0xFFFFFFFF; // Força nível baixo em todos os pinos do PORT1
Página 19
1° Edição 03/2011
C1
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26 3.3V
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27 (COM)
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
3.3V
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PWM2/EINT2
DIODE
P0.8/TxD1/PWM4/AD1.1
33 U3:B
34 R10
R1 C3 P0.9/RxD1/PWM6/EINT3
35 3 4
P0.10/RTS1/CAP1.0/AD1.2
P0.11/CTS1/CAP1.1/SCL1
37 R2 300
38 2k2
47k P0.12/DSR1/MAT1.0/AD1.3 74HCT04
100pF
P0.13/DTR1/MAT1.1/AD1.4
39 U3:C
41 R11
P0.14/DCD1/EINT1/SDA1
45 5 6
P0.15/RI1/EINT2/AD1.5
300
46
P0.16/EINT0/MAT0.2/CAP0.2 74HCT04
P0.17/CAP1.2/SCK1/MAT1.2
47 U3:D
P0.18/CAP1.3/MISO1/MAT1.3
53 R12 U2:B
54 13 12 R7
P0.19/MAT1.2/MOSI1/CAP1.2
55 3 4
P0.20/MAT1.3/SSEL1/EINT3 300
P0.21/PWM5/AD1.6/CAP1.3
1 U3:E
74HCT04 300
2 R13
P0.22/AD1.7/CAP0.0/MAT0.0 74HCT04
P0.23
58 11 10 U2:A
300 R3
9 1 2
P0.25/AD0.4/AOUT 74HCT04
P0.26/AD0.5
10 U3:F 300
11 R14
P0.27/AD0.0/CAP0.1/MAT0.1 74HCT04
P0.28/AD0.1/CAP0.2/MAT0.2
13 9 8 U2:C
14 300 R4
P0.29/AD0.2/CAP0.3/MAT0.3
P0.30/AD0.3/EINT3/CAP0.0
15 U4:A
74HCT04
5 6
P0.31
17 R15 300
1 2 U2:D
74HCT04
16 300 R5
P1.16/TRACEPKT0
3.3V 12 13 12
P1.17/TRACEPKT1 74HCT04
49
VBAT P1.18/TRACEPKT2
8 U4:B 300
P1.19/TRACEPKT3
4 R16 74HCT04
63
VREF P1.20/TRACESYNC
48 3 4 U2:E
7 44 300 R6
V3A P1.21/PIPESTAT0
51 40 11 10
V3 P1.22/PIPESTAT1 74HCT04
43 36 300
V3 P1.23/PIPESTAT2
23
V3 P1.24/TRACECLK
32 U2:F
74HCT04
28 R8
P1.25/EXTIN0
59 24 9 8
VSSA P1.26/RTCK
50 64 300
VSS P1.27/TDO
42 60
VSS P1.28/TDI 74HCT04
25
VSS P1.29/TCK
56 U3:A
18 52 R9
VSS P1.30/TMS
6 20 1 2
VSS P1.31/TRST
300
LPC2138
74HCT04
Figura 11 – Display de 7 Segmentos de dezena e unidade.
Página 20
1° Edição 03/2011
/*------------------------------------------------------------------------------------*/
/* DEFINITIONS AND MACROS */
/*------------------------------------------------------------------------------------*/
#define seg_a (1<<25) // Pino 25 do PORT1
#define seg_b (1<<26) // Pino 26 do PORT1
#define seg_c (1<<27) // Pino 27 do PORT1
#define seg_d (1<<28) // Pino 28 do PORT1
#define seg_e (1<<29) // Pino 29 do PORT1
#define seg_f (1<<30) // Pino 30 do PORT1
#define seg_g (1<<31) // Pino 31 do PORT1
/*------------------------------------------------------------------------------------*/
/* FUNCTION IMPLEMENTATION */
/*------------------------------------------------------------------------------------*/
int main (void) // Primeira função a ser executada, todo programa deve possuir uma.
{
cpu_init(); // Chama a rotina de inicialização da CPU
while(1){
i++; // Incrementa i
if (i >= 10){
i = 0;
}
}
}
return(0);
}
/*------------------------------------------------------------------------------------*/
/* EOF */
/*------------------------------------------------------------------------------------*/
Página 21
1° Edição 03/2011
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
3.3V
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
P0.8/TxD1/PW M4/AD1.1
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
P0.11/CTS1/CAP1.1/SCL1
37 R2
47k P0.12/DSR1/MAT1.0/AD1.3
38 2k2 U3:B
100pF 39 R10
P0.13/DTR1/MAT1.1/AD1.4
41 3 4
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5 300
74HCT04
P0.16/EINT0/MAT0.2/CAP0.2
46 U3:C
47 R11
P0.17/CAP1.2/SCK1/MAT1.2
53 5 6
P0.18/CAP1.3/MISO1/MAT1.3
54
P0.19/MAT1.2/MOSI1/CAP1.2 300
55
P0.20/MAT1.3/SSEL1/EINT3 74HCT04
P0.21/PW M5/AD1.6/CAP1.3
1 U3:D
2 R12
P0.22/AD1.7/CAP0.0/MAT0.0
58 13 12
P0.23
300
P0.25/AD0.4/AOUT
9 U3:E
74HCT04
10 R13
P0.26/AD0.5
11 11 10
P0.27/AD0.0/CAP0.1/MAT0.1
13 300
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3 74HCT04
P0.30/AD0.3/EINT3/CAP0.0
15 U3:F
P0.31
17 R14
9 8
16 300
P1.16/TRACEPKT0
3.3V
P1.17/TRACEPKT1
12 U4:A
74HCT04
49
VBAT P1.18/TRACEPKT2
8 R15
4 1 2
P1.19/TRACEPKT3
63 48 300
VREF P1.20/TRACESYNC
7 44
V3A P1.21/PIPESTAT0 74HCT04
51
V3 P1.22/PIPESTAT1
40 U4:B
43 36 R16
V3 P1.23/PIPESTAT2
23 32 3 4
V3 P1.24/TRACECLK
28 300
P1.25/EXTIN0
59 24
VSSA P1.26/RTCK 74HCT04
50
VSS P1.27/TDO
64 R3 Q1
42 60 BC337
VSS P1.28/TDI
25 56 2.2k
VSS P1.29/TCK
18 52
VSS P1.30/TMS
6 20
VSS P1.31/TRST
LPC2138
R4 Q2
BC337
2.2k
Figura 12 – Display de 7 Segmentos de dezena e unidade.
Segmento
Pino dos
Displays
P1.18 A
P1.19 B
P1.20 C
P1.21 D
P1.22 E
P1.23 F
P1.24 G
Página 22
1° Edição 03/2011
OBS2: Observe que os displays são do tipo catodo comum e o buffer 74HCT04
que aciona cada segmento é inversor, logo, os segmentos serão ligados
quando os pinos do microcontrolador estiverem em nível lógico baixo.
/*------------------------------------------------------------------------------------*/
/* DEFINITIONS AND MACROS */
/*------------------------------------------------------------------------------------*/
#define seg_a (1<<18) // Segmento a do display
#define seg_b (1<<19) // Segmento a do display
#define seg_c (1<<20) // Segmento a do display
#define seg_d (1<<21) // Segmento a do display
#define seg_e (1<<22) // Segmento a do display
#define seg_f (1<<23) // Segmento a do display
#define seg_g (1<<24) // Segmento a do display
/*------------------------------------------------------------------------------------*/
/* FUNCTION IMPLEMENTATION */
/*------------------------------------------------------------------------------------*/
//--------------------------------------------------------------------------------------
//--- Rotina que converte um número decimal para 7 Segmentos ---------------------------
void Decimal_to_7Segment(int i){
switch (i)
{
case 0: IOCLR1 = seg_a|seg_b|seg_c|seg_d|seg_e|seg_f; break; // 0 no display
Página 23
1° Edição 03/2011
case 1: IOCLR1 = seg_b|seg_c; break; // 1 no display
case 2: IOCLR1 = seg_a|seg_b|seg_d|seg_e|seg_g; break; // 2 no display
case 3: IOCLR1 = seg_a|seg_b|seg_c|seg_d|seg_g; break; // 3 no display
case 4: IOCLR1 = seg_b|seg_c|seg_f|seg_g; break; // 4 no display
case 5: IOCLR1 = seg_a|seg_c|seg_d|seg_f|seg_g; break; // 5 no display
case 6: IOCLR1 = seg_a|seg_c|seg_d|seg_f|seg_e|seg_g; break; // 6 no display
case 7: IOCLR1 = seg_a|seg_b|seg_c; break; // 7 no display
case 8: IOCLR1 = seg_a|seg_b|seg_c|seg_d|seg_e|seg_f|seg_g; break; // 8 no display
case 9: IOCLR1 = seg_a|seg_b|seg_c|seg_f|seg_g; break; // 9 no display
default: IOCLR1 = seg_a|seg_b|seg_c|seg_f|seg_g; // 0 no display
}
}
while(1){
Página 24
1° Edição 03/2011
/*------------------------------------------------------------------------------------*/
/* DEFINITIONS AND MACROS */
/*------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------*/
/* FUNCTION IMPLEMENTATION */
/*------------------------------------------------------------------------------------*/
//--------------------------------------------------------------------------------------
//--- Rotina que converte um número decimal para 7 Segmentos ---------------------------
void Decimal_to_7Segment(uint8_t i){
if (i > 9){
i = 0;
}
IOCLR1 = tabela[i];
}
while(1){
Página 25
1° Edição 03/2011
Decimal_to_7Segment(uni); // Chama Decimal_to_7Segment() para exibir unidade
for (j = 0; j < 5000; j++ ) asm volatile ("NOP"); // Espera
Página 26
1° Edição 03/2011
Portabilidade e o Pré-processador C
Um código portável possui módulos que são reutilizados quando se migra
de uma plataforma de desenvolvimento para outra ou de um modelo de
microcontrolador para outro.
Ao se modularizar um código, tomando-se os cuidados para torná-lo
portável, a maior parte dos módulos são reutilizados exigindo do programador o
trabalho de reajustar somente os módulos que comandam os dispositivos
periféricos que são particulares a um determinado modelo de microcontrolador.
Deste modo, "Portabilidade" significa escrever o seu programa (código), de
tal forma que o código funcione mesmo em ambientes diferentes, isto é, em
vários processadores, sistemas operacionais, versões de bibliotecas, etc.
Se o programa for portável, basta recompilar o código em um sistema novo
e ele deverá rodar sem problemas.
Por outro lado, os códigos não portáteis geram muitos problemas de
manutenção, controle de versões, possuem legibilidade ruim e são de difícil
compreensão.
O uso criterioso das diretivas do pré-processador auxiliam a tornar o
código portável.
Um pré-processador é um programa que recebe texto e efetua conversões
léxicas nele. As conversões podem incluir substituição de macros, inclusão
condicional e inclusão de outros arquivos.
A linguagem de programação C possui um pré-processador que efetua as
seguintes transformações:
Substitui trígrafos por equivalentes;
Concatena arquivos de código-fonte;
Substitui comentários por espaços em branco;
Reage a linhas iniciadas com um caractere de cardinal (#),
efetuando substituição de macros, inclusão de arquivos, inclusão
condicional e outras operações.
Segue dois exemplos de uso do pré-processador:
Exemplo 1: O CRC de um Frame MODBUS pode ser calculado de duas
maneiras. A primeira é utilizando tabelas e a segunda é por meio de expressão
aritmética que realiza o cálculo do CRC bit a bit.
Utilizar tabela consome mais memória enquanto calcular bit a bit requer
maior processamento. Deste modo, o melhor método a ser utilizado depende
dos recursos de processamento disponíveis no µC utilizado.
A Figura 13 mostra o uso do pré-processador para facilitar a escolha do
método de cálculo do CRC-16. Caso a macro USE_CRC_TABLE for igual a 1
o CRC-16 será calculado por meio de tabela que exigirá mais memória, mas
em contrapartida será mais rápido. Por outro lado, quando a macro
USE_CRC_TABLE for igual a 0, o cálculo do CRC será realizado por meio de
expressão aritmética que calcula o CRC bit a bit, o que exigirá maior
processamento.
Página 27
1° Edição 03/2011
Página 28
1° Edição 03/2011
Tipos Primitivos em C
Página 29
1° Edição 03/2011
MICROCONTROLADORES 8, 16 e 32 bit
Arquitetura Tipo n bit n byte Escala de Valores
8 bit int 8 1 -128 a 127
16 bit int 16 2 -32.768 a 32.767
32 bit int 32 4 –2.147.483.648 a 2.147.438.647
8 bit unsigned int 8 1 0 a 255
16 bit unsigned int 16 2 0 a 65.535
32 bit unsigned int 32 4 0 a 4.294.967.295
MUDANÇA DE PLATAFORMA
DE PARA
32 bit 16 ou 8 bit
16 bit 8 bit
Página 30
1° Edição 03/2011
Esse padrão criou o int8_t que especifica o tamanho do inteiro que está
sendo utilizado permitindo que o programador tome providências quando a
operação não for atômica.
TIPO DESCRIÇÃO
int8_t Inteiro de 8 bit com sinal
uint8_t Inteiro de 8 bit sem sinal
int16_t Inteiro de 16 bit com sinal
uint16_t Inteiro de 16 bit sem sinal
int32_t Inteiro de 32 bit com sinal
uint32_t Inteiro de 32 bit sem sinal
int64_t Inteiro de 64 bit com sinal
uint64_t Inteiro de 64 bit sem sinal
Página 31
1° Edição 03/2011
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
3.3V
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PW M2/EINT2
DIODE 33
P0.8/TxD1/PWM4/AD1.1
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
P0.11/CTS1/CAP1.1/SCL1
37 R2
38 2k2
47k P0.12/DSR1/MAT1.0/AD1.3
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41 3.3V
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5
46
P0.16/EINT0/MAT0.2/CAP0.2
47
P0.17/CAP1.2/SCK1/MAT1.2
53
P0.18/CAP1.3/MISO1/MAT1.3 300
54
P0.19/MAT1.2/MOSI1/CAP1.2 300
55
P0.20/MAT1.3/SSEL1/EINT3 330
1
P0.21/PW M5/AD1.6/CAP1.3 300
2
P0.22/AD1.7/CAP0.0/MAT0.0 300
58 300
P0.23
300
9
P0.25/AD0.4/AOUT
10
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1
13
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3
15
P0.30/AD0.3/EINT3/CAP0.0
17
P0.31
16
P1.16/TRACEPKT0
3.3V 12
10
11
12
13
3
P1.17/TRACEPKT1
49 8
VBAT P1.18/TRACEPKT2
P1.19/TRACEPKT3
4 U2
63 48 74HCT164
VREF P1.20/TRACESYNC
1D
7 44
V3A P1.21/PIPESTAT0
SRG8
51 40
V3 P1.22/PIPESTAT1
43 36
V3 P1.23/PIPESTAT2
C1/->
23 32
V3 P1.24/TRACECLK
28
&
P1.25/EXTIN0
R
59 24
VSSA P1.26/RTCK
50 64 3.3V
VSS P1.27/TDO
8
1
2
42 60
9
VSS P1.28/TDI
25 56
VSS P1.29/TCK
18 52
VSS P1.30/TMS
6 20
VSS P1.31/TRST
LPC2138
Figura 16 – Acionamento de display de 7 Segmentos com shift register.
Tabela 03 – Conexão dos pinos do shift register 74HCT164 com os segmentos do display
Página 32
1° Edição 03/2011
Página 33
1° Edição 03/2011
uint8_t num = 0;
uint8_t j = 0;
switch (i)
{
case 0: num = 0b00000001; break; // Escreve 0 no display
case 1: num = 0b01001111; break; // Escreve 1 no display
case 2: num = 0b00010010; break; // Escreve 2 no display
case 3: num = 0b00000110; break; // Escreve 3 no display
case 4: num = 0b01001100; break; // Escreve 4 no display
case 5: num = 0b00100100; break; // Escreve 5 no display
case 6: num = 0b01100000; break; // Escreve 6 no display
case 7: num = 0b00001111; break; // Escreve 7 no display
case 8: num = 0b00000000; break; // Escreve 8 no display
case 9: num = 0b00000100; break; // Escreve 9 no display
default: num = 0b00000001; // Escreve 0 no display
}
while(1){
Serialize_to_Display(cont);
Página 34
1° Edição 03/2011
Exercício Proposto
22pF
X1 U1
CRYSTAL
C2 FREQ=12MHz 62 19
3.3V
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22 R25
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6 2k2
3.3V 29
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
3.3V
P0.8/TxD1/PWM4/AD1.1
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35 R24
P0.10/RTS1/CAP1.0/AD1.2
37
P0.11/CTS1/CAP1.1/SCL1
38
47k P0.12/DSR1/MAT1.0/AD1.3 2k2
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41 3.3V 3.3V 3.3V
P0.14/DCD1/EINT1/SDA1
45
3.3V
P0.15/RI1/EINT2/AD1.5
46 R2
P0.16/EINT0/MAT0.2/CAP0.2
47
P0.17/CAP1.2/SCK1/MAT1.2
53
P0.18/CAP1.3/MISO1/MAT1.3 2k2 300 300 300
54
P0.19/MAT1.2/MOSI1/CAP1.2 300 300 300
55
P0.20/MAT1.3/SSEL1/EINT3 330 330 330
1
P0.21/PWM5/AD1.6/CAP1.3 300 300 300
2
P0.22/AD1.7/CAP0.0/MAT0.0 300 300 300
58 300 300 300
P0.23
300 300 300
9
P0.25/AD0.4/AOUT
10
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1
13
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3
15
P0.30/AD0.3/EINT3/CAP0.0
17
P0.31
16
P1.16/TRACEPKT0
3.3V 12
10
11
12
13
10
11
12
13
10
11
12
13
3
6
P1.17/TRACEPKT1
49 8
VBAT P1.18/TRACEPKT2
P1.19/TRACEPKT3
4 U2 U3 U4
63 48 74HCT164 74HCT164 74HCT
VREF P1.20/TRACESYNC
1D
1D
1D
7 44
V3A P1.21/PIPESTAT0
SRG8
SRG8
SRG8
51 40
V3 P1.22/PIPESTAT1
43 36
V3 P1.23/PIPESTAT2
C1/->
C1/->
C1/->
23 32
V3 P1.24/TRACECLK
28
&
&
&
P1.25/EXTIN0
R
59 24
VSSA P1.26/RTCK
50 64 3.3V U3(MR) U4(MR)
VSS P1.27/TDO
8
1
2
1
2
1
2
42 60
9
VSS P1.28/TDI
25 56
VSS P1.29/TCK
18 52
VSS P1.30/TMS
6 20
VSS P1.31/TRST
LPC2138
Figura 17 – Acionamento de três displays de 7 segmentos com shift register.
Página 35
1° Edição 03/2011
Teclado Matricial
Crie uma rotina para varrer o teclado matricial 4x4 apresentado na Figura
11. Toda vez que uma tecla numérica do teclado for pressionada, o número
correspondente deve ser exibido no display.
Os diodos D2, D3, D4 e D5 são utilizados em série com as linhas do
teclado para proporcionar proteção para os pinos do microcontrolador,
impedindo que qualquer falha de configuração nos pinos venha a danificá-los.
Por exemplo, se os pinos P1.16 e P1.28 forem configurados como saída e um
deles assumir o nível lógico alto e o outro baixo, quando a tecla 7 for
pressionada, ocorrerá um curto circuito nos pinos que poderá resultar em
danos permanentes de hardware. Os diodos utilizados neste tipo de aplicação
são, em geral, diodos de sinal do tipo 1N914 ou 1N4148.
3.3V
C1
22pF
X1 U1 U2:B
C2 CRYSTAL
62 19 3 4
R7
FREQ=12MHz XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0 300
22
P0.2/SCL0/CAP0.0 74HCT04
22pF 3
RTXC1 P0.3/SDA0/MAT0..0/EINT1
26 U2:A
5 27 R3
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29 1 2
P0.5/MISO0/MAT0.1/AD0.7
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0 300
31
P0.7/SSEL0/PWM2/EINT2 74HCT04
DIODE
P0.8/TxD1/PWM4/AD1.1
33 U2:C
34 R4
R1 C3 P0.9/RxD1/PWM6/EINT3
35 5 6
P0.10/RTS1/CAP1.0/AD1.2
37
P0.11/CTS1/CAP1.1/SCL1 300
47k P0.12/DSR1/MAT1.0/AD1.3
38 U2:D
74HCT04
100pF 39 R5
P0.13/DTR1/MAT1.1/AD1.4
41 13 12
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5 300
74HCT04
P0.16/EINT0/MAT0.2/CAP0.2
46 R2 U2:E
47 R6
P0.17/CAP1.2/SCK1/MAT1.2
53 11 10
P0.18/CAP1.3/MISO1/MAT1.3 2k2
54 3.3V
P0.19/MAT1.2/MOSI1/CAP1.2 300
P0.20/MAT1.3/SSEL1/EINT3
55 U2:F
74HCT04
1 R8
P0.21/PWM5/AD1.6/CAP1.3
2 9 8
P0.22/AD1.7/CAP0.0/MAT0.0
58
P0.23 300
74HCT04
P0.25/AD0.4/AOUT
9 U3:A
10 R9
P0.26/AD0.5
11 1 2
P0.27/AD0.0/CAP0.1/MAT0.1
13 300
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3 74HCT04
15
P0.30/AD0.3/EINT3/CAP0.0
17
P0.31 D2
3.3V
P1.16/TRACEPKT0
P1.17/TRACEPKT1
16
12
A 7 8 9
49 8
VBAT P1.18/TRACEPKT2
4 D3
P1.19/TRACEPKT3
63
7
VREF
V3A
P1.20/TRACESYNC
P1.21/PIPESTAT0
48
44
B 4 5 6
51 40 3.3V
43
V3 P1.22/PIPESTAT1
36 D4
V3 P1.23/PIPESTAT2
23
V3 P1.24/TRACECLK
P1.25/EXTIN0
32
28
C 1 2 3
59 24
50
VSSA P1.26/RTCK
64 D5
+
VSS P1.27/TDO
42
25
VSS
VSS
P1.28/TDI
P1.29/TCK
60
56 R10
10k
R11
10k
R12
10k
R13
10k
D 0 =
18 52
VSS P1.30/TMS
1
6 20
VSS P1.31/TRST
LPC2138
Página 36
1° Edição 03/2011
Programa
#include "LPC214x.h"
#include "cpu_init.h"
#include <stdint.h> // Biblioteca que define o tamanho exato do tipo primitivo
/*------------------------------------------------------------------------------------*/
/* DEFINITIONS AND MACROS */
/*------------------------------------------------------------------------------------*/
#define LINHA_A (1<<16)
#define LINHA_B (1<<17)
#define LINHA_C (1<<18)
#define LINHA_D (1<<19)
//--------------------------------------------------------------------------------------
//--- Rotina que converte um número decimal para 7 Segmentos ---------------------------
void Decimal_to_7Segment(uint8_t i){
switch (i)
{
case 0: IOSET0 |= seg_a|seg_b|seg_c|seg_d|seg_e|seg_f; break; // 0 no display
case 1: IOSET0 |= seg_b|seg_c; break; // 1 no display
case 2: IOSET0 |= seg_a|seg_b|seg_d|seg_e|seg_g; break; // 2 no display
case 3: IOSET0 |= seg_a|seg_b|seg_c|seg_d|seg_g; break; // 3 no display
case 4: IOSET0 |= seg_b|seg_c|seg_f|seg_g; break; // 4 no display
case 5: IOSET0 |= seg_a|seg_c|seg_d|seg_f|seg_g; break; // 5 no display
case 6: IOSET0 |= seg_a|seg_c|seg_d|seg_f|seg_e|seg_g; break; // 6 no display
case 7: IOSET0 |= seg_a|seg_b|seg_c; break; // 7 no display
case 8: IOSET0 |= seg_a|seg_b|seg_c|seg_d|seg_e|seg_f|seg_g; break; //8 no display
case 9: IOSET0 |= seg_a|seg_b|seg_c|seg_f|seg_g; break; // Escreve 9 no display
default: break; // Escreve 0 no display
}
}
//--------------------------------------------------------------------------------------
//--- Rotina que varre o teclado -------------------------------------------------------
uint8_t Varre_Teclado(void){
Página 37
1° Edição 03/2011
if (!(IOPIN1 & COLUNA_3)){
i = 6;
while (!(IOPIN1 & COLUNA_3)){ asm volatile ("NOP");} // Aguarda soltar botão
}
IOSET1 |= LINHA_B; // Nível alto na Linha B
IOCLR1 |= LINHA_C; // Nível baixo na Linha C
if (!(IOPIN1 & COLUNA_1)){
i = 1;
while (!(IOPIN1 & COLUNA_1)); // Aguarda soltar botão
}
if (!(IOPIN1 & COLUNA_2)){
i = 2;
while (!(IOPIN1 & COLUNA_2)); // Aguarda soltar botão
}
if (!(IOPIN1 & COLUNA_3)){
i = 3;
while (!(IOPIN1 & COLUNA_3)); // Aguarda soltar botão
}
IOSET1 |= LINHA_C; // Nível baixo na Linha A
IOCLR1 |= LINHA_D; // Nível baixo na Linha A
if (!(IOPIN1 & COLUNA_2)){
i = 0;
while (!(IOPIN1 & COLUNA_2)); // Aguarda soltar botão
}
IOSET1 |= LINHA_D; // Nível alto na Linha D
return(i);
}
//--------------------------------------------------------------------------------------
//--- Rotina Principal -----------------------------------------------------------------
int main (void)
{
cpu_init(); // Chama a rotina de inicialização da CPU
while(1){
k = Varre_Teclado(); // Varre o teclado
if (k != 10){
Decimal_to_7Segment(k);
}
}
return(0);
}
Exercício Proposto
Exercício 01: Crie um programa para varrer o teclado e acionar três displays
de 7 segmentos, conforme mostrado na Figura 12. Quando uma tecla for
pressionada, o número, correspondente a tecla pressionada, deverá ser exibido
no display da unidade e o número que estava sendo exibido na unidade deverá
ser deslocado para o display da dezena. Do mesmo modo, o número que
estava sendo exibido no display da dezena deverá ser deslocado para o
display da centena.
Página 38
1° Edição 03/2011
X1 U1
CRYSTAL
REQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1 300 300 300
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0 300 300 300
22
P0.2/SCL0/CAP0.0 330 330 330
3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1 300 300 300
5 27
RTXC2 P0.4/SCK0/CAP0.1/AD0.6 300 300 300
29
P0.5/MISO0/MAT0.1/AD0.7 300 300 300
57 30
RST P0.6/MOSI0/CAP0.2/AD1.0 300 300 300
31
P0.7/SSEL0/PWM2/EINT2
33
P0.8/TxD1/PWM4/AD1.1
34
C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
37
P0.11/CTS1/CAP1.1/SCL1
38
P0.12/DSR1/MAT1.0/AD1.3
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5
10
11
12
13
10
11
12
13
10
11
12
13
3
6
46
P0.16/EINT0/MAT0.2/CAP0.2
P0.17/CAP1.2/SCK1/MAT1.2
47 U2 U3 U4
53 74HCT164 74HCT164 74HCT
P0.18/CAP1.3/MISO1/MAT1.3
1D
1D
1D
54
P0.19/MAT1.2/MOSI1/CAP1.2
SRG8
SRG8
SRG8
55
P0.20/MAT1.3/SSEL1/EINT3
1
P0.21/PWM5/AD1.6/CAP1.3
C1/->
C1/->
C1/->
2
P0.22/AD1.7/CAP0.0/MAT0.0
58
&
&
&
P0.23
R
9 3.3V U3(MR) U4(MR)
P0.25/AD0.4/AOUT
1
2
1
2
1
2
10
9
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1
13
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3
15
P0.30/AD0.3/EINT3/CAP0.0
17
P0.31 D2
3.3V
P1.16/TRACEPKT0
P1.17/TRACEPKT1
16
12
A 7 8 9
49 8
VBAT P1.18/TRACEPKT2
4 D3
P1.19/TRACEPKT3
63
7
VREF
V3A
P1.20/TRACESYNC
P1.21/PIPESTAT0
48
44
B 4 5 6
51 40 3.3V
43
V3 P1.22/PIPESTAT1
36 D4
V3 P1.23/PIPESTAT2
23
V3 P1.24/TRACECLK
P1.25/EXTIN0
32
28
C 1 2 3
59 24
50
VSSA P1.26/RTCK
64 D5
+
VSS P1.27/TDO
42
25
VSS
VSS
P1.28/TDI
P1.29/TCK
60
56 R2
10k
R3
10k
R4
10k
R5
10k
D 0 =
18 52
VSS P1.30/TMS
4
6 20
VSS P1.31/TRST
LPC2138
Página 39
1° Edição 03/2011
C1
22pF LCD
X1 U1
LM016L
CRYSTAL
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
P0.5/MISO0/MAT0.1/AD0.7
VDD
VSS
VEE
57 30
RW
RS
D0
D1
D2
D3
D4
D5
D6
D7
RST P0.6/MOSI0/CAP0.2/AD1.0
E
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
P0.8/TxD1/PWM4/AD1.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
37
P0.11/CTS1/CAP1.1/SCL1
38
47k P0.12/DSR1/MAT1.0/AD1.3
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5
46
P0.16/EINT0/MAT0.2/CAP0.2
47
P0.17/CAP1.2/SCK1/MAT1.2
53
P0.18/CAP1.3/MISO1/MAT1.3
54
P0.19/MAT1.2/MOSI1/CAP1.2
55
P0.20/MAT1.3/SSEL1/EINT3
1
P0.21/PWM5/AD1.6/CAP1.3
2
P0.22/AD1.7/CAP0.0/MAT0.0
58
P0.23
9
P0.25/AD0.4/AOUT
10
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1
13
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3
15
P0.30/AD0.3/EINT3/CAP0.0
17
P0.31
16
P1.16/TRACEPKT0
3.3V 12
P1.17/TRACEPKT1
49 8
VBAT P1.18/TRACEPKT2
4
P1.19/TRACEPKT3
63 48
VREF P1.20/TRACESYNC
7 44
V3A P1.21/PIPESTAT0
51 40
V3 P1.22/PIPESTAT1
43 36
V3 P1.23/PIPESTAT2
23 32
V3 P1.24/TRACECLK
28
P1.25/EXTIN0
59 24
VSSA P1.26/RTCK
50 64
VSS P1.27/TDO
42 60
VSS P1.28/TDI
25 56
VSS P1.29/TCK
18 52
VSS P1.30/TMS
6 20
3.3V
VSS P1.31/TRST
LPC2138 R25
2k2
Resolução:
Página 40
1° Edição 03/2011
Programa
#include "LPC214x.h"
#include "cpu_init.h"
#include "iprintf.h" // Separa uma string em caracteres para poder enviá-los serialmente
#include "lcd.h" // Módulo com rotinas de inicialização e operação do LCD
#include "stdint.h" // Standard C data types
int main(void)
{
cpu_init(); // Chama a rotina de inicialização da CPU
uint16_t i=0;
while(1){
if (!(IOPIN1 & button)) // Verifica se o Botão foi pressionado
{
i++;
while (!(IOPIN1 & button)); // Espera soltar botão
lcd_line2(); // Leva o cursor do display para o início da linha 2
iprintf("Contador:%d",i); // Escreve string na linha
}
}
return 0;
}
//------------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------------
//---------------------------------------------------------------------
void lcd_init(void)
{
// P0.10, P0.11, P0.12 e P0.13 como entrada/saída (2 bits de configuração cada pino)
PINSEL0 &= ~((1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24)|(1<<25)|(1<<26)|(1<<27));
// P0.21, P0.22, P0.28 e P0.29 como entrada/saída (2 bits de configuração cada pino)
PINSEL1 &= ~((1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<24)|(1<<25)|(1<<26)|(1<<27));
// Força nível lógico baixo nos pinos E, RS, RW, D7, D6, D5 e D4
IOCLR0 = LCD_DATA_MASK|LCD_CONTROL_MASK;
Página 41
1° Edição 03/2011
/*------------------------------------------------------------------------------------*/
/* DEFINITIONS AND MACROS */
/*------------------------------------------------------------------------------------*/
#define E (1<<28) //!< Pino que liga/desliga o LCD, conectado no pino P0.20 do LPC2148
#define RS (1<<22) //!< Informa ao LCD se a informação é um comando ou dado, conectado
no pino P0.22 do LPC2148
#define RW (1<<29) //!< Pino que informa se a operação é de leitura ou escrita,
conectado no pino P0.29 do LPC2148 (0 = write to LCD module, 1 = read from LCD module)
#define busyflag (1<<13) //!< Verifica se o LCD está ocupado, isto é pronto para receber
o próximo comando.
#define DB4 (1<<10) //!< Pino de dado DB4 (LSB), conectado ao pino P0.10 do LPC2148
#define DB5 (1<<11) //!< Pino de dado DB5, conectado ao pino P0.11 do LPC2148
#define DB6 (1<<12) //!< Pino de dado DB6, conectado ao pino P0.12 do LPC2148
#define DB7 (1<<13) //!< Pino de dado DB4 (MSB), conectado ao pino P0.13 do LPC2148
#define LUZ (1<<21) //!< Liga/desliga a backlight do LCD, conectado no pino P0.21 do
LPC2148
Exercício Proposto
C1
22pF LCD
X1 LM016L
CRYSTAL
U1
C2 FREQ=12MHz 62 19
XTAL1 P0.0/TxD0/PWM1
61 21
XTAL2 P0.1/RxD0/PWM3/EINT0
22
P0.2/SCL0/CAP0.0
22pF 3 26
RTXC1 P0.3/SDA0/MAT0..0/EINT1
5 27
3.3V D1 RTXC2 P0.4/SCK0/CAP0.1/AD0.6
29
P0.5/MISO0/MAT0.1/AD0.7
VDD
VSS
VEE
57 30
RW
RS
D0
D1
D2
D3
D4
D5
D6
D7
RST P0.6/MOSI0/CAP0.2/AD1.0
E
31
P0.7/SSEL0/PWM2/EINT2
DIODE 33
P0.8/TxD1/PWM4/AD1.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
34
R1 C3 P0.9/RxD1/PWM6/EINT3
35
P0.10/RTS1/CAP1.0/AD1.2
37
P0.11/CTS1/CAP1.1/SCL1
38
47k P0.12/DSR1/MAT1.0/AD1.3
100pF 39
P0.13/DTR1/MAT1.1/AD1.4
41
P0.14/DCD1/EINT1/SDA1
45
P0.15/RI1/EINT2/AD1.5
46
P0.16/EINT0/MAT0.2/CAP0.2
47
P0.17/CAP1.2/SCK1/MAT1.2
53
P0.18/CAP1.3/MISO1/MAT1.3
54
P0.19/MAT1.2/MOSI1/CAP1.2
55
P0.20/MAT1.3/SSEL1/EINT3
1
P0.21/PWM5/AD1.6/CAP1.3
2
P0.22/AD1.7/CAP0.0/MAT0.0
58
P0.23
9
P0.25/AD0.4/AOUT
10
P0.26/AD0.5
11
P0.27/AD0.0/CAP0.1/MAT0.1
13
P0.28/AD0.1/CAP0.2/MAT0.2
14
P0.29/AD0.2/CAP0.3/MAT0.3
15
P0.30/AD0.3/EINT3/CAP0.0
17
P0.31 D2
3.3V
P1.16/TRACEPKT0
P1.17/TRACEPKT1
16
12
A 7 8 9
49 8
VBAT P1.18/TRACEPKT2
4 D3
P1.19/TRACEPKT3
63
7
VREF
V3A
P1.20/TRACESYNC
P1.21/PIPESTAT0
48
44
B 4 5 6
51 40 3.3V
43
V3 P1.22/PIPESTAT1
36 D4
V3 P1.23/PIPESTAT2
23
V3 P1.24/TRACECLK
P1.25/EXTIN0
32
28
C 1 2 3
59 24
50
VSSA P1.26/RTCK
64 D5
+
VSS P1.27/TDO
42
25
VSS
VSS
P1.28/TDI
P1.29/TCK
60
56 R12
10k
R13
10k
R14
10k
R15
10k
D 0 =
18 52
VSS P1.30/TMS
1
6 20
VSS P1.31/TRST
LPC2138
Página 42
1° Edição 03/2011
Sinais de dados: MOSI (Master data Output, Slave data Input) e MISO
(Master data Input, Slave data Output) são responsáveis pela
transferência de dados entre o master e o slave;
SCLK
MOSI
Master MISO Slave
SCLK
SCLK SCLK
MOSI MOSI
MISO MISO Slave 01
SPI Master
SS1 SS
SS2
SS3
SCLK
MOSI
MISO Slave 02
SS
SCLK
MOSI
MISO Slave 03
SS
Página 43
1° Edição 03/2011
Operações “ATOMIC”
OPERAÇÕES “ATOMIC”
TIPO µC de 8bit µC de 16bit µC de 32bit
int8_t
uint8_t
int16_t
uint16_t
int32_t
uint32_t
int64_t
uint64_t
Página 44
1° Edição 03/2011
Página 45
1° Edição 03/2011
Página 46
1° Edição 03/2011
Figura 26 - Operação não atômica de uma variável conhecida como “tick conter”,
utilizada na temporização “time out” dos frames em um protocolo MODBUS.
Página 47
1° Edição 03/2011
Figura 27 - Operação atômica de uma variável conhecida como “tick conter”, utilizada na
temporização “time out” dos frames em um protocolo MODBUS.
Página 48
1° Edição 03/2011
“STRUCTURE PADDING”
E
SERIALIZAÇÃO
Página 49
1° Edição 03/2011
Página 50
1° Edição 03/2011
Figura 31 – Exemplo de “Structure Padding”.
Página 51
1° Edição 03/2011
Página 52
1° Edição 03/2011
Figura 35 – Exemplo de Requisição e Resposta de Frame MODBUS.
Página 53
1° Edição 03/2011
Página 54
1° Edição 03/2011
A Figura 38 mostra uma rede MODBUS RTU que utiliza o meio físico
RS485. Esta figura também mostra o código da estrutura do ModFrame e o
código da rotina que envia os bytes do Frame MODBUS pela interface serial.
A presença do “Padding”, neste exemplo, traz as seguintes desvantagens:
Diminui a portabilidade;
Página 55
1° Edição 03/2011
Página 56
1° Edição 03/2011
Tipo de Identificador
Escala de Valores
Dados Sugerido
char Especificação do Compilador c
char8 uint8_t c8
int8_t -128 a 127 i8
uint8_t 0 a 255 u8
int16_t -32768 a 32767 i16
uint16_t 0 a 65535 u16
int32_t –2.147.483.648 a 2.147.438.647 i32
uint32_t 0 a 4.294.967.295 u32
-9.223.372.036.854.775.808 a
int64_t +9.223.372.036.854.775.807 i64
uint64_t 0 a +18.446.744.073.709.551.615 u64
float32 ver IEEE 754 (float) f32
float64 ver IEEE 754 (double) f64
Página 57
1° Edição 03/2011
uint8_t u8_VelocidadeDoCarro = 0;
uint16_t u16_AirTemperature = 0;
Identificador
Modificador de Tipo
Sugerido
Arrays a
Enumeração ( enum ) en
Pointers p
Structures ( struct ) st
Exemplo:
uint16_t *p_VelocidadeDoCarro;
p_VelocidadeDoCarro =&VelocidadeDoMercedes;
Página 58
1° Edição 03/2011
REGRAS MISRA
Evitar o uso de comentários do tipo /* xxx */ dentro do corpo de funções.
Exemplo:
Correto Evitar
/*******************************
* Inicializar_CPU void Inicializar_CPU(void)
********************************/ {
/* Inicializar CPU */
void Inicializar_CPU(void) ..
{ }
..
}
Constantes
Por exemplo:
ToneladasDeLaranja = 120;
ToneladasDePera = 071;
Chaves
Chaves não podem ser evitadas, elas devem ser alocadas em uma linha
própria, exceto na inicialização de array, quando vier após while em laços do
tipo do-while ou após definição de nomes de tipos - Typedef.
Página 59
1° Edição 03/2011
Exemplo:
Correto Evitar
if (u8_Largura != 10)
{ if (u16_Largura < 1000)
CalculaVolume( ); {
} u32_Area = u16_Altura * u16_Largura;
}
Exercício Proposto
Página 60
1° Edição 03/2011
Referências
Edição e Revisão
Eng. Gilson Fonseca Peres Filho
Universidade Federal de Uberlândia gilsonfonseca@yahoo.com.br
Faculdade de Engenharia Elétrica Possui graduação em Engenharia Elétrica pela Universidade Federal de
Disciplina de Sistemas Embarcados Uberlândia (2001). Tem experiência na área de Engenharia Elétrica,
www.feelt.ufu.br com ênfase em Eletrônica Industrial, Sistemas e Controles Eletrônicos,
programação em C, C++, Java e Python, atuando principalmente nos
seguintes temas: processamento paralelo, PLCs, sistemas de aquisição
de dados, redes industriais fieldbus, protocolos de comunicação
Prof. Fábio Vincenzi R. da Silva digitais, softwares para dispositivos móveis, sistemas embarcados e
aplicações para área de TI.
Página 61