Sunteți pe pagina 1din 48

1

Tecnologia Educacional Personalpic









Introduo
As circunstncias que se nos deparam hoje no campo dos microcontroladores tm os seus
primrdios no desenvolvimento da tecnologia dos circuitos integrados. Este desenvolvimento tornou
possvel armazenar centenas de milhares de transistores num nico chip. Isso constituiu um pr-
requisito para a produo de microprocessadores e, os primeiros computadores foram construdos
adicionando perifricos externos tais como memria, linhas de entrada e sada, temporizadores e
outros. Um crescente aumento do nvel de integrao, permitiu o aparecimento de circuitos
integrados contendo simultaneamente processador e perifrico. Foi assim que o primeiro chip
contendo um microcomputador e que mais tarde haveria de ser designado por microcontrolador,
apareceu.
Estima-se que, em poucos anos, em mdia uma pessoa interagir com 300 dispositivos
microcontroladores diariamente;


MICROCHIP

A Microchip uma empresa norte americana, fundada em 1989, com sede na cidade de
Chandler, Arizona. Desenvolve, fabrica e comercializa microcontroladores (PIC), memrias seriais
(I2C e SPI), produtos para segurana (Keeloq), identificadores por RF (RFID), conversores A/D,
circuitos integrados de superviso (Bronw out) e amplificadores operacionais.

Principais Endereos:
Estados Unidos:
Corporate Headquarters Microchip Technology Inc
2355 West Chandler Blvd. Chandler, Arizona, USA 85224-6199
T.: (480) 786-7200 (480) FAX: 899-9210
Brasil:
A Microchip representada no Brasil pela empresa Artimar.
Distribuidores autorizados: Aut-Comp, Future e Hitech.


Reviso
Um microcontolador PIC um sistema computacional completo, no qual esto includos uma
CPU (Central Processor Unit), memria, um sistema de clock, sinais de I/O (Input/Output), alm
de outros possveis perifricos, tais como, mdulos de temporizao e conversores A/D entre
outros, integrados em um mesmo componente (chip). As partes mais integrantes de qualquer
computador, e que tambm esto presentes, em menor escala, nos microcontroladores so:

2


Unidade Central de Processamento (CPU);
Sistema de Clock para dar seqncia s atividades da CPU;
Memria para armazenamento de instrues e manipulao de dados;
Entradas para interiorizar na CPU informaes do mundo externo;
Sadas para exteriorizar as informaes processadas pela CPU para o mundo externo;
Programa (Software) para que o sistema faa alguma coisa til.


Arquiteturas dos Microcontroladores PIC

A arquitetura de um sistema digital define quem so e como as partes que compe o sistema
esto interligadas. As duas arquiteturas (Arquitetura de Harvard, Arquitetura de Von Neuman).
Arquitetura de Harvard: A Unidade Central de Processamento interligada a memria de
dados e a memria de programa por barramento especfico.
O PIC possui arquitetura Harvard. A memria de dados do tipo RAM (voltil) e , no caso do
16F877, a memria de programa do tipo Flash (letra F no cdigo). O barramento de dados de 8
bits e o de instrues composto de 16 bits.
Este tipo de arquitetura permite que, enquanto uma instruo executada, outra seja
buscada da memria, o que torna o processamento mais rpido.

Filosofia RISC
Como o barramento de instrues maior do que 8 bits, o OPCODE da instruo j inclui o
dado e o local onde ela vai operar (quando necessrio), o que significa que apenas uma posio de
memria utilizada por instruo, economizando assim muita memria de programa. Dessa
forma, podemos observar que dentro da palavra do OPCODE, que pode ser de 12, 14 ou 16 bits, no
sobra muito espao para o cdigo da instruo propriamente dito.
Por isso, os PICs utilizam uma tecnologia chamada RISC, que significa Reduced
Instruction Set Computer (Computador com Set de Instrues Reduzido).

PICs:
RISC
Cerca de 35 instrues
Aprendizado mais fcil e dinmico
Desvantagem com a ausncia de determinadas funes (Ex: Funes de multiplicao e
diviso devem ser implementadas)

Estruturao Interna
ULA (Unidade Lgica Aritmtica);
Registrador W (work = trabalho);
Memria de Programa Bus de 14 bits;
Memria de Dados RAM Bus de 8 bits;
Portas: PORTA, B, C e D Pinos de I/O;
EEPROM (Memria de Dados No voltil);
Timers: TIMER0, TIMER1 e TIMER2
Comparador - Mdulo CCP (Capture, Compare e PWM);
Porta Serial USART;
Registrador STATUS;
Contador de Linha de Programa PC (Program Counter);
Pilha de 8 Nveis STACK;
Circuitos Internos: Reset, Osciladores, Watchdog Timer (WDT), Power-up e Brown-out.

Unidade Lgica Aritmtica (ULA)

Unidade Lgica Aritmtica (ULA): onde todas as operaes lgicas (funes lgicas
booleanas: e ou, exclusivo e complemento) e aritmticas (soma e subtrao) so efetuadas. O
registrador W sempre estar envolvido de alguma forma em toda operao lgica ou aritmtica.

3

Existem dois destinos possveis para estas operaes: o W (work) ou um registrador (posio da
memria de dados) definido no argumento da instruo.
Timer: O PIC possu internamente um recurso de hardware denominado Timer0. Trata-
se de um contador de 8bits incrementado internamente pelo ciclo de mquina ou por um sinal
externo (borda de subida ou descida), sendo esta opo feita por software durante a
programao (SFR). Como o contador possui 8 bits ele pode assumir 256 valores distintos (0 at
255). Caso o ciclo de mquina seja de 1us, cada incremento do Timer corresponder a um intervalo
de 1us. Caso sejam necessrio intervalos de tempos maiores para o mesmo Ciclo de Mquina,
utilizamos o recurso de PRE-SCALE.

Ciclos de Mquina

Nos microcontroladores PIC, o sinal de clock internamente dividido por quatro. Portanto,
para um clock externo de 4MHz, temos um clock interno de 1 MHz e, conseqentemente, cada ciclo
de mquina dura 1s;
A diviso do clock por quatro forma as fases Q1, Q2, Q3 e Q4.
O program Counter incrementado automaticamente na fase Q1 do ciclo de mquina e a
instruo seguinte buscada da memria de programa e armazenada no registrador de
instrues no ciclo Q4. Ela decodificada e executada no prximo ciclo, no intervalo de Q1 e Q4. Essa
caracterstica de buscar a informao em um ciclo de mquina e execut-la no prximo chamada
de PIPELINE. Ela permite que quase todas as instrues sejam executadas em apenas um
ciclo, gastando assim 1 s (para um clock de 4 MHz) e tornando o sistema muito mais rpido. As
nicas excees referem-se s instrues que geram saltos no program counter, como
chamadas de rotinas e retornos.





Toda instruo do PIC demanda um
Ciclo de Mquina para ser executada,
exceto aquelas que provocam desvio no
programa (demandam dois Ciclos de
Mquina).


Memria de Programa

A memria de programao onde as instrues do programa so armazenadas. No caso do
16F877 esta memria de 8192 palavras (words) (8Kb) de 14 bits cada uma. Parte destes 14 bits
informam o OPCODE (cdigo da instruo) e o restante traz consigo o argumento da instruo
correspondente. Na famlia PIC existem trs tipos de memria de programa: EPROM (O.T.P.
One Time Programable), EEPROM (janelado) e FLASH.
Existem duas posies da memria do programa que recebem nomes especiais: vetor de reset
e vetor de interrupo.
O vetor de reset para onde o programa vai quando ele inicializado, enquanto que o vetor
de interrupo a posio da memria de programa para onde o processamento desviado
quando ocorre uma interrupo.

Memria de Programa

Vetor de Reset: Trata-se do primeiro endereo de programa que ser executado quando o
PIC comear a funcionar (aps a alimentao ou um reset).

4

Aponta para o endereo 0x00.
Vetor de Interrupo: As rotinas de interrupes sero armazenadas na rea de
programao, juntamente com todo resto do programa. No, entanto existe um endereo que
reservado para o incio do tratamento de todas as interrupes.
Vetor de Interrupo aponta para o endereo 0x04.
Pilha (STACK): A pilha um local, totalmente separado da memria de programao,
em que sero armazenados os endereos de retorno quando utilizarmos instrues de
chamadas de rotinas.

Memria de Dados

A memria de dados uma memria voltil do tipo RAM (Random Access Memory).
O mapa de memria divido em duas partes:

Registadores especiais (Special Function Register - SFR) e Registradores de uso geral (General
Purpose Register - GPR).
Como o ponteiro da memria de programa tem capacidade de enderear somente 128
posies de memria de cada vez (7 bits), a memria de programa dividida em bancos
(banco 0,1,2 e 3 no 16F877).
Esta diviso implica em termos posies de memria que somente podero ser acessadas caso
o banco a que ela pertena seja previamente selecionado atravs de um bit especfico do SFR
STATUS.

















5

Mapas das Memrias

Memria de Programa Memria de Dados
Interrupo

As Interrupes so causadas atravs de eventos assncronos (podem ocorrer a qualquer
momento) que causam um desvio no processamento. Este desvio tem como destino o vetor de
interrupo.
Uma boa analogia para melhor entendermos o conceito de interrupo a seguinte: voc
est trabalhando digitando uma carta no computador quando o seu ramal toca. Neste momento voc,
interrompe o que est fazendo, para atender ao telefone e verificar o que a pessoa do outro lado da
linha est precisando.
Terminada a conversa, voc coloca o telefone no gancho novamente e retoma o seu
trabalho do ponto onde havia parado. Observe que no precisamos verificar a todo instante, se
existe ou no algum na linha, pois quando o ramal chamado, o telefone toca avisando que
existe algum querendo falar com voc.

Interrupes no PIC
Interrupes de TIMERS (3);
Interrupo de fim de escrita na EEPROM;
Interrupo de comparador;
Interrupes de USART (2);
Interrupo de CCP;
Interrupo externa: Essa interrupo gerada por um sinal externo ligado a uma porta
especfica que no caso a porta RB0. Ela utilizada para diversas finalidades, como, por
exemplo o reconhecimento de um boto ou outro sinal do sistema que necessite de uma
ao imediata. Funciona somente na borda de subida ou descida dependendo da configurao.

6

