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
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 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; ...
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):
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.
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.