Interrupo por mudana de estado: Ocorre tanto em borda de subida quanto em borda de descida.
Ligada s portas RB4, RB5, RB6 e RB7 simultaneamente.








7

O PIC16F877

Pinagem do PIC 16F877

Nome PINO N PINO TIPO Descrio
OSC1/CLKIN 13 I Entrada para cristal externo (fonte de clock)
OSC2/CLKOU 14 O Sada para cristal externo
MCLR/VPP 1 1 I/P Master Clear (reset) externo. Lgica baixa para reset
RA0/AN0 2 I/O I/O digital bidirecional ou entrada analgica 0
RA1/AN1 3 I/O I/O digital bidirecional ou entrada analgica 1
RA2/AN2/VREF- 4 I/O
I/O digital bidirecional ou entrada analgica 2 ou tenso de
referncia analgica negativa
RA3/AN3/VREF+ 5 I/O
I/O digital bidirecional ou entrada analgica 3 ou tenso de
referncia analgica positiva
RA4/T0CKI 6 I/O I/O digital bidirecional ou entrada de clock para contador TMR0
RA5/SS/AN4 7 I/O
I/O digital bidirecional ou entrada analgica 4 ou slave select
para a porta de comunicao serial sncrona
RB0/INT 33 I/O I/O digital bidirecional ou entrada para interrupo externa
RB1 34 I/O I/O digital bidirecional
RB2 35 I/O I/O digital bidirecional
RB3/PGM 36 I/O
I/O digital bidirecional ou entrada para programao em baixa
tenso
RB4 37 I/O I/O digital bidirecional

8

RB5 38 I/O I/O digital bidirecional
RB6/PGC 39 I/O I/O digital bidirecional ou clock da programao serial (ICSP)
RB7/PGD 40 I/O I/O digital bidirecional ou dados da programao serial (ICSP)
RC0/T1OSO/T1CK1 15 I/O
I/O digital bidirecional ou sada para cristal externo para TMR1
ou entrada de clock para contador TMR1
RC1/T1OSI/CCP2 16 I/O
I/O digital bidirecional ou entrada para cristal externo para
TMR1 ou I/O para Capture, Compare, PWM 2
RC2/CCP1 17 I/O I/O digital bidirecional ou I/O para Capture, Compare, PWM 1
RC3/SCK/SCL 18 I/O
I/O digital bidirecional ou entrada de clock serial sncrono ou
sada para os modos SPI e IC
RC4/SDI/SDA 23 I/O
I/O digital bidirecional ou entrada de dados SPI ou I/O de
dados IC
RC5/SDO 24 I/O I/O digital bidirecional ou sada de dados SPI
RC6/TX//CK 25 I/O
I/O digital bidirecional ou Transmisso para comunicao
USART assncrona ou via de clock para comunicao USART
sncrona
RC7/RX/DT 26 I/O
I/O digital bidirecional ou Recepo para comunicao USART
assncrona ou via de dados para comunicao USART sncrona
RD0/PSP0 19 I/O I/O digital bidirecional ou Porta paralela escrava
RD1/PSP1 20 I/O I/O digital bidirecional ou Porta paralela escrava
RD2/PSP2 21 I/O I/O digital bidirecional ou Porta paralela escrava
RD3/PSP3 22 I/O I/O digital bidirecional ou Porta paralela escrava
RD4/PSP4 27 I/O I/O digital bidirecional ou Porta paralela escrava
RD5/PSP5 28 I/O I/O digital bidirecional ou Porta paralela escrava
RD6/PSP6 29 I/O I/O digital bidirecional ou Porta paralela escrava
RD7/PSP7 30 I/O I/O digital bidirecional ou Porta paralela escrava
RE0/RD/AN5 8 I/O
I/O digital bidirecional ou Controle de Leitura para a Porta
paralela escrava ou entrada analgica 5
RE1/WR/AN6 9 I/O
I/O digital bidirecional ou Controle de Escrita para a Porta
paralela escrava ou entrada analgica 6
RE2/CS/AN7 10 I/O
I/O digital bidirecional ou Select Control para a Porta paralela
escrava ou entrada analgica 7
VSS 12,31 P Referncia TERRA
VDD 11,32 P Alimentao Positiva (+5V)

I = Input (Entrada) O = Output (Sada) I/O = Input/Output (Entrada/Sada) P = Power (Alimentao)
Registradores Especiais (SFR)
Status: As funes mais utilizadas desse registrador esto relacionadas s operaes
matemticas, pois ele indica estouros de registradores (C-Carry) e resultados iguais a zero
(Z). bom observar que, no caso da subtrao, o Carry trabalha com lgica invertida.
PCON: A principal funo deste registrador diz respeito escolha da freqncia do oscilador
interno (OSCF): 37KHz ou
4MHZ.
OPTION
INTCON, PIR1 e PIE1
PCL
PCLATH




9

Portas
TRIS: Esses registradores servem para configurar os pinos das portas como entrada ou sada.
Quando colocado 1 em um bit do TRIS, o pino relacionado a ele configurado como
entrada.
Para configurar o pino como sada, voc deve escrever 0 no bit relacionado. Uma
maneira prtica para memorizar essa regra associar 1 ao I de Input (entrada) e o 0
ao O de Output (sada). Para configurar o PORTA, deve ser utilizado o registrador TRISA, o
PORTB o TRISB, etc.
PORTS: PORTA, PORTB, PORTC, PORTD e PORTE Quando um pino dessas portas configurado
como entrada, ao lermos o seu bit relacionado, encontramos diretamente o nvel lgico
aplicado a esse pino. Da mesma maneira, ao configurarmos um pino como sada, podemos
alterar o seu estado, escrevendo diretamente no bit relacionado.

Contadores
Timer: O PIC possu internamente um recurso de hardware denominado Timer0. Trata-
se de um contador de 8bits incrementado internamente pelo ciclo de mquina ou por um sinal
externo (borda de subida ou descida), sendo esta opo feita por software durante a programao
(SFR). Como o contador possui 8 bits ele pode assumir 256 valores distintos (0 at 255). Caso o ciclo
de mquina seja de 1us, cada incremento do Timer corresponder a um intervalo de 1us. Caso
sejam necessrio intervalos de tempos maiores para o mesmo Ciclo de Mquina, utilizamos o recurso
de PRE-SCALE.
PRE-SCALE: O Pre Scale um divisor de freqncia programvel do sinal que
incrementa o Timer0. Quando temos um pre scale de 1:1, cada ciclo de mquina corresponde a um
incremento do Timer0 (unidade de Timer0). Ao alterarmos o pre scale para, por exemplo 1:4 (os
valores possveis so as potencias de dois at 256), o Timer0 ser incrementado uma vez a cada
quatro ciclos de mquina.

Parmetros de Configurao

Tipo de Oscilador: 2 grupos: Internos e Externos Oscilador Interno: 32 KHz ou 4 MHz
(Seleo por software) Osciladores Externos:
RC_CLKOUT: Para oscilador externo tipo RC com o pino 15 operando como CLKOUT, isto ,
com uma onda quadrada de da freqncia;
RC_I/O: Para oscilador externo tipo RC com o pino 15 operando como I/O (RA6);
INTOSC_CLKOUT: Para oscilador interno com o pino 15 operando como I/O (RA6);
EC_I/O: Para clock externo (circuito auto-oscilante) com o pino 15 operando como I/O (RA6);
XT: Para osciladores externos tipo cristal ou ressoadores;
HS: Para cristais ou ressoadores externos com freqncias elevadas (acima de 4 MHz);
LP: Para cristais ou ressoadores externos com baixas freqncias (abaixo de 200 KHz).
Utilizado para minimizar consumo.

Parmetros de Configurao

WATCHDOG (WDT): um recurso disponvel no PIC que parte do princpio que todo
sistema passvel de falha. Se todo sistema pode falhar, cabe ao mesmo ter recursos para que, em
ocorrendo uma falha, algo seja feito de modo a tornar o sistema novamente operacional.
Dentro do PIC existe um contador incrementado por um sinal de relgio (clock) independente.

10

Toda vez que este contador extrapola o seu valor mximo retornando a zero, provocado a
reinicializao do sistema (reset).
Clear Watchdog: Se o sistema estiver funcionado da maneira correta, de tempos em
tempos uma instruo denominada clear watchdog timer (CLRWDT) zera o valor deste
contador, impedindo que o mesmo chegue ao valor mximo. Desta maneira o Watchdog somente
ir "estourar" quando algo de errado ocorrer.

Parmetros de Configurao

POWER UP TIMER: um temporizador que faz com que o PIC, durante a energizao
(power up), aguarde alguns ciclos de mquina (72 ms) para garantir que todo o sistema perifrico
(display, teclado, memrias, etc) estejam operantes quando o processamento estiver sendo
executado.
BROWN OUT DETECT: O Brown Out monitora a diferena de tenso entre VDD e VSS,
provocando a reinicializao do PIC (reset) quando esta cai para um valor inferior ao mnimo definido
em manual (4V tpico por mais de 100s).
LOW VOLTAGE PROGRAM: Trata-se do sistema de programao do PIC (gravao da
memria de programa) em baixa tenso: 5V. Normalmente essa programao habilitada por
uma alta (13 V) no pino MCLR.
CDIGO DE PROTEO: Para gravao em srie muito importante que esta opo esteja
ativada, pois impedir que qualquer pessoa consiga ler o programa gravado dentro do PIC.

Configurao no Programa
DIRETRIZ: _CONFIG

_CP_ON: Para code protection ligado
_CP_OFF: Para code protection desligado
_DATA_CP_ON: Para acesso externo EEPROM
habilitado
_DATA_CP_OFF: Para acesso exerton EEPROM
desbilitado
_PWRTE_ON: Power Up ligado
_PWRTE_OFF: Power Up desligado
_WDT_ON: Para WatchDog ligado
_WDT_OFF: Para WatchDog desligado
_LVP_ON: Para sistema de programao em
baixa tenso ativado
_LVP_OFF: Para sistema de programao em
baixa tenso desativado

_MCLRE_ON: Para Master Clear externo ativado
_MCLRE_OFF: Para Master Clear externo
desativado
_RC_OSC_CKOUT: Para RC externo com sada
CKOUT
_RC_OSC_NOCKOUT: Para RC externo sem sda
CKOU (com I/O)
_EXTCLK_OSC: Para clock externo sem sada
CKOUT (com I/O)
_LP_OSC: Para oscilador tipo LP
_XT_OSC: Para oscilador tipo XT
_HS_OSC: Para oscilador tipo HS



Exemplo: _CONFIG _CP_ON&_PWRTE_ON&WDT_OFF&_INTOSC_OSC_NOCKOUT

Iniciao linguagem C

A principal vantagem de se usar linguagens de alto nvel (no nosso caso a linguagem C) esta
na menor interao do projetista com o hardware, no que diz respeito ao controle do mesmo (ajuste
de bancos de registradores, seqncias de inicializao, ...).
Desta forma o projetista dedica seu tempo basicamente lgica do problema e no aos
detalhes internos do chip.

11

Como exemplo vamos ver a seqncia de escrita na EEPROM do 16F84 (gravar no endereo
20H o valor 12H, pg. 27 do livro):

Em assembler
bcf STATUS,RP0
movlw 20H
movwf EEADR
movlw 12H
movwf EEDATA
bsf STATUS,RP0
bcf INTCON,GIE
bsf EECON1,WREN
movlw 55H
movwf EECON2
movlw 0AAH
movwf EECON2
bsf EECON1,WR


Em C
write_eeprom(0x20,0x12);
Modelo bsico de um programa em C

Quatro elementos esto presentes em um programa C:
Comentrios
Diretivas de compilao
Definies de dados
Blocos com instrues e funes

Modelo bsico
#include <....> Diretivas de compilao
#fuses ......

// comentrio ocupando uma linha Comentrios
/* comentrios entre / * e * /
podem ocupar mais de uma linha
*/

char i , j ; Variveis
float Tempo;
void main()
{
instrues do programa principal
}
void delay()
{
instrues da funo (rotina) delay
}
Comentrios

Comentrios so informaes anexadas ao programa fonte (*) que permitem ao programador
ou outros entenderem o significado do que esta sendo feito.

12

boa prtica comentar todas as linhas, pois aps um certo tempo, nem mesmo o criador do
programa lembrar de tudo o que estava pensando no momento da escrita.
O compilador ignora tudo que estiver definido como comentrio (*) O programa fonte em C
deve ter terminao .C

Exemplo: teste.c

Existem dois tipos de comentrios:
Comentrios que ocupam apenas 1 linha: Este tipo de comentrio iniciado com duas barras
conjuntas: //
Neste caso, tudo que estiver aps as duas barras ser ignorado pelo compilador.

Exemplo:
x = x + 2; // soma 2 varivel x

Comentrios com mltiplas linhas: Este tipo de comentrio iniciado com a seqncia /* e
finalizado pela seqncia */.

Neste caso, tudo que estiver ENTRE estas duas seqncias ser ignorado pelo compilador. Ideal para
excluir temporariamente trechos de cdigo.

Exemplo:
x = x + 2;
/* tempo++;
a = SQRT(25); */
x = 0;
No exemplo acima, as linhas tempo++; e a=SQRT(25); sero ignoradas no momento da compilao.

Diretivas de compilao
So instrues para o compilador, e no para o programa que ser gerado.
As diretivas informam, por exemplo, o processador para o qual o cdigo dever ser gerado, o
valor do clock que ser usado pela cpu,..).
As diretivas sempre comeam com # .
Um bom exemplo a diretiva que inclui no processo de compilao as definies do chip.

#include <16F84.H>
A terminao .H indica um H eader File da linguagem C, ou seja, um cabealho.
Equivale ao P16F84.INC usado no assembler.

Indicador de fim de instruo

O compilador C no um compilador de linha, como o assembler.
O compilador C procura o sinal de que a instruo ou o bloco de instrues j acabou.
Este sinal o ponto e virgula para uma instruo ou o } para o bloco (mais tarde
falaremos sobre blocos de instrues).
No exemplo abaixo, as duas maneiras so corretas, pois o ; que sinaliza o fim da
instruo.
x = x + 25; x=
x + 25
;

13

Definio de variveis, constantes e identificadores

Todas as variveis e constantes usadas no programa devem ser devidamente definidas, com
um nome e um tipo. O mesmo vale para identificadores de funes e rotinas.
Os dados bsicos podem ser de 8, 16 e 32 bits de comprimento, e devido as caractersticas
peculiares dos microcontroladores, variveis de 1 bit tambm podem ser definidas.

Variveis: tamanho faixa
varivel de 8 bits CHAR de 0 255
varivel de 16 bits LONG INT de 0 65535(*)
varivel de 32 bits FLOAT (____________________________)
varivel de 1 bit SHORT pode assumir 0 ou 1

(*) Variveis com valores negativos:
As variveis do tipo LONG INT podem ou no ter sinal negativo. Para garantir que a varivel
seja sempre positiva, usamos unsigned antes da definio da mesma.

Caso seja necessrio tratar nmeros negativos, usaremos signed.

Ex.: unsigned long int tempo; // tempo ir de 0 65535
signed long int espaco; // espaco ir de -32768 32767

Observe que o indicativo signed diminui o alcance da varivel pela metade.

O padro da linguagem, quando no indicado, o tipo UNSIGNED.
CHAR sempre UNSIGNED.
FLOAT no admite os indicativos mas pode ser positivo ou negativo.

Seqncia de declarao de variveis e constantes

Para se declarar uma varivel temos a seguinte ordem das definies:

Tipo Nome
char tempo; // a varivel tempo vai de 0 255

Um grupo de variveis de mesmo tipo pode ser declarada na mesma linha.

char i, j, k; // declara que i, j e k so do tipo char.

Constantes:
CONST define um label para valores que no sero alterados pelo programa:

Exemplo:
FLOAT CONST PI = 3.14;






14

Como escrever os nomes de variveis, constantes e funes

Todo label (nome ou identificador), seja de varivel, constante ou funo, deve comear por
letra, ter no mximo 32 caracteres e no usar caracteres especiais ou de controle ( ! \ ? % ....).
Nomes de funes e rotinas internas tambm no podem ser utilizados.

Exemplos de definies:

Corretas Incorretas
Teste 0local comea com nmero
teste parte!dois
TESTE ^
_12A caracter invlido ( ! )
x_2_5

IMPORTANTE: O compilador diferencia letras minsculas de maisculas.

Nos exemplos acima, Teste, teste e TESTE so 3 variveis diferentes para o compilador.
Uma boa prtica esta em diferenciar variveis, labels e registros com tipos diferentes de letras.

Exemplo:

PORTB registro da CPU
TempoMs Rotina de tempo em ms
quantos varivel em RAM




Atribuindo valores

A atribuio de valores feita pelo sinal de igualdade, tempo = 123. Aqui a varivel tempo
passa a ter o valor 123 decimal.

IMPORTANTE:
Valores iniciais das variveis
Devemos sempre ajustar os valores iniciais de cada varivel do programa antes de us-las, pois nada
garante que esto em 0 no reset.


Variveis locais e variveis globais

Existem duas maneiras principais para a alocao de variveis em memria:
Variveis Globais: As variveis globais tem alcance para todas as rotinas e funes existentes no
programa. Isto significa que qualquer rotina ou funo poder utiliz-la.
Variveis Locais: As variveis locais tem alcance apenas dentro das rotinas ou funes onde
foram criadas. Isto significa que apenas a rotina ou funo onde a mesma foi criada poder utiliz-la.




15

Vamos ver um fragmento de cdigo como exemplo:

char A,B,C; // A, B e C so variveis globais, pois esto fora de
// qualquer funo ou rotina.
main ()
{
A = 0; // Faz A=0
Tempo(); // chama rotina Tempo
Espera(); // chama rotina Espera
}
Tempo()
{
char J; // cria uma varivel chamada J.
// Somente a rotina Tempo() poder utiliz-la
J = A;
}
Espera()
{
char X; // cria uma varivel chamada X.
// Somente a rotina Espera() poder utiliz-la
X = A;
X = J; // Erro: A varivel J no existe para esta rotina
}
A principal vantagem no uso das variveis locais esta em que a memria RAM ocupada pela
mesma ser compartilhada por outras variveis locais, permitindo um aumento no espao de
memria.


Funes, Procedimentos e Rotinas
Chamamos funo um trecho de programa que realiza determinada operao, bem como as
funes pr-definidas (SQRT, ABS, ACOS, ...).
A principal caracterstica da funo a capacidade de retornar um valor ao ponto de chamada
da mesma.
Procedimentos: so trechos de programa que no retornam valor.
Podemos as vezes nos referir as funes e aos procedimentos como rotinas.
No exemplo abaixo, temos a funo MAIN (falaremos dela depois) que a rotina executada no
reset do programa. A funo MAIN chama uma ROTINA para ler teclas, e a rotina de ler teclas chama
uma FUNO para calcular o valor absoluto da tecla.
main ( )
{
---
LeTeclas( );
---
}
LeTeclas( )
{
---
X = ABS(tecla_lida);
---
}


16

Funes especialmente desenvolvidas para os PICs

Na parte II, referente ao compilador da CCS, veremos quais as funes que existem para os
PICs e como funcionam.

Retorno de funes
A idia bsica da funo esta em retornar um valor para o ponto de chamada.
Todas as funes no definidas como VOID (*) retornam um valor.
Para que o valor seja retornado, devemos usar a instruo return seguida do valor a ser
retornado, que encerra a funo e faz com que o programa volte ao ponto de origem.
Uma funo pode ter vrios return, mas somente um ser executado. Podemos assim criar
vrios pontos de sada da funo, um para cada situao.
Se no colocarmos o return, o valor retornado ser 0.

(*) Veremos os tipos de funo depois

Exemplo: Funo para dividir dois nmeros. Se o divisor for 0, retorna 0
main( )
{
...........
x = 100; // fax x = 100
y = getchar( ); // faz y = ao valor recebido via serial
// para o programa o valor recebido indeterminado
valor = DIVID (x,y); // chama a funo DIVID e ao retornar atribui a
// valor o resultado da diviso
if ( valor == 0 ) { . . . } // ao caso y = 0
..........
}
long int DIVID ( long int A , B)
{
if ( B == 0 ) return (0); // se B=0 retorna 0,
else return ( A / B ); // senao retorna a diviso
}

OBSERVAO:
Este programa da forma acima apenas ilustrativo. A listagem apresentada ao final nos
exemplos esta completa, com todos os detalhes para permitir a compilao.

Variveis como parmetros

Outra facilidade da linguagem C esta na passagem de valores de uma rotina ou funo para
outra. Estes valores so conhecidos por parmetros. Como exemplo, temos o programa acima,
onde enviamos dois nmeros para a funo que calcula a diviso.

Expresses numricas e de string (caracteres)

Vamos ver neste item os tipos de expresso permitidas para valores numricos e para a
manipulao de caracteres.

Nmeros Decimais: No podem comear por 0 (zero)
Exemplos: 123; 2; 14534; 3.14; ...

17



Nmeros Octais: Devem comear por 0 (zero)
(Pouco utilizados) Exemplos: 045; 09;...

Nmeros Binrios: Devem iniciar por 0b
Exemplo: 0b10101010
Devem iniciar por 0x

Nmeros Hexadecimais: Devem iniciar por 0x
Exemplo: 0x32; 0xA9; ...

String de 1 caractere: Entre Apstrofos
Exemplo: z; A; ....


String de vrios caracteres: Entre aspas
String
Exemplo: teste de escrita


Operadores lgicos e aritmticos bsicos da linguagem C

Principais operadores lgico-relacionais e aritmticos da linguagem C.
+ Adio
++ Incremento da varivel indicada ( D++ equivalente a D = D + 1)
- Subtrao
-- Decremento da varivel indicada ( X-- equivalente a X = X - 1)
Multiplicao
/ Diviso (parte inteira da diviso para variveis inteiras)
% Resto da diviso (se for diviso de inteiros)
^ Exponencial
< Comparador lgico menor que
Comparador lgico maior que
<= Comparador lgico menor ou igual que
>= Comparador lgico maior ou igual que
== Comparador lgico igual a (*)
!= Comparador lgico diferente de
&& AND lgico ou relacional (todas as condies verdadeiras)
|| OR lgico ou relacional (uma das condies verdadeira)
! NOT lgico ou relacional (v se a condio TRUE ou FALSE)
& AND binrio (bit a bit nas variveis)
| OR binrio (bit a bit nas variveis)
~ NOT binrio (inverte o estado de cada bit da varivel)

(*) IMPORTANTE: Se numa comparao usarmos = , o compilador far uma atribuio, gerando um
programa errado logicamente.

Exemplo correto: SE A == 5 ..... // Verifica se A igual a 5
Exemplo errado: SE A = 5 ...... // Primeiro faz A igual a 5, o que no o objetivo do teste.

18

O compilador no avisa deste erro. Cuidado !

Exemplo para inverter a varivel X e escrever no portb:
portb = ~ X; // operador NOT binrio


Exemplo para ver se o bit T0IF ainda no chegou a 1:

if ( ! T0IF ) .... // Se T0IF NO (not) TRUE ( true = 1),....
// operador NOT lgico


Matrizes

Define-se como matriz um grupo de dados que podem ser agrupados num mesmo nome,
diferen- ciando-se apenas pela posio no grupo.
Como exemplo temos uma rua com vrias casas. A rua seria nossa matriz, por exemplo, Rua
Paran. Cada casa tem um nmero que indica sua posio na rua (na matriz).

Exemplo: casa 32 da Rua Paran
Poderamos escrever Rua Paran[32]
Em C, a definio de uma varivel ou de uma constante como matriz feita apenas pela incluso de
seu tamanho entre colchetes [ ].

Exemplo:
Matriz para os 20 valores de temperatura lidos, variveis tipo char:

char temperatura[20]; // reserva espao de memria para
// 20 bytes que indicaro a temperatura
// O primeiro elemento temperatura[0]
// O ltimo elemento temperatura[19]
Para acessar os elementos da matriz basta escrever o nome da varivel com o ndice do valor
desejado.

Exemplo:
valor = temperatura[12]; // o 13 elemento da matriz temperatura
// copiado para a varivel valor.

IMPORTANTE:
1) O ndice da matriz pode ser outra varivel. Ex.: H = temperatura [contador];
2) O ndice de acesso a matriz vai de 0 at tamanho-1. No nosso exemplo, ir de 0 19.
Se voc tentar acessar um elemento de endereo maior que o existente, o compilador usara uma
posio de RAM que provavelmente esta em uso por outra varivel. O compilador no tem condies
de alertar sobre este erro.
3) Muito cuidado com o uso de matrizes, pois temos pouca memria RAM nos chips.

Controle do programa em C
Um dos pontos mais importantes do aprendizado da linguagem C esta na sua sintaxe, isto ,
como o programa deve ser escrito.
At agora vimos apenas teorias sobre variveis, dados, e funes.
Veremos a partir de agora como tudo isto integrado de forma a produzir um resultado til.

19

Para tal vamos estudar as estruturas de montagem de programas e ver como se controla o
fluxo de aes que o programa deve tomar.
Para facilitar o aprendizado no vamos nos preocupar agora com o PIC e nem com as funes
criadas para o mesmo, mas apenas com a forma como escrevemos o programa em C.

Blocos de declaraes

Sempre que mais de uma instruo tiver de ser executada para uma certa rotina, as mesmas
devero estar contidas dentro de um BLOCO de declaraes.
Um bloco tem incio com a abertura de uma chave { e finalizado pelo fechamento da
chave } .
Como um bloco no termina no fim da linha, mas sim ao fechar a chave, podemos escrever o
mesmo de forma mais clara, colocando seus elementos em vrias linhas e permitindo melhor
colocao de comentrios..

Exemplo 1: { x = 1; tempo = x * 2; }
Exemplo 2: {
x = 1; // posso colocar um
tempo = x * 2; // comentrio para cada
} // linha

Os dois exemplos acima realizam a mesma tarefa, mas o exemplo 2 mais fcil de ser lido e
posteriormente entendido.

Abreviaes teis para instrues aritmticas

Incremento e Decremento
Duas delas foram mostradas no item I.8 (Operadores lgicos e aritmticos bsicos da linguagem C), a
saber:

++ Incremento da varivel indicada
O operador ++ facilita a escrita de instrues para o incremento de variveis.
Ao invs de escrever: a = a + 1;
podemos escrever: a++; ou ++a; (*)
-- Decremento da varivel indicada
O operador -- facilita a escrita de instrues para o decremento de variveis.
Ao invs de escrever: a = a - 1; podemos escrever: a--; ou --a; (*)
Soma ou subtrao de valores maiores que 1 uma varivel

Instruo normal Instruo abreviada
X = X + 10; X + = 10;
G = G - 25; G - = 25;

Combinando abreviaes

Podemos combinar numa nica linha abreviaes e atribuies, de forma a facilitar a escrita do
programa.
Importante: Os iniciantes na linguagem devem usar inicialmente as instrues bsicas para
no se confundirem.



20

Vamos explicar com alguns exemplos:

X = X + 1;
Y = X; Y = ++X;

(*) Como o ++ esta antes do X, primeiro o X ser incrementado para depois Y receber o valor.
Se fizermos o equivalente ser
Y = X++; Y= X;
X = X + 1;

A varivel tipo VOID
Existe um tipo de varivel especial chamada VOID.
Seu significado seria mais ou menos do tipo VAZIO.
usada principalmente na chamada de rotinas ou no retorna das mesmas, para indicar que
nenhum valor foi enviado ou ser retornado da funo.
Para melhor entendimento, vejamos uma rotina que no precisa de parmetros e nada
retorna:

......... // trecho de programa
.........
LeTeclas( ); // chama a rotina sem enviar nada
.........
.........

void LeTeclas( ) // este void indica que a rotina no envia
{ // parmetros de volta
......... // O parenteses vazio informa que a rotina no
......... // recebeu parmetros
.........
}

Prottipos de funes
No inicio do programa devemos informar ao compilador todas as rotinas que sero usadas e
seus parmetros. Isto serve para evitar que quando usarmos a rotina a mesma seja chamada de
forma errnea.

Serve ainda para o compilador montar o programa ja reservando as posies de memria RAM
e estimativa de pilha usada.
Esta declarao da rotina feita da mesma forma da rotina em s, mas sem as instrues e
finalizada pelo ; .
Esta declarao conhecida por prottipo.

Exemplos de prottipos:

void LeTeclas (void); // a rotina LeTeclas no receber parmetros e tambm
// no retornar valores.
float DIVID (long int A, B); // a rotina DIVID receber duas variveis do tipo
// long int, que recebero o nome de A e B para seu
// uso, e retornar um valor float.



21

A funo MAIN ( )
Todo programa em C deve ter uma funo chamada MAIN ( ), que a rotina que ser executada
quando o programa for chamado.
No caso do PIC, o compilador vai gerar um cdigo de inicializao e depois desviar para o MAIN
propriamente dito.
Exemplo de um programa que nada faz, mas que teoricamente pode ser compilado:

void main ( void) // a funo MAIN no recebe ou devolve valores
{
}

Bloco IF (executa se a condio for verdadeira)
Podemos entender o bloco IF como um teste simples.
Temos duas opes bsicas, sendo que a condio de teste dever estar entre parnteses:
SE (teste == ok!) executa esta(s) declarao(es)
SE (teste == ok!) executa esta(s) declarao(es)
SENO executa esta(s) outras declarao(es)

Temos vrios formatos possveis para o IF
IF simples, com apenas uma declarao caso o teste seja verdadeiro

if ( A == 0 ) A = 10; // SE a varivel A estiver zerada, atribui 10 mesma.
// Veja teoria dos operadores lgicos para o ==

IF com mais de uma declarao caso o teste seja verdadeiro.
Neste caso o grupo de declaraes dever estar num BLOCO, isto , entre chaves

{ } .
if ( tempo > 10 )
{
tempo = 0;
contador = contador + 1;
}

IF com exceo (se o teste falha, executa outra declarao ou bloco).
Pode na exceo executar uma instruo apenas ou um bloco

if ( teste == sim ) declarao individual ou bloco
else declarao individual ou bloco da exceo

Importante: A instruo (declarao) simples no precisa estar na mesma linha do IF ou do ELSE.

Podemos ento resumir numa tabela todas as combinaes dos IFs:
if (teste desejado) instruo para teste OK
if (teste desejado)
{
grupo de instrues para teste OK
}

if (teste desejado) instruo para teste OK
else instruo para teste NO OK

22


if (teste desejado)
{
grupo de instrues para teste OK
}
else instruo para teste NO OK

if (teste desejado) instruo para teste OK
else
{
grupo de instrues para teste NO OK
}
if (teste desejado)
{
grupo de instrues para teste OK
}
else
{
grupo de instrues para teste NO OK
}

Bloco FOR (loop para executar por um certo nmero de vezes)
For significa PARA (preposio). uma estrutura de repetio bastante prtica, e voltada para
realizar contagens ou iteraes de um lao relacionadas a uma varivel de controle.
for ( expresso_inicial; condio_para_repetio; expresso_auxiliar)
linha ou bloco de instrues a repetir...
Observe que entre os parnteses deste comando, so inseridos 3 itens : a expresso geral-
mente utilizada para inicializar uma varivel, determinando qual o seu valor inicial. A segunda
expres-so a condio para ocorrer a repetio. Quando esta condio for falsa, o for ir terminar.
A terceira expresso geralmente utilizada para realizar um incremento ou decremento na
varivel de controle, ou seja, na varivel eu utilizada para determinar quantas interaes o lao
deve executar.
Vejamos um exemplo do uso do FOR, considerando uma varivel j declarada chamada de X
do tipo INT.
Exemplo:
for (X=0; X<10; X ++)
{
output_high(PIN_D0);
delay_ms(100);
output_low(PIN_D0);
delay_ms(100);
}
Para o exemplo acima, a varivel X ir comear valendo zero (X=0). A cada interao do lao,
a varivel testada, e se seu valor for menor que 10, ir continuar a repetio (X<10). Ao final de
cada interao, a varivel ser incrementada (X++). Desta forma, o que est entre as chaves (bloco
de instrues) do for ser repetido 10 vezes.



23

WHILE
WHILE significa enquanto, e implica em uma condio temporal, algo que deve ser repetido
at que uma determinada situao no seja mais satisfeita.
A sintaxe do while
while ( condio )
{
linha ou bloco de instrues a repetir...
}
Lembre tambm que uma linha de instrues sempre terminada por um ponto e vrgula (;),
e um bloco de instrues delimitado por chaves ({ ... }).No caso de no haver nenhuma instruo a
executar (o que podemos chamar de lao vazio), a linha ou bloco de instrues que seguem o while
podero ser suprimidos. Para isso, basta acrescentar um ponto e vrgula no final da linha.Mas
cuidado : Caso acrescente acidentalmente o ponto e vrgula no final da linha, a instruo ou bloco de
instruo posterior ao while no ter relao com a estrutura condicional, causando um efeito
diferente do esperado.







Lao vazio. Usa (;) na linha do while

While c/ bloco de instrues. Sem o ponto e vrgula.

Explicando o while(1):
At ento nos deparamos com um elemento comum em nossos programas para
Microcontroladores : o while(1).
Note que aps esta linha de instruo, segue-se
(sem nenhum ponto e vrgula) um abrir chaves, que
fechado somente no final do programa. O que quer dizer
isso ?
Significa que todas as instrues contidas entre
estas chaves sero repetidas at que a condio que est
entre os parnteses do while seja falsa. Como o nmero
1 a representao binria de verdadeiro, ento este
lao no ir terminar nunca.
Ou melhor... ir terminar sim... caso o sistema seja
desligado, ou ainda caso seja encontrada uma
instruo que interrompa o while.
Como interromper um while : No somente o
while, mas qualquer estrutura de repetio pode ser
interrompida se executada a instruo break. J a
instruo continue promove um reinicio do lao,
ignorando o restante das instrues compreendidas no

24

bloco definido pela estrutura de repetio.

DO WHILE
WHILE significa enquanto. DO significa faa. Portanto, do while significa FAA ENQUANTO.
muito parecido com o WHILE, mas seu efeito diferente. O WHILE um tipo de estrutura de
repetio cujo teste feito no incio do lao. J o DO WHILE possui o teste no final do lao, o que
permite que o lao sofra pelo menos uma execuo, antes de avaliar se deve ser repetido ou no.
A sintaxe do do while
do {
linha ou bloco de instrues a repetir...
}
while ( condio );

Lembre tambm que uma linha de instrues sempre terminada por um ponto e vrgula (;),
e um bloco de instrues delimitado por chaves ({ ... }). Assim como no WHILE, o comando
BREAK pode ser usado para interromper um DO WHILE, e o comando CONTINUE far com que o lao
reinicie

Exemplo
...
while(!input(PIN_A1)) //enquanto A1 estiver desligado
{ //inicio da estrutura de repetio
output_high(PIN_D0); //liga D0
delay_ms(100); //tempo
output_low(PIN_D0); //desliga D0
if (input(PIN_A2)) //se A2 for acionado
{ //
x = 0; //zera x
break; //e sai da estrutura de repetio
} //
if (input(PIN_A3)) //se A3 for acionado
continue; //volta ao incio da estrutura de repetio
x ++; //aumenta X
output_high(PIN_D1); //liga pino D1
delay_ms(100); //tempo
output_low(PIN_D1); //desliga pino D1
} //final da estrutura de repetio
...

O lao acima descrito continuar a ser executado at que seja acionado o pino A1.
Se o pino A2 for acionado, o lao tambm interrompido (instruo break), alm de atribuir o
valor ZERO a varivel X.
Desta forma, se o pino A3 estiver acionado, o programa continuar executando o lao, porm
no far o incremento de X e nem acionara e desligar o pino D1, pois a instruo continue faz com
que o lao seja reiniciado, fazendo com que a execuo do programa volte ao incio do bloco de
instrues, refazendo tambm o teste de condio do lao.




25

O condicional SWITCH
O SWITCH testa a varivel e conforme seu valor pula diretamente para o grupo de instrues
conforme a clusula CASE.
Caso nenhuma das condies previstas nos vrios CASE sejam satisfeitas, executa o bloco
DEFAULT, se houver (no obrigatrio).
Mesmo que apenas uma instruo seja usada para um certo CASE, sempre teremos um bloco (
entre chaves { } ) pois alm da instruo a ser executada devemos incluir a instruo BREAK, que
faz com que o programa v imediatamente para o fim do SWITCH, continuando a partir dai.
Caso o BREAK no seja colocado, o programa continuar pelo CASE logo abaixo do que foi
chamado (ou no DEFAULT).

Seu formato geral :

switch ( varivel )
{
case constante1
{
( instruo ou grupo de instrues )
break;
}
case constante2
{
( instruo ou grupo de instrues )
break;
}
.
.
.
default:
{
( instruo ou grupo de instrues para falso geral )
break;
}
}

Vamos ver um exemplo que faz o mesmo que o IF aninhado que vimos anteriormente.

switch ( posio )
{
case 1: // CASO posio = 1 ....
{
peso = 1;
break; // sai do CASE.
}
case 2:
{
peso = 2;
break;
}
case 3:
{
peso = 4;

26

break;
}
case 4:
{
peso = 8;
break;
}
default: // CASO posio NO seja 1, 2, 3 ou 4,
{ // executa este bloco
peso = 0;
break;
}
}
Para ilustrar vamos escrever vrias declaraes em uma s linha.
switch ( posio )
{
case 1: { peso = 1; break; } // CASO peso=1, ....
case 2: { peso = 2; break; } // CASO peso=2, ....
case 3: { peso = 4; break; }
case 4: { peso = 8; break; }
default: { peso = 0; break; }
}


Configurando o programa
#include - Diretiva do Compilador
Ex: Incluindo um arquivo coma as definies relativas ao processador-alvo, para qual o programa
ser compilado:

Exemplo: #include 16F877A

#use Diretiva Interna do Compilador
Ex: Definindo o valor da freqncia de clock da MCU para utilizao em rotinas que dependam de
tempo:

Exemplo: #use delay(clock=4000000)

#fuses Diretiva que especifica o estado dos fusveis
Ex: Configurando o PIC com oscilador interno de 4MHz com os pinos RA6 e RA7 disponveis para E/S,
watchdog desligado, timer power-up ligado, reset por brown-out ligado, programao por baixa
tenso desligada e MCLR interno (pino RA5 disponvel como entrada):

Exemplo: #fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP,NOMCLR


Programa Exemplo

#include <16f877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,PUT

27

void main()
{
while (true)
{
output_high(PIN_B0); // Seta o pino RB0
delay_ms (1000); // Aguarda 1000 ms = 1s
output_low(PIN_B0); // Resseta o pino RB0
delay_ms (1000); // Aguarda 1000 ms = 1s
}
}
































28

Fundamentos e Programao de Microcontroladores PIC

Mdulo LCD
Mdulos de caractere baseados no chip controlador HD 44780, um chip que praticamente
um padro de fato, no segmento de mdulos de display LCD;
Permitem uma interface simples com sistemas microcontrolados, com largura de
barramento de dados selecionvel para 4 ou 8 bits, requerendo ainda mais trs linhas de sinalizao
adicionais: ENABLE, RS e R/W;
A comunicao no modo 4 bits realizada utilizando apenas as quatro linhas mais
significativas de dados (D7 a D4), dividindo o byte em dois nibbles que so transferidos sempre
iniciando pelo mais significativo seguido pelo menos significativo;

#include <lcd.c> - Biblioteca de manipulao de mdulo LCD:
Default: - ENABLE: Pino B0
RS: Pino B1
RW: Pino B2
B4 B7: Pino B4, B5, B6 e B7 respectivamente.

Pinagem do LCD 16x2








29

Comandos LCD
Biblioteca MOD_LCD.C:
OBS: necessrio que este arquivo esteja no mesmo diretrio do arquivo fonte
lcd_ini() - Inicializa LCD
lcd_escreve('\f') Apaga LCD
lcd_pos_xy(1,2) Posiciona cursor no LCD
Lcd_ecreve Escreve Texto no LCD
Ex: printf(lcd_escreve,Alo Mundo")
lcd_le(1,2) - L caractere do display
lcd_envia_nibble(dado) Envia um dado de 4 bits para o display
lcd_envia_byte(endereco,dado) Envia um byte para o LCD (utilizado para construir novos
caracteres)


Exemplo:
#include <16f877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,PUT,NOBROWNOUT,NOLVP
#include <lcd.c> // Biblioteca de Funes do LCD
void main() {

lcd_ini(); // Inicializa LCD
lcd_escreve('\f'); // Apaga LCD
lcd_pos_xy(1,2); // Posiciona cursor na linha 2 coluna 1
printf (lcd_escreve,"Prof. Tacio Luiz"); // Escreve no LCD
delay_ms(1000); // Atraso de 1s
while (true)
{
lcd_escreve('\f'); // Apaga LCD
delay_ms(1000); // Atraso de 1s
printf (lcd_escreve,"Testando Placa");
delay_ms(1000); // Atraso de 1s
}
}


Mdulo de Converso A/D

8 canais de converso (16F877)
Conversor de Aproximao Sucessiva
Nmero digital de 10 bits
Tenses de Referncia : VDD , VSS , RA2 e RA3 (Selecionveis via software)
4 Registradores:
1. A/D Result High Register (ADRESH)
2. A/D Result Low Register (ADRESL)
3. A/D Control Register0 (ADCON0)
4. A/D Control Register1 (ADCON1)




30

A/D de Aproximaes Sucessivas



Analisando o diagrama anterior, vamos supor que a sada do conversor DA varie de 0V a 5V,
quando sua entrada binria tem uma faixa de 0000 a 1111, com 0000 produzindo 0V e 001
produzindo 1V, e assim por diante. Suponha que uma entrada analgica de 13V seja plicada. No
primeiro pulso do relgio , o registrador de sada carregado com 1000, que convertido pelo
conversor AD em 8V. O comparador determina que 8V menor que a entrada analgica (13V),
de modo que no prximo pulso do relgio o circuito de controle faz com que a sada do registrador
seja carregada com 1100. A sada do conversor DA agora e 12V, e o comparador determina
novamente que menor que a entrada analgica. Ento o registrador carregado com 1110 no
prximo pulso do relgio. A sada do conversor DA ser de 14V, e o comparador determina agora que
maior que a entrada analgica de 13V. portanto, o ultimo 1 carregado no registrador substitudo
por 0, e 1 carregado no LSB.
Desta vez, a sada do conversor DA de 13V, que igual ao valor da entrada analgica, de
modo que a converso est completa. A sada do registrador contm 1101.

Especificaes de um A/D

A resoluo de um conversor AD a menor variao que pode ser identificada em uma escala
analgica. Nos conversores AD, a resoluo depende diretamente do nmero de bits.
O tempo necessrio para converter uma entrada analgica simples em uma sada digital
chamado de tempo de converso de um conversor AD.
O teorema da amostragem de Shannon declara que o dado amostrado pode ser usado para
reproduzir fielmente um sinal que varia no tempo, desde que a taxa de amostragem seja pelo menos
o dobro da freqncia da componente de maior freqncia do sinal.

Exemplo:
Qual o tempo mximo de converso que um conversor AD pode ter se ele for usado para
converter sinais de entrada de udio?
A faixa de freqncia de udio considerada de 20 Hz a 20 kHz.
Como a maior freqncia na entrada pode ser de 20 kHz, as converses devem ser executadas
em uma taxa de pelo menos 40 x 103 converses/s. O tempo mximo de converses permitidas ,
portanto, igual a:



31

Leitura de Tenses Analgicas
Comandos Relacionados:
SETUP_COMPARATOR(): Configura o funcionamento do mdulo comparador interno.
SETUP_VREF(): Configura a referncia interna de tenso.
SETUP_ADC(): Configura o conversor AD interno.
SETUP_ADC_PORTS(): Configura as entradas analgicas do conversor A/D interno.

OBS: Ver tabela.
SET_ADC_CHANEL: Seleciona um canal de entrada para o mdulo AD interno.
READ_ADC: Efetua converso A/D.

Aplicaes:
Normalmente, utilizam-se sensores especiais para converter a grandeza desejada em um nvel
de tenso proporcional.
Podemos efetuar a leitura dessa tenso por intermdio de um conversos analgico/digital, cuja
funo converter a tenso analgica em um nmero binrio, proporcional tenso analgica.

Caractersticas
Nos conversores A/D, utiliza-se uma tenso de referncia (normalmente chamada de Vref) que
serve de fundo de escala para o sinal de sada do conversor, ou seja, as sadas do conversor estaro
todas em nvel 1 quando a tenso de entrada do conversor for igual ou maior que a tenso Vref.
Como a sada do conversor um nmero binrio proporcional tenso medida e no o prprio
valor binrio da tenso, necessrio utilizar tcnicas conhecidas como escalonamento, de forma a
calcular o valor equivalente sada do conversor.
O ideal seria usar valores de Vref que facilitem a tarefa de escalonamento, os mais comuns
so 1,024; 2,048 e 4,096 Volts. No entanto, como a obteno de tais valores de tenso complicada
e muitas vezes cara(apesar de existirem muitos CIS de referncia precisa de tenso), normalmente
opta-se pela utilizao da prpria tenso de alimentao como referncia para o conversor.
Para entender o funcionamento do escalonamento, suponha um conversor A/D com resoluo
de 10 bits e referncia de 5V. Podemos facilmente concluir que o valor de cada bit ser igual a 10
5/(2 - 1)=4,8876 mV, ou seja, para um resultado igual a 100 (decimal), teremos uma tenso de
100* 4,8876 mV = 0,48876 V.
Quando trabalhamos com os conversores A/D internos do PIC devemos lembrar que a
impedncia mxima da fonte de sinal analgico deve ser de 10 Kohms e o tempo mnimo de aquisio
de 19,72s.









32

Circuitos Exemplo

Outros exemplos

LIGAO POTENCIMETRO SENSOR DE LUMINOSIDADE SENSOR DE TEMPERATURA

Exemplo de programa 1
#include <16f877.h>
#device adc=10 // Configura o compilador para conversor A/D de 10 bits
#use delay(clock=4000000)
#fuses HS,NOWDT,PUT
#include <regs_16f87x.h>
#include <lcd.c>
main()
{
long int valor;
int32 val32;
lcd_ini();
setup_ADC_ports (RA0_analog);
setup_adc(ADC_CLOCK_INTERNAL );
set_adc_channel(0);
while (true)
{
lcd_escreve ('\f'); // apaga o display
// O escalonamento realizado da seguinte forma:

33

// resultado = (5000 * valor lido) / 1023
// Para facilitar os clculos, somamos um ao
// valor lido:
// resultado = (5000 * (valor + 1)) / 1024
// simplificando:
// resultado = ((valor + 1) * 4) + ((valor + 1) * 113) / 128
// Repare que necessrio converter a segunda parte da
// equao para 32 bits para que o compilador efetue o
// clculo corretamente
valor = read_adc(); // efetua a converso A/D
// Se o valor > 0, soma 1 ao valor lido
if (valor) valor += 1;
val32 = valor * 4 + ((int32)valor * 113)/128;
// imprime o valor da tenso no display
// 5000 = 5,000 Volts ou 5000 milivolts
printf (lcd_escreve,"Tensao = %lu mV",val32);
delay_ms (250); // aguarda 250 ms
}
}

Exemplo de programa 2
#include <16f877.h>
#device ADC=10 // define que o AD utilizado ser de 10 bits
#use delay (clock=4000000)
#define use_portb_lcd true
#include <lcd.c>

long AD(int CANAL) // declara funo (subrotina) usada para ler entrada analgica
{
long AUXILIAR; //Declara uma varivel de 16 bits
enable_interrupts(GLOBAL); //Habilita uso de interrupo para converso AD
setup_adc_ports(ALL_ANALOG); //Habilita todas as analgicas
setup_adc(ADC_CLOCK_INTERNAL);//Configurao do clock do conversor AD
set_adc_channel(CANAL); //Configurao do canal do conversor AD
delay_us(100); //Tempo para selecionar canal lido
AUXILIAR = read_adc(); //Faz a leitura e armazena na varivel AUXILIAR
setup_adc_ports(NO_ANALOGS); //Desativa entradas analgicas
return(AUXILIAR); //Retorna valor analgico lido
}

void main()
{
long LIDO;
lcd_init();
while(1)
{
LIDO = AD(0); // l AD canal 0. Usa a funo acima descrita
printf(lcd_putc,"\fAD -> %lu", LIDO); // escreve valor lido no LCD
delay_ms(30); // para evitar que o LCD fique piscando
}
}

34

IMPORTANTE: A linha #device ADC=10 precisa estar na segunda linha, logo aps a linha do
#include <picxxxxxxx>.
Mdulo Capture, Compare, PWM
2 Mdulos Capture, Compare, PWM (16F877);
CPP1 e CPP2 (2 canais);
Registrador Capture de 16 bits;
Registrador Compare de 16 bits;
Registrador PWM de 10 bits;
CPPR1L: Registrador de 8 bits menos significativos (canal 1);
CPPR1H: Registrador de 8 bits mais significativos (canal 1);
CPPR2L: Registrador de 8 bits menos significativos (canal 2);
CPPR2H: Registrador de 8 bits mais significativos (canal 2);
CPP1CON: Registrador de controle do mdulo 1;
CPP2CON: Registrador de controle do mdulo 2;

Pulse Width Modulation (PWM)
Modulao por Largura de Pulso:

Da forma de onda, facilmente deduzido que o valor mdio VM(rea total da forma de onda)
dado por:









35

PWM - Caractersticas
Observa-se ento, que o valor mdio pode ser alterado atuando-se em TON, em T ou em
ambos. Atuando-se sobre T , com TON fixo, tem-se a estratgia de controle de VM designada por
modulao de freqncia dos pulsos (do ingls, PFM).
Porm, atuando-se sobre TON com T fixo (freqncia fixa), tem-se a estratgia designada
modulao por largura de pulso (do ingls, PWM).
Considerando-se que a implementao de uma chave eletrnica feita com dispositivos
semicon-dutores (tiristores ou transistores), a transio do estado conduzindo para o estado no -
conduzindo (e vice-versa) no instantnea, de modo que cada etapa de transio caracteriza uma
perda de potncia por dissipao no prprio dispositivo.
Neste caso, fica claro que a estratgia PFM implicar globalmente em maior dissipao de
potncia de chaveamento para abranger uma grande variao de VM.
J com a estratgia PWM, toda gama de valores de VM pode ser conseguida com uma nica e
determinada quantidade de potncia dissipada em transies, definida pela freqncia do PWM.
As perdas relacionadas com os semicondutores em estado de conduo sero
substancialmente as mesmas. Logo pelas razes aqui mencionadas, a estratgia PWM se mostra
superior PFM.

PWM - Aplicaes
1. Controle de potncia em cargas CC:
Controle de Brilho de um LED;
Controle de Velocidade de um Motor CC;
Controle de um tenso analgica CC (D/A);

2 . Controle de potncia em cargas CA com a utilizao de tiristores:
Controle de Velocidade de um Motor CA;
Controle de temperatura;
Controle do valor RMS tenso analgica CA;

Exemplos:

CONVERSOR CC-CC CHOPPER




36

Comandos - Capture, Compare, PWM
SETUP_CCPX(): Configura o funcionamento do watchdog.
Sintaxe: setup_ccp1( modo )
setup_ccp2( modo )
Modos (varivel ou constante inteira de 8 bits):
CCP_OFF: mdulo CCP desligado;
CCP_PWM: configura o modo de gerao de sinal PWM;
Exemplo: setup_ccp1(CCP_PWM)
SET_PWMX_DUTY(): Configura o ciclo ativo do mdulo CCP no modo PWM.
Sintaxe: set_pwm1_duty ( valor )
set_pwm2_duty ( valor )
valor uma varivel ou constante inteira de 8 ou 16 bits
Exemplo: set_pwm1_duty(100);

Freqncia do PWM
Freqncia definida pelo Timer 2
SETUP_TIMER2(): Configura o Timer 2.

Sintaxe: setup_timer_2( modo , per , os )
a) modo uma varivel ou constante inteira de 8 bits;
b) per uma varivel inteira de 8 bits;
c) ps um nmero entre 1 e 16;

modos: T2_DISABLE: desliga o timer 2;
T2_DIV_BY_1: timer 2 ligado com prescaler dividindo por 1;
T2_DIV_BY_4: timer 2 ligado com prescaler dividindo por 4;
T2_DIV_BY_16: timer 2 ligado com prescaler dividindo por 16;
O parmetro per utilizado para especificar um perodo de contagem para o timer 2. A
contagem do temporizador inicia em 0 e cada vez que ele chegar a uma contagem igual ao valor de
per, o temporizador ser reiniciado.
O parmetro os utilizado para especificar um valor para o ps-divisor do timer 2. O nmero
programado em ps ser igual ao nmero de reincios do timer 2 necessrios para gerar uma
interrupo (TMR2IF).
Exemplo: setup_timer_2( T1_DIV_BY_1, 100 , 1);

Circuitos Exemplos







Controle de Brilho de um LED: Controle de Velocidade de um Motor CC:

37

Exemplo de Programa 1
#include <16f877.h> // porque vamos usar um PIC16F877 ou PIC16F877A
#use delay (clock=4000000) // Importante que o valor do CLOCK esteja correto
#define use_portb_lcd true
#include <lcd.c>

void main()
{
long TEMPO_PULSO = 0; // varivel que determina tamanho do pulso ligado
setup_ccp1(CCP_PWM); // ativa PWM 1 (pino C2)
setup_ccp2(CCP_PWM); // ativa PWM 2 (pino C1)
setup_timer_2(T2_DIV_BY_4, 250, 1); // O tamanho do ciclo 4*(4/CLOCK)*250.
while(1) // lao infinito
{
set_pwm1_duty(TEMPO_PULSO); // Configura tamanho do pulso
set_pwm2_duty(1023 TEMPO_PULSO); // Configura tamanho do pulso (inversamente
proporcional)
delay_ms(50); // Tempo de 50 milsimos de segundo
if (input(PIN_D0)&&TEMPO_PULSO>0) // Se sinal em D0 e TEMPO_PULSO for superior a
ZERO
{
TEMPO_PULSO --; // Diminui uma unidade da varivel TEMPO_PULSO
}
if (input(PIN_D7)&&TEMPO_PULSO<1023) // Se sinal em D7 e TEMPO_PULSO menor que
1023
{
TEMPO_PULSO ++; // Incrementa TEMPO_PULSO em uma unidade
}
printf(lcd_putc,"\fPWM: %lu", TEMPO_PULSO); // mostra no display o valor de
TEMPO_PULSO
}
}

Obs importante :
O exemplo acima ter efeito sobre os pinos do PWM fsico, ou seja, pinos C6 e C7.
Em outros casos, e para outros pinos, ser necessrio gerar um PWM via software. Isso quer
dizer que seu programa deve ficar ligando e desligando o pino em questo. Veja como seria no
exemplo abaixo :
Exemplo de Programa 2
#include <16f877.h> // porque vamos usar um PIC16F877 ou PIC16F877A
#use delay (clock=4000000) // Importante que o valor do CLOCK esteja correto
#define use_portb_lcd true
#include <lcd.c>

void main()
{
long TEMPO_PULSO = 0; // varivel que determina tamanho do pulso ligado
while(1) // lao infinito

38

{
output_high(PIN_D0);
delay_us(TEMPO_PULSO);
output_low(PIN_D0);
delay_us(1024 TEMPO_PULSO);
if (input(PIN_A1)) TEMPO_PULSO = 0; // Se A1 acionado, tamanho do pulso zero
if (input(PIN_A2)) TEMPO_PULSO = 200; // Se A2 acionado, tamanho do pulso 200
if (input(PIN_A3)) TEMPO_PULSO = 400; // Se A2 acionado, tamanho do pulso 400
if (input(PIN_A4)) TEMPO_PULSO = 800; // Se A2 acionado, tamanho do pulso 800
if (input(PIN_A5)) TEMPO_PULSO = 1023; // Se A2 acionado, tamanho do pulso 1023
}
}

Programando em C: Boas Prticas
Em 1972 o funcionrio da AT&T Dennis Ritchie iniciou o desenvolvimento de uma linguagem de
programao que simplificasse a sua tarefa diria de programador nos laboratrios Bell. Chamou-a
simplesmente de "C", em referncia clara uma linguagem anterior, escrita por Ken Thompson,
conhecida como "B". Aps estar madura a suficiente para substituir o assembly no kernel do sistema
Unix em 1973, a linguagem ganhou o mundo, evoluindo com o tempo e tornando-se referncia, mas
sem perder as principais caractersticas que a fizeram ocupar uma posio de destaque.

Esta dica pretende conversar diretamente com o programador, revelando algumas boas
prticas que podem auxili-los no desenvolvimento e manuteno do cdigo. Apesar de genrico
linguagem C, os tpicos abordados so frutos da experincia como desenvolvedor de sistemas
embarcados, sendo estes o nosso foco principal.
Mantendo Bonito

A linguagem C, por definio, no exige que voc escreva o programa seguindo regras que o
tornem esteticamente agradvel de ver (e ler). Nada impede voc de escrever algo como:

/*#define ppp xp
* /## define */#define x =
#define zim void
/*\**\*\***//*/ #denife $/*/
#define p ()
#define iu for(
/*\**\*\***//*/ #defie $##def x^3printdf/*/
#define xyz <
/*/* 8/ *******/ #define o ;}
#define v "\na l o m u n d o "
int s (zim) { char b x 1; iu b x 9;\
b xyz 21; b++){ printf( v ) o /*}}}*/}
zim main( zim ) { s p o

Exceto, claro, o bom senso. De uma maneira geral, o cdigo bonito e organizado sempre
mais fcil de ler.






39

Endentao & Espaos

Utilizar endentao no cdigo algo essencial para a legibilidade. O tamanho do espaamento
pode variar, mas o importante sempre manter blocos aninhados respeitando os nveis de
endentao das estruturas condicionais e laos de repetio. De uma forma geral, o nvel de
endentao muda sempre aps o incio de uma funo, estrutura condicional ou lao:

void exemplo ( void ) {
if ( a > 5 ) {
b += 3;
for ( i=0; i<5; i++ ) {
z++;
x--;
}
}
}

No exemplo acima foram utilizados quatro espaos entres os blocos. Voc pode configurar o
seu editor de texto preferido para que a tecla TAB substitua o carter invisvel de tabulao por estes
espaos, bastante til. Evite espaamentos muito curtos, como apenas um espao, ou muito longos.

Alm da endentao, que voc j deve estar habituado, outro recurso que facilita a legibilidade
a utilizao de espaos horizontais e verticais. Aumentar o nmero de linhas e espaos no vai,
obviamente, aumentar o tamanho do binrio compilado. Ao invs de escrever uma sentena
condicional como:

if (a<20 &&(c==5||d==6)) { }

prefira algo assim:

if ( (a < 20) && ( (c==5) || (d==6) ) ) { }

que visivelmente mais agradvel de avaliar. Separar as sentenas por parnteses tambm evita
algum erro de precedncia que voc possa cometer ao digitar as expresses, reduzindo o tempo de
depurao no futuro.

Laos complexos tambm podem ser quebrados em vrias linhas, com o mesmo objetivo:

for ( cont = 0, aux = 3;
cont < 100;
cont++, aux+=2 ) {

a = c + b;
d = e - f;
}

Quando falo em legibilidade do cdigo, lembro-me que existe um operador na linguagem C, o
ternrio, que utilizado em excesso pode tornar as expresses pouco legveis aos olhos menos
treinados. De uma forma geral eu evito utilizar o operador ternrio, mesmo em sentenas simples.




40

A operao

aux = ( cont < aux ) ? cont : cont * -1;

poderia ser escrita, sem nenhum prejuzo, como:

if ( cont < aux )
aux = cont;
else
aux = cont * -1;


Mas se voc gosta do operador ternrio, uma opo para melhorar a legibilidade separar as
sentenas por linhas endentadas. A mesma expresso poderia ser escrita assim:

aux = ( cont < aux )
? cont
: cont * -1;
Isto ser especialmente til caso voc utilize o operador ternrio de forma encadeada. Este cdigo:

a = ( b < z )
? x
: ( i > x )
? i
: ++i;

certamente mais legvel que este:

a = ( b < z ) ? x : ( i > x ) ? i : ++i;

- ++ e --
Evite agregar mais de um ++ ou -- na mesma sentena. Com o mesmo intuito, evite atribuir
ao resultado da operao, operadores que utilizaram o incremento ou decremento na expresso.


Portando, expresses como:

z = a++ + ++b;

ou

a[b] = b++;

devem ser evitadas e substitudas por clusulas que inibam, ou pelo menos minimizem,
interpretaes errneas.

Nmeros Mgicos

As constantes so suas amigas, e os "#define" uma das mais ricas formas de melhorar a
legibilidade do cdigo. "Nmeros Mgicos" so valores, inteiros ou no, que aparecem no cdigo e
que so constantes, mas no foram declarados como tais. Fazer isso prejudica a organizao e
dificulta a manuteno.

41

Ao invs de ter condies como:

while ( tensao_bateria < 30 ) {
if ( potencia_transmissor > 50 )
diminua_potencia();
else {
desliga_radio();
while ( tensao_bateria < 30 ) { /* espera bateria carregar */ }
liga_radio();
}
}

substitua os inteiros por constantes com nomes adequados, como LIMITE_BATERIA_CRITICA e
POTENCIA_MINIMA_TRANSMISSOR. Alm de melhorar a organizao facilita a manuteno, em caso
de alteraes nestas constantes.
Loops "Parados"
Utilizando o exemplo anterior, observe que escrevemos
while ( tensao_bateria < 30 ) { /* espera bateria carregar */ }

ao invs de simplesmente

while ( tensao_bateria < 30 );

A primeira forma deixa explcita a nossa inteno, ao contrrio da segunda, que poderia ser
confundida com um erro do programador ou causar problemas posteriormente, caso o ";" fosse
erroneamente removido (possivelmente sem erro na compilao).

Convenes
No importa exatamente quais convenes voc utiliza, o importante que voc defina uma
(prpria ou no) e siga-a da forma mais rigorosa possvel. Preferencialmente estas convenes
devem ser descritas em um documento simples, que permita consultas rpidas sempre que
necessrio. Exemplificarei algumas abaixo que so bastante populares, mas voc deve adapt-las s
suas necessidades.

Constantes: para as constantes utilize sempre letras maisculas. Desta forma ser fcil
distingui-la entre as variveis.
Exemplo:
#define LIMITE_TEMPERATURA 40
#define BATERIA_BAIXA 30

Variveis: mais importante que as convenes, uma regra bsica: utilize nomes claros para as
variveis, abreviando apenas o que bastante conhecido ou bvio. Programadores so, em sua
maioria, geis no teclado. Portanto, abreviar pressoMotorEsquerdo para preMotE provavelmente no
vai economizar muito do seu tempo durante o desenvolvimento e certamente dificultar a leitura do
cdigo.

Existem algumas convenes mais antigas como a Notao Hngara ou mais modernas, como
a Notao Camelo, muito utilizada na programao orientada a objetos. Usualmente, em C,
bastante comum todas as variveis serem escritas com letras minsculas e/ou com o "_" como
separador de palavras. Sendo assim, variveis como velocidademaxima ou velocidade_maxima so
bastante comuns, sendo esta ltima forma mais freqente.


42

Tipos de Variveis: uma das grandes vantagens da linguagem C a portabilidade entre
arquiteturas. No entanto, alguns tipos de variveis possuem comprimento varivel dependendo da
arquitetura e compilador, o que pode ocasionar problemas no software, como overflow ou erros de
converses. Por exemplo, o tipo inteiro (int) normalmente representa o tamanho da palavra do
processador, nos processadores modernos de 32 e 64 bit e compiladores como o GCC. Mas isso no
necessariamente uma regra; no compilador HITECH para microcontroladores PIC de 8 bit, por
exemplo, o inteiro possui 16 bit.
Sendo assim, defina tipos claros e utilize-os, como uint8 para inteiros no sinalizados de 8 bit
ou int16 para inteiros sinalizados de 16 bit.

Tambm seja atencioso ao declarar ponteiros. Uma declarao como:

char* s, t, u;

no est errada, mas provavelmente no o que voc deseja, j que t e u no sero declarados
como ponteiros. Sendo assim, prefira esta forma para declarar os ponteiros sem margem para erros:

char *s, *t, *u;

Concluso

Nossa inteno neste assunto foi abordar algumas tcnicas que podem ajud-lo a
melhorar a legibilidade do seu cdigo. Apesar de existirem vrios outros pontos que podem
ser abordados neste tpico, de uma forma geral, escrevendo um cdigo organizado, bonito e
bem comentado existe uma grande probabilidade do seu cdigo tornar-se bastante legvel, quesito
que traduz-se em agilidade e produtividade em todas as fases do ciclo de vida do software.

Padro Serial RS-232

Tambm conhecido por EIA RS-232C ou V.24, o RS-232 um padro bastante antigo mas que
continua sendo bem utilizado por sua simplicidade e confiabilidade.
Como Funciona como qualquer dispositivo de transmisso serial, os bit so enviados um um,
seqencialmente, e normalmente com bit menos significante primeiro (LSB). Por ser um protocolo
assncrono isto , sem uma linha de relgio (clock), responsabilidade do transmissor e do receptor
efetuarem controles de tempo para saber quando cada bit inicia e finaliza.

Na sua forma padro o RS-232 utiliza dois sinais de controle, o RTS (ready to send) e o CTS
(clear to send) para efetuar o controle de fluxo via hardware. Basicamente, quando o transmissor
deseja comear um envio ele sinaliza atravs do pino RTS. O receptor, ao perceber que o transmissor
deseja enviar algum dado, prepara-se para receb-lo e seta o pino CTS. Apenas depois de receber o
sinal CTS o transmissor pode comear a transmisso.

Para cada byte existem bit de start e stop; o mais comum utilizar-se 1 bit de incio (start bit)
e 1 bit de parada (stop bit), mas possvel encontrar aplicaes que utilizam 1,5 ou 2 bit de
incio/parada. A figura abaixo mostra como a transmisso de um byte ocorre:



43



Como j citado anteriormente, esta transmisso assncrona. Tendo a velocidade de
comunicao ajustada nos dois dispositivos inicialmente, cada um deles sabe quanto tempo um bit
demora para ser transmitido, e com base nisto que a identificao dos bit possvel.

No transmissor o envio basicamente resume-se enviar um bit de incio, aguardar um tempo,
e enviar os prximos 8 bit + bit de parada, com o mesmo intervalo de tempo entre eles.

No receptor, aps a primeira borda de descida (nvel lgico de "1" para "0") (start bit) o
receptor sabe que uma seqncia de mais 8 bit de dados + bit de parada chegar. Ele tambm
conhece a velocidade de transmisso, ento tudo que ele precisa fazer aguardar o tempo de
transmisso entre cada bit e efetuar a leitura. Aps receber o bit de parada, a recepo encerra-se e
ele volta aguardar o prximo start bit.

Nos microcontroladores modernos todo este trabalho normalmente efetuado por uma UART
(Universal Asynchronous Receiver Transmitter). Este perifrico encarrega-se de efetuar todo o
controle e apenas gerar interrupes quando um byte recebido. No entanto, algumas vezes o
microcontrolador utilizado no possui uma UART, ou mesmo ela est sendo utilizada. Nestes casos
possvel implementar uma interface serial atravs de software, tratando a seqncia de transmisso e
recepo descrita anteriormente.

Na interface RS232 o nvel lgico "1" corresponde uma tenso entre -3V e -12V e o nvel
lgico "0" uma tenso entre 3V e 12V. Valores de tenso entre -3V e +3V so indefinidos e
precisam ser evitados. O estado idle da linha 1 lgico (-V).
Porm a grande maioria dos perifricos que trabalham com portas seriais no utilizam o padro
RS232 para nveis eltricos diretamente. Portanto sempre necessrio um circuito de converso
de nvels TTL/RS232. O circuito integrado mais comum para efetuar esta converso, de baixo
custo, o MAX232 que possui alimentao TTL.
Abaixo voc pode ver os dois conectores mais utilizados no padro RS-232, o DB9 e o DB25,
com seus respectivos pinos:


44


CTS Clear To Send [DCE > DTE]
DCD Data Carrier Detected (Tone from a modem) [DCE > DTE]
DCE Data Communications Equipment eg. modem
DSR Data Set Ready [DCE > DTE]
DSRS Data Signal Rate Selector [DCE > DTE] (Not commonly used)
DTE Data Terminal Equipment eg. computer, printer
DTR Data Terminal Ready [DTE > DCE]
FG Frame Ground (screen or chassis)
NC No Connection
RCk Receiver (external) Clock input
RI Ring Indicator (ringing tone detected)
RTS Ready To Send [DTE > DCE]
RxD Received Data [DCE > DTE]
SG Signal Ground
SCTS Secondary Clear To Send [DCE > DTE]
SDCD Secondary Data Carrier Detected (Tone from a modem)[DCE > DTE]
SRTS Secondary Ready To Send [DTE > DCE]
SRxD Secondary Received Data [DCE > DTE]
STxD Secondary Transmitted Data [DTE > DTE]
TxD Transmitted Data [DTE > DTE]


Grande parte da confiabilidade do padro deve-se sua boa imunidade rudos, por ter nveis
eltricos diferenciais em suas linhas. Mesmo assim, o padro RS-232 destinado aplicaes de
curto alcance.
Outras interfaces, como RS-485 so mais recomendadas quando grandes distncias so
necessrias.

45

BOOTLOADER

A transferncia de programas para os microcontroladores da famlia PIC normalmente
efetuada atravs de um hardware de gravao especfico. Como alternativa a este mtodo, para
os PIC da famlia 16F87xA e 18F, possvel efetuar a descarga de programas diretamente
a partir do PC, atravs da interface serial utilizando somente um MAX232 com capacitores.
Para que isso seja possvel previamente gravado de forma convencional o bootloader na
memria de programa flash do PIC, que um programa que gerencia a transferncia de
arquivos .hex para a memria de programa atravs de softwares de comunicao serial
especficos para a famlia 16F87xA.

Ambiente de Desenvolvimento MPLAB
Software Gratuito www.microchip.com;
Linguagem de programao: Assembly;
Gerenciamento de projetos;
Compilao;
Simulao;
Emulao;
Gravao do chip;

Compiladores CCS C
PCB: para dispositivos 12 bits (sries PIC12 e PIC16C5X);
PCM: para dispositivos de 14 bits (sries PIC14000 e PIC16xXXX);
PCH: para dispositivos de 16 bits (srie PIC18).
Caractersticas:
Compatibilidade com a padronizao ANSI e ISSO;
Grande eficincia no cdigo gerado;
Grande diversidade de funes e bibliotecas da linguagem C (padro ANSI), tais como:
entrada/sada serial, funes matemticas, etc,;
Grande portabilidadade de cdigo;
Integrao com o MPLAB.










46

Criando um novo projeto


1 PASSO 2 PASSO


Definindo a linguagem de programao (Linguagem C)



1 PASSO 2PASSO








47

Associando um arquivo fonte



1 PASSO 2PASSO

Compilando o projeto


1PASSO 2PASSO

3 PASSO


48































Tecnologia Educacional Personalpic
www.personalpic.xpg.com.br
Denis.hf@terra.com.br
Henrique_freitas@pop.com.br

S-ar putea să vă placă și