Baixe o app para aproveitar ainda mais
Prévia do material em texto
Respostas dos Exercícios 1 Microcontroladores PIC18 com Linguagem C Uma Abordagem Prática e Objetiva com Base no PIC18F4520 Wagner da Silva Zanco Respostas dos Exercícios Editora Érica Ltda. www.editoraerica.com.br 2 Microcontroladores PIC18 com Linguagem C Capítulo 1 1. 40MHz com o PLL ativo. 2. 36 pinos, divididos em cinco grupos denominados Ports. São eles: Port A, Port B, Port C, Port D e Port E. 3. Dez configurações diferentes. São elas: LP: cristal de baixa potência (até 200KHz). XT: cristal/ressonador (até 4MHz). HS: cristal/ressonador de alta frequência (acima de 4MHz). HSPLL: cristal/ressonador de alta frequência com o PLL habilitado. RC: RC externo com saída de clock. EssaUopção fornece ao pino OSC2/CLKO/RA6 um sinal digital com frequência quatro vezes menor que a do oscilador principal (Fosc/4). RCIO: RC externo. Nessa opção o RA6 funciona como pino digital. INTIO1: oscilador interno com Fosc/4 no pino RA6 e pino RA7 configurado como digital. INTIO2: oscilador interno com RA6 e RA7 configurados como pinos digitais. EC: oscilador externo com saída de clock. Essa opção fornece no pino OSC2/CLKO/RA6 um sinal digital com frequência quatro vezes menor que a do oscilador principal. ECIO: oscilador externo. Nessa opção o pino RA6 funciona como digital. 4. Quando a aplicação exige um bom nível de precisão para o oscilador, como no caso de aplicações que envolvem comunicação de dados ou temporizadores. 5. O PIC18F4520 possui dois osciladores internos que, se ativados, dispensam a utilização de componentes externos. São eles o INTOSC e o INTRC. O oscilador principal, o INTOSC, possui uma frequência de 8MHz e pode ser utilizado como oscilador de clock. Esse oscilador tem associado o recurso postscaler que permite prover frequências na faixa de 31kHz - 4MHz. O oscilador principal INTOSC é habilitado quando é selecionada uma frequência de clock dentro da faixa de 125kHz a 8MHz. O outro oscilador interno, o INTRC, provê uma frequência de 31kHz. O oscilador INTRC é habilitado se ele for selecionado como origem do sinal de clock. 6. O PIC18F4520 possui três fontes diferentes que podem gerar o sinal de clock. O sinal de clock pode vir do oscilador primário, do oscilador secundário ou de um dos osciladores internos. O oscilador primário inclui as opções cristal/ressonador externo, RC externo, oscilador externo e os osciladores internos. O oscilador secundário é associado ao módulo Timer1 e inclui a conexão de um cristal de baixa frequência entre os pinos T1OSO e T1OS1. Para que o oscilador secundário possa ser utilizado, é necessário que o módulo Timer1 esteja habilitado. O cristal de baixa frequência conectado entre os pinos T1OSO e T1OS1 normalmente é de 32,768kHz e pode ser utilizado como base de tempo para um RTC (Real Time Clock). Os osciladores internos, além de fazerem parte do set de opções do oscilador primário, estão disponíveis como fontes de clock para o modo de energia gerenciado (power-managed). Respostas dos Exercícios 3 7. OSCCON<7,1:0> Sinal de clock Modo IDLEN SCS1:SCS0 CPU Periféricos Disponibilidade do clock e origem do oscilador Sleep 0 N/A Off Off Nenhum - todos os clocks estão desligados PRI_RUN N/A 00 Recebe Recebe Primário - LP, XT, HS, HSPLL, RC, EC e oscilador interno Este é o modo de execução normal SEC_RUN N/A 01 Recebe Recebe Secundário - oscilador do TIMER 1 RC_RUN N/A 1x Recebe Recebe Osciladores internos PRI_IDLE 1 00 Off Recebe Primário - LP, XT, HS, HSPLL, RC, EC SEC_IDLE 1 01 Off Recebe Secundário - oscilador do TIMER 1 RC_IDLE 1 1x Off Recebe Osciladores internos Capítulo 2 1. O PIC18F4520 possui três tipos de memória integrados. São elas: memória de programa Flash-ROM, memória de dados RAM e memória não volátil EEPROM. A memória de programa possui uma capacidade de armazenamento de 32k x 16, ou seja, 32k localidades com capacidade de armazenamento de 16 bits em cada localidade. 2. Na localidade 0000h da memória de programa. 3. Até 31 chamadas. 4. A memória de dados do PIC18F4520 é implementada em memória SRAM e está dividida em 16 bancos de 256 localidades cada, com capacidade de armazenamento de 8 bits em cada localidade. No entanto, apenas os bancos 0, 1, 2, 3, 4, 5 e 15 estão disponíveis para o armazenamento de dados. 5. É um tipo de acesso à memória em que não é necessário o chaveamento entre bancos para acessar uma localidade de memória. O Access Bank, como é chamado, utiliza um segmento do banco 0 e um segmento do banco 15 para formar um único banco de memória no qual podemos acessar tanto os SFRs quanto os GPRs. O acesso à memória de dados via Access Bank não leva em consideração o valor armazenado no registrador BSR. 6. Registrador BSR. 7. A memória EEPROM interna é classificada na arquitetura do PIC18F4520 como um periférico e ocupa a faixa de endereços 00h - FFh. 4 Microcontroladores PIC18 com Linguagem C Capítulo 3 1. Power-on Reset (POR). 2. São os bits /RI, /TO, /PD, /POR, /BOR, STKFUL e STKUNF. A tabela a seguir mostra como esses bits estão associados aos diferentes tipos de Reset. Registrador RCON Registrador STKPTR Condição Contador de Programa RI TO PD POR BOR STKFUL STKUNF Power-on Reset 0000h 1 1 1 0 0 0 0 Instrução RESET 0000h 0 u u u u u u Brown-out Reset 0000h 1 1 1 u 0 u u MCLR Reset durante a execução dos Power-Managed Modes 0000h u 1 u u u u u MCLR Reset durante os Power-Managed Idle modes and Sleep Mode 0000h u 1 0 u u u u WDT Time-out durante a execução do Full Power or Power-Managed Mode 0000h u 0 u u u u u MCLR Reset durante a execução em Full Power 0000h u u u u u u u Stack Full Reset (STVREN = 1) 0000h u u u u u 1 u Stack Underflow Reset (STVREN = 1) 0000h u u u u u u 1 Stack Underflow Error (não é um Reset real, STVREN = 0) 0000h u u u u u u 1 WDT Time-out durante os Power-Managed Idle or Sleep Modes PC + 2 u 0 0 u u u u Saída da interrupção dos Power-Managed Modes PC + 2 (1) u u 0 u u u u Legenda: u - não é alterado. Nota 1: Quando um wake-up ocorre devido a uma interrupção e os bits GIEH e GIEL estão setados, o PC é carregado com vetor de interrupção (008h ou 0018h). 3. O Power-up Timer (PWRT) provê um time-out típico de 72ms após o POR. Um circuito RC interno é o responsável pela temporização. O PWRT é um recurso que precisa ser ativado e o seu objetivo é manter o microcontrolador em Reset até que a tensão de alimentação esteja estabilizada. 4. O Oscillator Start-up Timer é um circuito que provê um delay de 1024 ciclos de clock do oscilador principal, após o Power-up Timer, antes de colocar o circuito oscilador em funcionamento. Isso garante que o oscilador esteja estabilizado na sua partida, evitando travamento. O Oscillator Start-up Timer só é invocado para os modos de funcionamento do oscilador XT, LP e HS no POR ou quando o microcontrolador acorda após ter entrado no modo Sleep. 5. Quando o PLL está habilitado, a sequência time-out (temporização) que segue o POR é diferente dos outros modos de funcionamento do oscilador. Uma parte do Power-up Timer é utilizada para prover um time-out suficiente para o PLL estabilizar a frequência do oscilador principal. O delay gerado para o PLL é de 2ms e ocorre após o Start-up Timer-out (OST). Respostas dos Exercícios 5 6. Em funcionamento normal, o pino /MCLR (Master Clear) precisa estar recebendo nível '1'. Quando o nível lógico nele é forçado a '0', o microcontrolador é resetado e só sai do Reset quando o nível lógico retornar a '1'. 7. O Brown-out Reset é um recurso que, quando está ativado, faz o microcontrolador resetar caso a tensão de alimentação caia abaixo de um determinado valor, que pode ser configurado por software ou por hardware. Uma vez que o microcontrolador entrou em Reset devido ao Brown-out Reset, ele só volta ao seufuncionamento normal, ou seja, a executar o programa, quando a tensão de alimentação voltar ao nível especificado pelo fabricante para correto funcionamento do microcontrolador. 8. Este é um recurso muito poderoso utilizado para evitar a paralisação do sistema em caso de travamento do oscilador devido a uma interferência eletromagnética, ou qualquer outro tipo de ruído que o faça parar de oscilar, exceto em caso de defeito no circuito oscilador. O WDT é um temporizador que provoca um Reset no programa sempre que ele produzir um time-out, ou seja, quando o tempo programado para o time-out terminar sem que seja executada a instrução CLRWDT. 9. A instrução RESET pertence ao set de instruções dos microcontroladores da série PIC18. Essa instrução, quando executada, provoca um /MCLR Reset por software. O bit RCON</RI>=0 sinaliza que o último Reset foi provocado pela instrução RESET. 10. O Reset ligado aos eventos Stack Full RESET e Stack Underflow RESET está associado ao recurso Return Adress Stack, o qual permite ao programa efetuar até 31 chamadas à sub-rotina ou a funções associadas à ocorrência de uma interrupção. Quando é executada a instrução CALL, a instrução RECALL ou quando ocorre uma interrupção, o programa sai da sequência normal de execução e é desviado para outro ponto. Antes de ocorrer o desvio, no entanto, o endereço de retorno é armazenado em uma pilha, chamada Return Adress Stack, para que o programa possa voltar ao ponto de onde ocorreu o desvio. O registrador STKPTR<4:0> é um ponteiro para a posição da pilha onde está armazenado o próximo endereço de retorno. Quando ocorre um desvio com retorno, o endereço de retorno é armazenado na pilha e o registrador STKPTR<4:0> é incrementado. Da mesma forma, quando ocorre um retorno de uma sub-rotina, o endereço de retorno é retirado da pilha e o registrador STKPTR<4:0> é decrementado. Se no registrador STKPTR<4:0> for armazenado o valor 31 quando for executado um desvio com retorno, ocorre um overflow no Return Adress Stack. Na sequência, o bit STKFUL (STKPTR<7>) será setado e ocorrerá um Reset se o bit de configuração Stack Overflow Reset estiver ativado. Da mesma forma, se no registrador STKPTR<4:0> estiver armazenado o valor 0 e for executado mais um retorno, ocorre um underflow no Return Adress Stack. Na sequência, o PC é carregado com o valor 0 e o bit STKUNF (STKPTR<6>) será setado. Ocorrerá um Reset se o bit de configuração Stack Overflow Reset estiver ativado. Os bits STKFUL e STKUNF podem ser testados após a ocorrência de um Reset para o programa detectar se o Reset foi provocado por um overflow ou por um underflow no Return Adress Stack e tomar as devidas providências. 6 Microcontroladores PIC18 com Linguagem C Capítulo 4 1. Quando configurados como digitais, os pinos do PIC18F4520 são divididos em cinco grupos chamados Ports de I/O, identificados como Port A, Port B, Port C, Port D e Port E. O Port A é composto pelos pinos RA7:RA0. O Port B pelos pinos RB7:RB0. O Port C pelos pinos RC7:RC0. O Port D pelos pinos RD7:RD0. O Port E pelos pinos RE3:RE0. 2. O registrador TRISx. O TRISA configura os pinos do Port A, o TRISB os pinos do Port B e assim sucessivamente. 3. Eles são o elo entre o software e o hardware, ou seja, entre o programa e os pinos do microcontrolador. 4. Significa que é preciso conectar uma fonte de alimentação externa no pino. 5. Porque os resistores de pull-up são implementados na pastilha de silício e por isso possuem uma potência muito pequena. Qualquer sobrecarga de corrente pode queimá-los. 6. Pino RE3. Para ativar a função digital desse pino, é preciso desabilitar a função /MCLR. 7. Um Schmitt Trigger é um circuito comparador incorporado de realimentação positiva. Quando o nível de tensão de entrada é maior que um limiar escolhido, a saída está em nível alto; quando a entrada está abaixo de outro limiar, a saída está em nível baixo; quando a entrada se encontra entre os dois limiares, a saída retém o valor anterior até a entrada se alterar suficientemente para mudar o estado do Trigger. 8. Parallel Slave Port. Capítulo 5 1. Um compilador executado em um computador que pode gerar códigos que são executados em um diferente tipo de computador. 2. Um bloco de código escrito em linguagem Assembly contém um menor número de instruções, sendo, consequentemente, executado mais rapidamente do que um bloco de código escrito em linguagem C que executa a mesma tarefa. 3. Suporte para microcontroladores de 8 bits, MPLAB IDE, MPLAB SIM, MPASM, MPLAB ICD 2 (opcional se for utilizar um gravador/debugger compatível com o ICD 2). 4. Project Wizard. Clicar no menu Project/Project Wizard. Respostas dos Exercícios 7 5. Arquivo Caminho MPASMWIN.exe C:\MCC18\mpasm\MPASMWIN.exe mplink.exe C:\MCC18\bin\mplink.exe mcc18.exe C:\MCC18\bin\mcc18.exe mplib.exe C:\MCC18\bin\mplib.exe 6. Criar o programa-fonte, criar o projeto e configurar o MPLAB IDE, associar o programa-fonte ao projeto, compilar o projeto, debugar o projeto e, finalmente, gravar o programa no microcon- trolador. 7. Neles o MPLAB irá procurar os arquivos cabeçalho e os arquivos biblioteca incluídos na aplicação. 8. MPLAB SIM. Capítulo 6 1. enum, const, signed, void e volatile. 2. Função main(). 3. São informações que a função pode receber quando for chamada para que ela seja executada corretamente. As informações recebidas podem ser qualquer tipo de dado válido em C. Para não receber nenhum valor, lista_de_parametros deve ser declarada como void. 4. Um bloco de código é uma sequência de comandos compreendidos entre chaves, o qual é visto como uma unidade única. 5. A linguagem C possui cinco tipos básicos de dados: caractere, inteiro, ponto flutuante, ponto flutuante de precisão dupla e sem valor. São eles, respectivamente, char (8 bits), int (16 bits), float (32 bits), double (32 bits) e void (sem valor). 6. Chamamos de identificador o nome atribuído a uma variável, constante, função, label e a outros elementos do sistema. Um identificador pode conter letras, números e o caractere alfanumérico underline. Ele deve começar com uma letra ou com o caractere underline. É proibido na linguagem C um identificador iniciar com um valor numérico. 7. Uma variável global é aquela que foi declarada fora de qualquer função, inclusive da função main(). A variável global se mantém ativa durante toda a execução do programa. Uma variável é local quando ela é declarada dentro de uma função. A variável local é destruída na saída da função. Além disso, uma variável local só é reconhecida dentro da função na qual ela foi criada. 8. A principal componente da linguagem C é a função. Uma função é formada por um conjunto de comandos que são agrupados em um ou mais blocos de código. A função executa uma tarefa bem definida dentro do programa. 8 Microcontroladores PIC18 com Linguagem C 9. Do ponto de vista lógico uma função é um bloco de comandos que executa uma tarefa bem definida. 10. Comentário de linha única. Começa com dois caracteres barra // e identifica como comentário tudo que vier após as duas barras até o final da linha. Comentário de linha múltipla. Deve sempre começar com os caracteres /* e terminar com os caracteres */. Além disso, ele pode conter várias linhas. /*Comentário... Comentário... Comentário...*/ 11. O arquivo cabeçalho disponibiliza ao projeto uma biblioteca de funções que podem ser utilizadas quando solicitadas. Para incluir um arquivo cabeçalho no projeto deve-se utilizar a diretiva #include. #include <stdio.h> A linha anterior inclui no projeto as funções prototipadas no arquivo cabeçalho stdio.h, dentre as quais podemos citar a função printf(). 12. tipo nome_da_função (lista_de_parâmetros) { //sequência de comandos } 13. São eles os signed, unsigned, long e short. 14. Variáveis são localidades de memória reservadas para armazenamento de dados que serão manipuladosdurante a execução do programa, o que chamamos de tempo de execução. Quando uma variável é declarada, é necessário informar o tipo de dado que ela irá receber, ou seja, definir o tipo da variável. Além disso, uma variável pode ter escopo global ou local. A variável global é reconhecida por todo o programa. A variável local só é reconhecida dentro da função na qual ela foi criada. 15. tipo lista_de_ variáveis; tipo: é um tipo de dado válido em C, com exceção do tipo void. lista_de_variáveis: o nome das variáveis que serão declaradas. Se mais de uma variável for declarada, elas devem estar separadas por vírgula. 16. O modificador de tipo de acesso const é utilizado quando desejamos criar uma variável e não permitir que o seu conteúdo seja alterado por algum elemento do sistema durante o tempo de execução. Quando uma variável é declarada com o modificador const, após a inicialização, ninguém pode alterar o seu conteúdo. O modificador de tipo de acesso volatile é utilizado quando uma determinada variável pode ser alterada por algum elemento externo ao programa, sem que seja utilizado um comando de atribuição. O comando de atribuição é utilizado no programa para armazenar, por meio de uma instrução de programa, uma informação na variável. Uma variável que é atualizada automa- ticamente por um relógio/calendário é um exemplo de uma variável que deveria ser declarada com o modificador volatile. Respostas dos Exercícios 9 17. extern, static, register e auto. 18. O especificador extern é utilizado na declaração da variável quando ela for criada em um determinado arquivo e precisar ser acessada de outro arquivo. O procedimento correto nesse caso é declarar a variável em um arquivo e declará-la com o especificador extern no outro arquivo em que ela será acessada. O compilador saberá que a variável foi declarada em outro arquivo por causa do especificador extern. O especificador extern só funciona quando a variável é declarada como global no arquivo de origem. 19. Quando uma variável local é declarada como static, o compilador aloca memória como se ela fosse uma variável global. Em outras palavras, ela se manterá ativa durante todo o tempo de execução. Mas, pelo fato de a variável ser do tipo local, ela só será reconhecida dentro do bloco de código no qual ela foi criada. 20. Sim. Uma variável global static só é reconhecida dentro do arquivo no qual ela foi criada. A variável local static só é reconhecida dentro da função na qual ela foi criada. No entanto, ambas se mantêm ativas durante todo o tempo de execução. 21. Uma variável register é armazenada dentro da CPU. O objetivo é aumentar a velocidade no processamento da informação armazenada na variável. Esse especificador foi criado na época em que os microprocessadores tinham uns poucos registradores internos que poderiam ser utilizados para o armazenamento de dados temporários. Os microcontroladores de hoje possuem memória RAM interna, o que elimina a necessidade do especificador register. 22. Dar à variável um escopo local. Não é necessário, no entanto, a utilização desse especificador, uma vez que uma variável local, quando é criada, é automaticamente definida como automática. 23. É um valor numérico que não pode ser alterado. Uma constante pode ser também uma string. Da mesma forma que o valor numérico, a constante string não pode ser alterada. 24. Decimal: YY Hexadecimal: 0xYY Octal: OYY Binário: 0bYYYYYYYY ASCII: 'Y' Y: valor numérico 25. Associar um valor numérico a uma string. 26. A forma com que eles são representados. Um caractere é representado entre apóstrofos e uma string é representada entre aspas. 10 Microcontroladores PIC18 com Linguagem C Capítulo 7 1. Lógicos, relacionais, bit a bit, operadores especiais. 2. Atribuir a uma variável o resultado de uma expressão. int x; x=10; 3. x = y = z = 20; 4. Operador Ação − Subtração + Adição * Multiplicação / Divisão % Resto da divisão − − Decremento ++ Incremento 5. Deslocar os bits que representam o conteúdo de uma variável para a esquerda (<<) ou para a direita (>>). 6. y=15 e x=16. 7. Mais alta ++ -- * / % Mais baixa + - 8. Operador Ação > Maior que >= Maior ou igual a < Menor que <= Menor ou igual a == Igual a != Diferente de 9. O operador = é de atribuição e o operador == é usado para a comparação entre dois valores. 10. ≠ 0 para verdadeiro e = 0 para falso. 11. Mais alta > >= < <= Mais baixa == != Respostas dos Exercícios 11 12. Operador Ação && AND || OU ! NOT 13. 1 se a expressão for verdadeira e 0 se ela for falsa. 14. Mais alta ! > >= < <= == != && Mais baixa || 15. Operador Ação & AND | OR ^ XOR ~ Complemento de 1 >> Deslocamento à direita << Deslocamento à esquerda 16. z = 000100002 17. O operador xor. Exemplo: x = 20; y = x; z = x^y; Se o resultado armazenado em z for 0, significa que os valores comparados são iguais. 18. Basta inverter todos os níveis lógicos do valor e somar 1 ao resultado. 19. char introd_nibble(char x) //função introd_nibble { char y; /*declaração de variável local não inicializada*/ y = (x & 0x0f) | 0b10100000; /*máscara nibble superior que introduz o nibble 1010 na parte alta de x */ return y; //retorna y } 20. O bit mais significativo do valor. 21. Efetuar o deslocamento dos bits do conteúdo armazenado em uma variável para a esquerda (<<) ou para a direita (>>). 22. x = 4; y = x; x <<= 2; x += y; 12 Microcontroladores PIC18 com Linguagem C 23. variável = Exp1 ? Exp2 : Exp3; Quando o comando é executado, a Exp1 é avaliada. Se ela for avaliada como verdadeira, a Exp2 assume o valor da expressão que será atribuída à variável. Caso Exp1 seja avaliada como falsa, Exp3 assume o valor da expressão que será atribuída à variável. 24. É o operador * antes do nome da variável. Sua função é informar ao compilador que aquela é uma variável de ponteiro. 25. O operador &. 26. O operador cast ou especificador de tipo é utilizado quando é necessário forçar uma expressão a ser tornar um tipo específico de dado. A forma geral do uso do cast é: (tipo) expressão tipo: é um tipo de dado padrão em C. expressão: pode ser uma variável ou uma expressão válida em C. 27. O operador sizeof retorna, em bytes, o tamanho da variável ou do especificador de tipo que ele precede. O tipo_de_dado pode ser qualquer tipo de dado reconhecido pelo compilador. sizeof variavel sizeof (tipo_de_dado) 28. y = (x=1, x+=2, x= x *5); 29. Exemplo: x = x + 10; O comando anterior pode ser abreviado da seguinte forma: x+= 10; 30. Mais alta ( ) [ ] -> ! ~ ++ -- (tipo) * & sizeof * / % + - << >> < <= > >= == != & ^ | && || ? = += -= *= /= Menor , Respostas dos Exercícios 13 Capítulo 8 1. Seleção, iteração e desvio. 2. If(expressão) comando1; else comando2; O comando if testa a expressão. Sendo ela verdadeira, o comando1 é executado. Caso a expressão seja falsa, o comando2 é executado. Não se pode esquecer de que em C, verdadeiro é qualquer valor diferente de zero e falso representa o valor zero. Podemos dizer que o comando if funciona da seguinte forma: se (if) a expressão for verdadeira, é executado o comando1 e, se não (else), é executado o comando2. 3. O comando switch é utilizado quando desejamos tomar uma determinada ação se uma expressão assumir o valor de uma constante inteira ou caractere. O comando switch permite a comparação da expressão com uma lista de constantes que, como definido pelo padrão C ANSI, pode ter pelo menos 257 valores diferentes. 4. O comando switch compara o valor da expressão com as constantes associadas às diversas cláusulas case, na ordem, de cima para baixo. Se ocorrer uma coincidência, a sequência de comandos associada àquela cláusula case será executada.5. Não havendo nenhuma coincidência com as constantes associadas às cláusulas case, a sequên- cia de comandos associada à cláusula default será executada. A cláusula default não é obriga- tória, não sendo tomada nenhuma ação caso não tenha ocorrido nenhuma coincidência se ela for omitida. 6. Em determinadas situações o comando switch pode substituir o comando if, porém é importante ressaltar que o comando switch só pode testar igualdade, não sendo possível efetuar avaliação de expressões lógicas ou relacionais com esse comando. 7. Os comandos de iteração são os laços for, while e do-while. 8. for(inicialização; condição; incremento) comando; A seção inicialização é utilizada para atribuir um valor inicial à variável de controle do laço. A seção condição é uma expressão relacional que será testada após a execução do comando para determinar quando a repetição na execução do comando termina. A seção incremento define como o conteúdo da variável de controle irá variar, determinando o número de vezes que a execução do comando irá acontecer. O comando pode ser um único comando, um bloco de código ou um comando vazio. 9. Se a expressão testada na seção condição for dada como falsa na entrada do laço, o comando não será executado uma única vez. 14 Microcontroladores PIC18 com Linguagem C 10. while(condição) comando; Quando o laço while é executado, primeiramente é testada a condição que pode ser qualquer expressão válida em C. Caso a expressão seja verdadeira, o comando é executado e, em seguida, a expressão é novamente testada. O ciclo se repete até que a expressão se torne falsa, quando então o laço é finalizado. É importante observar que, como a condição é testada no início do laço, o comando pode não ser executado caso a expressão seja falsa no primeiro teste. O comando pode ser um único comando, um bloco de código ou um comando vazio. 11. O comando while testa a expressão na entrada do laço enquanto o comando do-while testa a condição na saída do laço. Ao contrário do comando while, quando o comando do-while dá a expressão testada como falsa, o comando é executado uma vez. 12. Os comandos de desvio provocam um desvio incondicional no programa que fará com que o processamento desvie para uma localidade da memória de programa fora da sequência de execução. Exemplos: return, goto e break. 13. Uma vez que a função foi prototipada, ela pode ser definida no programa-fonte após a função main() ou até mesmo ser editada em outro arquivo. 14. O comando return é utilizado quando é preciso retornar de uma função. Quando ele é executado, ocorre um desvio incondicional e o programa retorna para o comando imediatamente após aquele que fez a chamada à função que está sendo executada. De uma forma geral, a chamada a uma função também provoca um desvio incondicional, porém o endereço de memória de programa onde está armazenada a primeira instrução a ser executada após o retorno é guardado em uma pilha. Quando o comando return é executado dentro da função, o endereço de retorno é retirado da pilha e utilizado para que o microcontrolador encontre a próxima instrução que será executada. 15. Com o advento da programação estruturada, o comando goto acabou caindo em desuso porque ele possuía uma grande tendência de deixar o código ilegível à medida que ia crescendo. Sendo a linguagem C de natureza estruturada, em qualquer aplicação, por maior e mais complexa que ela seja, não é necessário o uso do comando goto. A base da programação estruturada é a chamada à função, que não precisa do comando goto. 16. Ele pode ser utilizado para terminar uma cláusula case em um comando switch ou para finalizar antecipadamente um laço de repetição. Quando o comando break é encontrado, o laço é imediatamente finalizado e o programa prossegue para o comando imediatamente após o laço. O comando break é utilizado, em tese, quando uma condição especial, sendo satisfeita, deva provocar a saída imediata do laço. 17. O comando continue funciona de forma um pouco parecida com o comando break, com a diferença de que o comando break força a saída do laço, enquanto o comando continue finaliza apenas a iteração atual do laço. Respostas dos Exercícios 15 Capítulo 9 1. Um vetor, também conhecido como array, é um conjunto de variáveis do mesmo tipo referenciadas por um mesmo nome. Cada variável que compõe um vetor pode ser acessada individualmente, sendo a sua posição dentro do vetor denominada índice. Todos os índices de um vetor ocupam posições contíguas de memória. 2. O caractere Null 3. char vect [10]="suave"; 4. 12 elementos, sendo 11 elementos utilizados para armazenar a string "Casa Blanca", mais um elemento para armazenar o caractere terminação de string, o caractere '\0'. 5. Variável de ponteiro. 6. Sim. Para passar um vetor como parâmetro para uma função utiliza-se o nome do vetor. Quando o nome do vetor é passado como parâmetro, o endereço do primeiro elemento do vetor é passado como parâmetro. Vejamos a fração de código a seguir. char *p; //declaração de variável de ponteiro char vogal[10]; //declaração de vetor p=vogal; //variável p recebe o endereço do primeiro elemento do vetor vogal Na fração de código anterior, é passado para a variável de ponteiro p o endereço inicial do vetor vogal. A passagem do endereço inicial do vetor vogal para a variável p poderia também ser feita pelo comando &vogal[0];. Em aplicações profissionais, no entanto, não é comum a utilização do operador & para a passagem do endereço inicial de um vetor para uma variável de ponteiro. Normalmente isso é feito utilizando o próprio nome do vetor. 7. Matriz. 8. Chamamos de adimensional um vetor que, na sua declaração, fica a cargo do compilador calcular a sua dimensão. Se na declaração de um vetor inicializado o tamanho do vetor não for especificado, o compilador cria um vetor grande o suficiente para conter todos os elementos presentes na sua inicialização. Vejamos o exemplo a seguir. São criados dois vetores, um chamado solar do tipo char inicializado com a string "Hoje eh domingo" e outro de nome vogais do tipo char inicializado com os caracteres 'A', 'B', 'C', 'D' e 'E'. Como a quantidade de elementos dos vetores não foi fornecida, o compilador cria um vetor com capacidade de armazenar os dados de inicialização. No caso do vetor solar o compilador aloca uma localidade de memória adicional para receber o caractere terminador de string, o caractere null. char solar[ ] = "Hoje eh domingo!"; //declaração de vetor inicializado char vogais[ ] = {'A','B', 'C', 'D', 'E'}; //declaração de vetor inicializado 16 Microcontroladores PIC18 com Linguagem C 9. char alfabeto[6][6]={'\0'}; //declaração de matriz inicializada char x='A'; //declaração de variável inicializada char i; //declaração de variável inicializada char j; //declaração de variável inicializada for(i=0;i<6;i++) //laço de iteração { if(x=='Z') break; //finaliza o laço de iteração caso x='Z' else for(j=0;j<6;j++) //laço de iteração { alfabeto[i][j]=x //atribui ao índice i,j o conteúdo de x if(x=='Z') break; //finaliza o laço de iteração caso x='Z' else x++; //incrementa x } } 10. char * tabela_Hexa(char *p); Capítulo 10 1. Do ponto de vista físico, uma string é representada na memória por um conjunto de caracteres terminado pelo caractere null, representado na forma de caractere por '\0' e no código ASCII pelo valor 0x00. 2. string.h 3. strcat (destino, origem); strcat: função que concatena strings armazenadas na memória RAM. destino: aponta para a string que será concatenada com a string apontada por origem. origem: aponta para a string que será inserida no final da string apontada por destino. 4. O tipo de dado string não faz parte do grupo básico de dados da linguagem C. Isso significa, entre outras coisas, que várias operações efetuadas com os tipos básicos não funcionam com o tipo string. Por exemplo,não podemos atribuir uma string a um vetor utilizando o comando de atribuição =, como é feito com os tipos de dados básicos, exceto na declaração do vetor. 5. A função strcpy() copia uma string apontada por origem para o endereço apontado por destino. Ambas as strings, de destino e de origem, estão armazenadas na memória RAM. 6. A função strncmp() compara alfabeticamente as duas strings até o caractere n e retorna um valor numérico da seguinte forma: < 0 se a String1 for alfabeticamente menor que a String2 > 0 se a String1 for alfabeticamente maior que a String2 == 0 se a String1 for igual a String2 Respostas dos Exercícios 17 O que importa não é o valor retornado pela função strncmp(), mas o sinal do valor retornado. A forma geral de declaração da função strncmp() é: strlncmp (str1, str2, n); strncmp: função que compara duas strings até um número n de caracteres. str1: aponta para uma das strings que será comparada. str2: aponta para uma das strings que será comparada. n: número máximo de caracteres que será comparado. 7. O comando procura o caractere 'a' dentro da string apontada por string. Caso o caractere seja encontrado, é atribuído à variável x um ponteiro para ele; caso contrário, x recebe um null. 8. strstr() 9. Todas as instruções de manipulação se strings que têm a memória de programa como destino (*pgm) só funcionam quando o microcontrolador utiliza memória de programa externa. Elas não funcionam para gravar dados na memória Flash ROM do microcontrolador. O microcontrolador PIC18F4520 não tem suporte para memória de programa externa. Sendo assim, essas instruções não surtirão o efeito desejado nesse microcontrolador. 10. strlen() Capítulo 11 1. Uma estrutura é um conjunto de variáveis, não necessariamente do mesmo tipo, referenciadas por um mesmo nome, facilitando o acesso a informações relacionadas entre si. 2. As variáveis que compõem uma estrutura são normalmente chamadas de membro ou elementos da estrutura. 3. Para que uma estrutura possa de fato armazenar dados, é necessário declarar uma variável de estrutura. 4. Operador ponto. 5. Por valor ou por referência. A linguagem C só aceita passagem de parâmetros por valor. 6. Quando passamos um elemento de uma variável de estrutura como parâmetro para uma função, será passada uma cópia do valor armazenado naquele elemento. 7. Não. Quando uma estrutura é passada como parâmetro para uma função, é passada uma cópia da estrutura. Sendo assim, a função que recebeu a estrutura como parâmetro não poderá alterar os elementos da estrutura que foi passada. 8. O operador seta permite referenciar um elemento de uma variável de estrutura utilizando um ponteiro para a estrutura. 9. Uma estrutura é aninhada quando um de seus elementos é uma variável de estrutura. 10. É uma estrutura na qual cada elemento é formado por um ou mais bits, daí o nome campos de 18 Microcontroladores PIC18 com Linguagem C bits. O campo de bits é um elemento de estrutura em que é definido o número de bits do campo. Sendo assim, é possível montar estruturas utilizando campos de bits como elementos. A forma geral de definição de uma estrutura de campos de bits é mostrada a seguir. struct identificador { tipo elemento1 : comprimento ; tipo elemento2 : comprimento ; tipo elemento3 : comprimento ; . . . } listas_de_variaveis; identificador: é opcional, podendo ou não ser definido. elementox: é o nome atribuído ao campo. comprimento: é o comprimento do campo. Ele não pode ser maior que 8 bits. tipo: normalmente é definido como unsigned, embora ele possa ser definido como outros tipos de dados suportados pelo compilador. lista_de_variáveis: são variáveis de estrutura que opcionalmente podem ser declaradas. Se a estrutura for anônima, pelo menos uma variável deve ser declarada no momento da declaração da estrutura. 11. Uma união se assemelha bastante a uma estrutura. Existe, no entanto, uma diferença fundamental entre elas. Quando uma estrutura é declarada, é alocada memória para cada um dos elementos que a compõem quando uma variável de estrutura é criada. Em uma união, o espaço de memória alocado é o comprimento do maior elemento que a compõe. 12. Enumeração. 13. Qualquer tipo de dado válido em C pode ter uma nova identificação atribuída a ele. O comando typedef é utilizado para esse fim. O typedef não cria outro tipo de dado, apenas redefine um tipo de dado padrão em C para um identificador indicado pelo usuário. Capítulo 12 1. A ideia principal por trás do conceito de stream está em transformar os dispositivos reais, funcionalmente diferentes, em dispositivos lógicos chamados streams. Para o programador, cada dispositivo será visto como uma stream, permitindo escrever caracteres em dispositivos diferentes utilizando as mesmas funções. 2. As duas streams definidas pelo MPLAB C18 são _H_USART e _H_USER. A primeira se refere ao periférico UART como destino para as funções de saída de caracteres. A stream _H_USER permite ao usuário estabelecer um destino diferente para as funções de saída de caracteres. 3. Para selecionar uma das streams definidas pelo MPLAB C18 utilizamos as variáveis globais stdout e stderr, definidas na biblioteca do compilador e que possuem o valor default de Respostas dos Exercícios 19 _H_USART. A stream _H_USART está associada ao periférico UART, o qual servirá de arquivo de saída padrão para essa stream. A variável stdout define a stream para as funções de saída de caracteres. A variável stderr define a stream para onde devem ser enviadas as mensagens de erro geradas pelo programa. Ambas as variáveis, stdout e stderr, tendo o valor default _H_USART, definem como arquivo de saída padrão o periférico UART. 4. Significa que pode ser passado como parâmetro para essas funções o conteúdo de variáveis, o qual é convertido em strings na forma como os caracteres de formatação definirem. 5. Caractere %. 6. Cinco. São eles: Caractere flag, Comprimento do campo, Precisão do campo, Tamanho do campo, Operador de conversão. 7. Os caracteres de barra invertida foram incorporados à linguagem C em substituição a alguns caracteres de controle que são impossíveis de inserir pelo teclado. Dentre eles podemos destacar o caractere retorno de carro (CR), caractere correspondente a tecla Enter. Exemplo: \b: retrocesso (BS). \n: nova linha (LF). \r: retorno de carro (CR). 8. %d 9. A função printf() envia para a stream atribuída à variável stdout, _H_USART por default, a string que foi passada como parâmetro. 10. A função vfprintf() é funcionalmente equivalente à função fprintf(), com a diferença de que os parâmetros passados para a segunda foram substituídos por um ponteiro para esses parâmetros na primeira. O ponteiro, no entanto, não pode ser qualquer um, mas um ponteiro do tipo va_list, definido no arquivo cabeçalho stdarg.h. 11. A função sprintf(). 12. Significa que a função pode receber parâmetros de comprimento variável. 13. Permitir a funções receber parâmetros com comprimento variável. 14. vfprintf(),vprintf() e vsprintf(). 15. A função _user_putc() envia um simples caractere para um arquivo de saída definido pelo usuário. Ela é invocada quando uma função de saída de caracteres envia dados para a stream _H_USER. 20 Microcontroladores PIC18 com Linguagem C Capítulo 13 1. 4,5V< VDD < 5,5V Entrada Mín Máx Nível Lógico VIL (tensão de entrada baixa) 0V 0,8V 0 VIH (tensão de entrada alta) 2V VDD 1 Saída Mín Máx Nível Lógico VOL (tensão de saída baixa) 0V 0,6V 0 VOH (tensão de saída alta) VDD - 0,7V - 1 2. 3. 20mA 4. 2V 5. Quando um LED é acionado por lógica positiva, é preciso aplicar nível lógico '1' para ele emitir. Quando ele é acionado por lógica negativa, é necessário aplicar nível lógico '0' para ele emitir. A forma como o hardware está implementado vai definir se o LED será acionado por lógica positivaou negativa. 6. 5x5 = 25 teclas. 7. 4 linhas + 4 colunas = 8 pinos 8. '0' a 'F': caso uma tecla seja detectada como pressionada. Nesse caso, a função retorna, no código ASCII, o valor da tecla pressionada. '\0': caso nenhuma tecla esteja pressionada, a função retorna o caractere null. 'G': caso uma tecla tenha sido detectada como pressionada no último rastreamento, a função retorna o caractere 'G'. Respostas dos Exercícios 21 Capítulo 14 1. Display catodo comum e anodo comum. O nome catodo comum deriva do fato de que todos os catodos de todos os LEDs estão interligados. Da mesma forma, o display anodo comum deriva do fato de que todos os terminais anodo de todos os LEDs estão conectados. 2. Segmentos A, B, C, D, F, G. 3. A técnica consiste em conectar os segmentos de um display aos segmentos de mesmo nome dos outros displays e, no caso do display catodo comum, aterrar apenas o catodo do display que estará emitindo. Apenas um dos displays pode emitir de cada vez pelo fato de as linhas de dados estarem multiplexadas. A solução para o problema resume-se no fato de que um LED piscando em uma frequência acima de 50Hz faz com que a retina não consiga acompanhar a piscagem, dando a impressão de que o LED esteja emitindo continuamente. Os displays emitirão, um de cada vez, em uma frequência acima de 50Hz para termos a impressão de que todos os displays emitem simultaneamente. 4. Nesse caso, cada display se mantém emitindo durante 4ms e apagado durante 12ms. Isso significa que o ciclo completo de atualização do display é de 16ms. Como o período de cada ciclo é de 16ms, a frequência de piscagem será de 1 / 16m = 62,5Hz, o suficiente para termos a impressão de que todos os displays emitirão simultaneamente. É importante lembrar que em cada ciclo (16ms) cada display só se mantém emitindo durante 4ms. Capítulo 15 1. No início da década de 1970, descobriu-se que as moléculas do cristal líquido poderiam ser giradas pela aplicação de uma tensão elétrica, tornando-o, desta forma, transparente ou opaco. Essa descoberta deu origem ao display de cristal líquido. 2. LCD caractere e LCD gráfico. 3. RS (dado/instrução), R/W (escrita/leitura) e E (pulso de clock). 4. Pino E. 5. Instrução 38h. 6. ♦ Oito bits de dados Uma linha de caracteres Formato 5 x 7 mais cursor Display e cursor desativados Move cursor para a direita com entrada de um novo caractere Mensagem não será deslocada com a entrada de um novo caractere 22 Microcontroladores PIC18 com Linguagem C 7. Detectar se o LCD terminou de executar a última instrução que lhe foi enviada. Se, ao ser lida, a linha busy flag fornecer nível lógico '1', significa que o LCD está ocupado executando uma instrução. 8. 80h e C0h. Capítulo 16 1. Podemos definir interrupção como um evento de hardware que provoca uma interrupção na execução do programa principal e um desvio incondicional para que o evento seja tratado. Uma vez que o evento foi tratado, o programa retorna ao ponto em que foi interrompido e a sua execução continua. Podemos dizer que a interrupção é um desvio no programa provocado pelo hardware. Em aplicações em que se deve tratar um determinado evento de hardware no momento da sua ocorrência, a interrupção pode ser uma excelente saída. 2. É uma região de memória reservada para armazenar dados ou instruções do programa. Uma seção pode ser criada na memória de dados ou na memória de programa. Além disso, é possível atribuir um endereço estático para a seção de dados criada. 3. Cria uma seção de dados não inicializada na memória RAM. 4. O MPLAB® C18, por default, cria as variáveis temporárias utilizadas no programa principal na seção de dados .tmpdata. Para alterar a seção de dados utilizada para as variáveis temporárias, deve-se utilizar a sintaxe mostrada a seguir: #pragma tmpdata nome_da_seção nome_da_seção: é o nome da seção de dados que substitui a seção .tmpdata no arma- zenamento de dados temporários. 5. A diretiva #pragma varlocate permite ao compilador otimizar código à medida que ela possibilita a remoção de instruções de chaveamento de banco no acesso a dados armazenados na memória RAM. A diretiva #pragma varlocate ajuda o MPLAB C18 a remover instruções de chaveamento de banco de memória informando a ele a eventual localização de variáveis. Lembre-se, no entanto, de que a diretiva #pragma varlocate somente deve ser utilizada com variáveis cujos endereços já foram explicitamente especificados no código. 6. Podem ser definidos dois níveis de prioridade no tratamento de uma interrupção. Uma interrupção pode ser definida como de alta ou de baixa prioridade. 7. Os níveis de prioridade no tratamento da interrupção são definidos pelo bit IPEN (RCON<7>). Quando esse bit é setado, o PIC18F4520 utiliza os níveis de prioridade no tratamento da interrupção, podendo cada interrupção ser configurada como de alta prioridade ou de baixa prioridade. Quando o bit IPEN é apagado, o PIC18F4520 não utiliza as prioridades, desviando o programa para o endereço 0008h da memória de programa quando ocorrer o evento que pode dar origem a uma interrupção. No POR o bit IPEN é apagado, devendo ser setado por software caso o programador queira utilizar os dois níveis de tratamento de interrupção. Respostas dos Exercícios 23 8. 18 fontes de interrupção. Como exemplo podemos citar a interrupção externa, interrupção de estouro do TMR0 e interrupção de recepção de dados pela EUSART. 9. A interrupção provoca um desvio ocasionado por um evento de hardware. Uma chamada à função provoca um desvio provocado pelo software. Capítulo 17 1. Uma delas é a utilização de funções desenvolvidas para esta finalidade, as funções de delay. A outra forma de medição de tempo é por meio dos módulos temporizadores. 2. TCI = 1/(Fosc/4) = 1/(8M/4)=500ns 3. A função Delay10TCYx() gera um delay, em segundos, de dez vezes o valor que lhe é passado como parâmetro multiplicado pelo tempo correspondente ao ciclo de instrução. A forma geral de declaração da função Delay10TCYx() é: Delay10TCYx (valor) valor: valor multiplicado por dez vezes o ciclo de instrução. 4. No modo temporizador o timer conta ciclos de instrução, enquanto no modo contador o timer conta a quantidade de pulsos aplicados no pino correspondente, que varia de um timer para outro. 5. O prescaler retarda o incremento do registrador associado ao timer. O retardo depende do fator de prescaler aplicado. 6. Registrador T0CON. 7. Operando em 8 bits, o incremento será no máximo até o valor 255. Operando em 16 bits, o incremento será no máximo até o valor 65.535. 8. Módulo Timer2. 9. Módulo Timer2. O bit de sinalização de estouro do TMR2 é setado e uma interrupção é gerada se ela estiver habilitada quando o TMR2 estoura o número de vezes configurado no postscaler. Se, por exemplo, o postscaler do TMR2 for configurado para 1:16, fazendo os bits TOUTPS3:TOUTPS0 (T2CON<6:3>) = 1111, o TMR2 deve estourar dezesseis vezes para que o flag de estouro de TMR2 seja setado e uma interrupção seja gerada, caso ela esteja habilitada. 10. Se após a configuração do Timer0 o par de registradores TMR0H:TMR0L for inicializado com o valor F82Fh, com um prescaler de 1:4 e uma frequência de clock de 8MHz, o TMR0 será incrementado a cada 4x500n = 2µs. O número de incrementos até que o TMR0 estoure será dado pela fórmula 65.535(FFFFh) – F82Fh = 2.000. Ele será incrementado 2.000 vezes até o estouro. Como ele está operando com 16 bits, o tempo decorrido até o estouro será de: Tempo_estouro = 2.000 x 2µ = 4ms 24 Microcontroladores PIC18 com Linguagem C A diferença 65.535 − 2.000 = 63.535 (F82Fh) é o valor com o qual deve ser inicializado o TMR0 para que o número de incrementos necessários até o estouro seja 2.000. Capítulo 18 1. Uma tensão é analógica quando para ir de um valor a outro de intensidade, a tensão elétrica precisa passar por todos os pontos intermediáriosde intensidade entre os valores inicial e final. Por outro lado, a tensão é digital quando normalmente é composta por apenas dois níveis, representados pelos níveis lógicos '0' e '1'. 2. Transdutor. 3. PCM (Pulse Code Modulation). 4. É a quantidade de partes em que a tensão será dividida. 5. NB = Log101024/Log102 = 10 bits 6. A conversão de um sinal analógico em digital consiste em amostrar o sinal um número de vezes em cada segundo e associar cada amostra ao valor correspondente à amplitude do sinal naquele ponto. A amostragem é uma leitura no valor instantâneo da tensão de tempos em tempos. Associar um valor proporcional à amplitude do sinal de tempos em tempos é um processo conhecido como PAM (Pulse Amplitude Modulation). 7. A partir dos pulsos PAM é possível produzir pulsos PCM por meio de um processo conhecido como quantização, que substitui cada pulso PAM por um conjunto de bits que represente aquele valor. 8. Em 1928, H. Nyquist provou que um sinal analógico que tenha passado por um filtro passa- -baixas (FPB) com frequência de corte Fc pode ser completamente reconstituído a partir de um número de amostras 2 x Fc. Segundo Nyquist, um número maior de amostras seria inútil porque as frequências acima que 2 x Fc já foram eliminadas pelo filtro. 9. Para garantir que a tensão de saída do filtro não sofra nenhuma queda significativa em relação à tensão de entrada para qualquer frequência do sinal de entrada, o projetista deve obedecer à fórmula a seguir, na qual a frequência máxima do sinal de entrada deve ser pelo menos dez vezes menor que a frequência do filtro passa-baixas. 10 FcFmáx ≤ 10. Como o conversor A/D será de 10 bits, é preciso dividir a faixa de tensão em 1024 partes iguais de tensão. Sendo assim, cada parte terá um valor de 2,048 / 1024 = 2mV. A frequência de corte será de: Fc = 10 x Fmáx Fc = 10 x 25 = 250Hz Respostas dos Exercícios 25 Para dimensionar o FPB de primeira ordem, podemos escolher um valor para o resistor R, por exemplo, de 4,7KΩ, e calcular o valor do capacitor C, visto que já foi calculada Fc. Nesse caso, deduzindo C na fórmula, teremos: C = 1 / 2. π.4k7.250 C = 135,45nF O valor comercial inferior mais próximo é 120nF. Com esse valor de C, Fc passa a ser 282,18Hz, bem próximo dos 250Hz calculados a partir de Fmáx. 11. S = 1,5 / 2m = 750 12. Definir os níveis máximo e mínimo de tensão a serem aplicados no conversor A/D. A tensão de referência também define a faixa de tensão analógica que será convertida em tensão digital. 13. O conversor A/D interno do PIC18F4520 possui uma resolução de 10 bits. O resultado da conversão estará disponível em dois registradores de 8 bits, dando um total de 16 bits. A sobra de bits nos registradores em que o resultado da conversão será armazenado permitiu aos projetistas deslocar o resultado para a esquerda ou para a direita, procedimento denominado justificação do resultado. 14. É o tempo necessário para que o capacitor existente na entrada do conversor A/D (CHOLD) possa se carregar para então ser dado início à conversão. 15. Gerar a base de tempo utilizada na conversão A/D. O período do sinal de clock do conversor, chamado de TAD, é o tempo necessário para a conversão de cada bit. 16. Na forma manual, o conversor A/D não aguarda o tempo de aquisição para começar a conversão após o bit que dá início à conversão ter sido setado, o bit GO/DONE. Na conversão automática, o tempo de aquisição pode ser configurado de 2TAD até 20TAD pelos bits ACQT2:ACQT0 para qualquer valor diferente de 0002. Nesse caso, quando a conversão é iniciada, o capacitor CHOLD continua conectado ao canal até o tempo de aquisição configurado. Logo após, CHOLD é desco- nectado e a conversão tem início. 17. 18. Treze canais de conversão, e apenas um deles pode ser ativado de cada vez. 19. O bit ADIE(PIE1<6>). 20. O módulo conversor A/D do PIC18F4520 pode funcionar no modo sleep desde que o clock utilizado na conversão A/D seja gerado pelo circuito RC interno ao módulo conversor. Para selecionar o clock gerado pelo circuito RC, é necessário fazer os bits ADCS2:ADCS0 = x11. 26 Microcontroladores PIC18 com Linguagem C Quando o clock gerado pelo circuito RC é selecionado, o módulo conversor A/D aguarda um ciclo de instrução para começar a conversão após o bit DONEGO/ ter sido setado. Isso permite que a instrução SLEEP seja executada, fazendo com que o microcontrolador entre no modo Sleep sem interromper a conversão A/D. Quando a conversão terminar, o bit DONEGO/ será apagado, o flag de sinalização de fim de conversão será setado e o resultado da conversão armazenado nos registradores ADRESH:ADRESL. Se a interrupção do módulo conversor A/D estiver habilitada, o microcontrolador acorda; caso contrário, o módulo conversor A/D será desligado, embora o bit ADON se mantenha setado. Capítulo 19 1. O PWM é um sinal digital com frequência fixa e com ciclo ativo variável. 2. É a parte do ciclo em que o sinal se mantém em nível lógico '1'. 3. Duty cycle é a relação entre o ciclo ativo e o período do sinal PWM e é diretamente proporcional ao nível DC do sinal. O duty cycle é também adimensional e seu valor pode variar entre 0 e 1. 4. Fazê-lo passar por um filtro passa-baixas com frequência de corte pelo menos dez vezes menor que a frequência do sinal PWM. 5. PR2 = [F(osc) / (F(PWM) × 4 × Prescaler do TMR2)] – 1 PR2 = [8x106 / (31.250 x 4 x 1)] – 1 PR2 = 63 6. O controle do ciclo ativo do sinal PWM é feito a partir de uma divisão do período do sinal PWM em partes iguais de tempo que recebem o nome de passos. O número de passos em que o período do sinal será dividido depende do número de bits de controle utilizado. Dividindo o período do sinal PWM pelo número de passos, calcula-se o tempo correspondente a cada passo (Tp). O Tp é o tempo mínimo no qual o ciclo ativo do sinal PWM pode variar. 7. a) 1 )2TMRdoescaler(Pr4F F 2PR PWM OSC − ×× = 1 14250.31 M82PR − ×× = PR2 = 63 b) 4)12PR(Np ×+= 4)163(Np ×+= Np = 256 passos Respostas dos Exercícios 27 c) 250.31 1 F 1T PWM PWM == S32TPWM μ= 512 S32 Np TTp PWM μ== ns125Tp = d) 50TpPWM )ativociclo( ×= 50n125PWM )ativociclo( ×= S25,6PWM )ativociclo( μ= e) )alto( PWM )ativociclo( V T PWM Vdc ×= 5 32 25,6Vdc × μ μ= Vdc = 0,97V f) Diagrama de tempo Capítulo 20 1. Permitir a comunicação entre dispositivos onboard, ou seja, dispositivos que estão instalados na mesma placa de circuito impresso. 2. Mestre e escravo. O mestre é o responsável pela geração do sinal do clock. 3. Condição START e condição STOP. 4. O barramento I2C permite que seja alterada a direção do fluxo dos dados durante uma trans- missão em andamento sem que o dispositivo mestre precise antes finalizar a transmissão corrente com uma condição STOP. Isso é permitido impondo uma condição Re-START no barramento após o último byte transmitido. Alterar a direção do fluxo dos dados significa alterar de um ciclo de leitura para um ciclo de escrita ou vice-versa. 5. O endereçamento pode ser efetuado com 7 bits ou com 10 bits de endereços. 6. O barramento I2C possui um recurso que permite ao dispositivo mestre endereçar todos os dis- positivos escravos simultaneamente. Isso é feito por meio do endereçamento de chamada geral, cujo uso pode ser interessante quando o dispositivo mestre desejar enviar dados para todos os dispositivos escravos simultaneamente, um tipo de comunicação conhecido como broadcast. 7. O barramento I2C permite a conexão de vários dispositivos mestres no mesmo barramento de forma que todos possam transmitir e receber informações, porém não simultaneamente. Isso significa que apenas um dos dispositivos mestres pode assumir o controle do barramento de cada vez. É importante observar também que cada dispositivo mestre gera o seu próprio sinal de clock. 28 Microcontroladores PIC18 com LinguagemC 8. Quando mais de um dispositivo mestre tenta assumir o controle do barramento no mesmo instante para efetuar uma transmissão, ocorre uma colisão. Um procedimento denominado arbitration assegura que apenas um dos mestres vai concluir a transmissão. Os demais vão abortar a transmissão à medida que vão perdendo a arbitration. O dispositivo mestre que dará continuidade à transmissão será o ganhador da arbitration. O procedimento de arbitration ocorre na linha SDA enquanto a linha SCL estiver em nível lógico alto. A figura a seguir mostra como é feita uma arbitration. O gráfico DADO 1 mostra o sinal que o dispositivo mestre 1 está tentando aplicar na linha SDA, enquanto o gráfico DADO 2 apresenta o sinal que o dispositivo mestre 2 está tentando aplicar na linha SDA. O terceiro gráfico, o SDA, exibe o sinal que irá realmente aparecer na linha SDA. Observe que o dispositivo mestre 1 perdeu a arbitration no terceiro pulso de clock, uma vez que ele aplicou nível lógico 1 na linha SDA, tendo prevalecido o nível lógico '0' aplicado na linha SDA pelo dispositivo mestre 2. Como o dispositivo mestre 1 perdeu a arbitration, ele aborta a transmissão. O dispositivo mestre 2 prossegue a transmissão, tendo em vista que ele foi o ganhador da arbitration. O dispositivo mestre que perdeu a arbitration deve tentar uma nova transmissão quando o barramento estiver novamente ocioso. A arbitration garante que dados não sejam perdidos quando dois ou mais mestres tentam assumir o controle do barramento no mesmo instante. O procedimento de arbitration não é permitido durante as condições START, STOP e Re-START. 9. O módulo MSSP possui seis registradores utilizados na configuração e no controle do barramento I2C. São eles SSPSTAT, SSPCON, SSPCON2, SSPBUF, SSPSR e SSPADD. 10. Um microcontrolador configurado como dispositivo mestre pode dar início a um dos eventos descritos a seguir: Gerar a condição START Gerar a condição Re-START Iniciar a transmissão de um byte escrevendo no registrador SSPBUF (mestre-transmissor) Configurar a interface I2C para receber dados (mestre-receptor) Gerar um pulso ACK (ou um NACK) no final de um byte recebido (mestre-receptor) Gerar a condição STOP e finalizar a transmissão Respostas dos Exercícios 29 11. Gerar a condição START, enviar o byte de endereços junto com a direção do fluxo dos dados como escrita, enviar o byte de dados e gerar uma condição STOP no barramento. 12. Em um barramento I2C as linhas SDA e SCL precisam estar conectadas à linha de alimentação VDD por meio de resistores de pull-up. A função desses resistores, entre outras coisas, é impor nível alto à linha. 13. O 24C08 tem uma capacidade de armazenamento de 8kbits (1k × 8). Em outras palavras, ele possui 1k (1024) de localidades de memória EEPROM com capacidade de armazenamento de 8 bits em cada localidade. Capítulo 21 1. O barramento SPI é composto por três linhas: serial data out (SDO), serial data in (SDI) e serial clock (SCK). Adicionalmente, um quarto sinal pode ser utilizado como chip select e pode selecionar o dispositivo com o qual o mestre vai se comunicar caso existam vários escravos conectados no barramento. Esse quarto sinal é o SS . 2. Sim. Um barramento SPI pode ter um mestre e vários escravos. Cada escravo será ativo por uma linha de controle adicional chamada chip select. Apenas um dispositivo escravo pode estar ativo de cada vez. 3. Os bits SSPM3:SSPM0(SSPCON1<3:0>) são os responsáveis pela configuração do dispositivo operar como mestre ou como escravo, como mostrado a seguir. 0011 = SPI modo mestre, clock = saída do TMR2 / 2 1000 = SPI modo mestre, clock = Fosc / 64 0111 = SPI modo mestre, clock = Fosc / 16 0110 = SPI modo mestre, clock = Fosc / 4 Além disso, para ativar a interface SPI é necessário setar o bit SSPEN (SSPCON1<5>). A polaridade do clock é configurada pelo bit CKP (SSPCON1<4>), ou seja, o bit CKP define se o estado ocioso do clock será o nível alto ou o nível baixo. O estado ocioso é o nível lógico no qual a linha de clock deve se manter quando nenhuma transmissão estiver em andamento. O bit CKE (SSPSTAT<6>) define se a transmissão de cada bit ocorre na transição de ativo para ocioso ou na transição de ocioso para ativo do sinal de clock. O bit CKE determina o momento em que o bit deve ser amostrado no dispositivo escravo. O bit SMP (SSPSTAT<7>) define o momento em que cada bit recebido será amostrado, se na metade ou se no final do time bit. Além disso, é necessário configurar como entrada a linha SDI e como saída as linhas SDO, SS e SCK. A fração de código a seguir mostra como configurar a interface SPI para operar como mestre, com uma taxa de transferência de 125kbps, com o sinal de clock ocioso em nível alto, com a transmissão do dado ocorrendo na transição de estado ocioso para ativo do sinal de clock e com o bit de entrada sendo amostrado no fim do time bit. 30 Microcontroladores PIC18 com Linguagem C #define _SS PORTCbits.RC1 //define linha chip select //**************************************************************************** //Configuração do modulo SPI como mestre com taxa de 125kbps void Configura_SPI (void) TRISCbits. TRISC5 = 0; //configura SDO como saída TRISCbits. TRISC4 = 1; //configura SDI como entrada TRISCbits. TRISC3 = 0; //configura SCK como saída TRISCbits. TRISC1 = 0; //configura linha _SS como saída _SS = 1; //desabilita chip select SSPCON1 = 0b00110000; /*habilita módulo SPI <5> bit rate 125kbps (Fosc/64)<3:0> clock ocioso em nível alto<4>*/ SSPSTAT = 0b00000000; /*dado de entrada é amostrado no fim do time bit do dado de saída<7> transmissão ocorre do estado ocioso para o estado ativo do clock <6>*/ //**************************************************************************** 4. 10Mbps. 5. Independente de o dispositivo mestre precisar enviar e/ou receber dados, é necessário escrever no registrador SSPBUF para dar início a uma transmissão, aguardar a recepção ser finalizada e, em seguida, efetuar a leitura do registrador SSPBUF, onde estará armazenado o byte recebido na transmissão corrente. 6. É setado o bit de sinalização de final de transmissão, o bit SSPIF. 7. O MCP41010 é um potenciômetro digital implementado em circuito integrado com um valor nominal de 10kΩ, fabricado pela Microchip Technology. O protocolo de comunicação utilizado na comunicação com o MCP41010 é o SPI. 8. É possível, por meio de software, colocar o potenciômetro em um modo chamado shutdown, no qual o terminal A do potenciômetro é desconectado do meio exterior, enquanto o cursor é unido ao terminal B. O modo shutdown é conveniente quando o usuário deseja colocar o circuito em modo de economia de energia. Capítulo 22 1. UART (Universal Asynchronous Receiver Transmiter) é um protocolo de comunicação serial assíncrono desenvolvido na década de 1960 para permitir a comunicação ponto a ponto entre computadores mainframes e computadores terminais remotos. 2. Meio ocioso. 3. Taxa de transferência, quantidade de bits de dados, inclusão ou não do bit de paridade, tamanho do stop bit e controle de fluxo. 4. É o tempo no qual cada bit se mantém na linha de transmissão. O período do bit define a taxa de transferência da transmissão. Respostas dos Exercícios 31 5. Par, ímpar, marca ou espaço. Paridade par: a soma dos bits de dados iguais a 1 mais o bit de paridade tem de ser par. Paridade ímpar: a soma dos bits de dados iguais a 1 mais o bit de paridade tem de ser ímpar. Marca: o bit de paridade é sempre 1. Espaço: o bit de paridade é sempre 0. 6. A principal evolução da EUSART é a capacidade de detectar automaticamente a taxa de transferência, um recurso chamado de auto-baud rate detect. Essa característica está disponível somente no modo de transmissão assíncrono. 7. TXSTA, RCSTA e BAUDCON. 8. Para transmissão em alta velocidade e com gerador de baud rate de 16 bits,o valor a ser escrito no par de registradores SPBRGH:SPBRG é 207. 9. Bit SYNC(TXSTA<4>) 10. Inicializar o registrador SPBRGH:SPBRG para o baud rate desejado. Configurar os pinos RC7:RC6 como entrada. Habilitar a porta de comunicação serial apagando o bit SYNC e setando o bit SPEN. Habilitar a interrupção se for desejado. Setar o bit RX9 se a recepção for de 9 bits. Habilitar o transmissor setando o bit TXEN, o qual setará também o bit TXIF. Se a transmissão for de 9 bits, escrever o nono bit no bit TXD9. Carregar o dado a ser transmitido no registrador TXREG (a transmissão terá início). A transmissão estará finalizada quando o bit TRMT for setado pelo hardware. 11. O padrão RS-232 define uma faixa de tensão que deve ser identificada pelos terminais como níveis lógicos '0' e '1'. O nível lógico '1' é representado pela faixa de tensão de –3V a –15V. Da mesma forma, o nível lógico '0' é identificado pela faixa de tensão de 3V a 15V. A faixa de tensão de –3V a +3V é uma região de transição, sendo, portanto, de nível lógico indefinido. 12. O padrão RS-232 foi inicialmente desenvolvido para permitir a comunicação entre computadores conectados a um modem. É muito comum, no entanto, a necessidade de comunicação entre computadores que estejam fisicamente próximos. Nesse caso, não será necessária a utilização de um modem, mas isso não impede a conexão dos computadores via RS-232. O problema é que esta é uma comunicação direta entre dois DTEs e fere a norma de utilização do padrão RS-232, desenvolvida para a comunicação entre um DTE e um DCE. Para resolver o problema foi criado um tipo de conexão chamado Null modem (sem modem). 32 Microcontroladores PIC18 com Linguagem C 13. Número do pino Direção Nome do sinal Descrição do sinal 1 Entrada DCD Data Carrier Detect 2 Entrada RD Receiver Data 3 Saída TD Transmiter Data 4 Saída DTR Data Terminal Ready 5 - Gnd Common 6 Entrada DSR Data Set Ready 7 Saída RTS Request To Send 8 Entrada CTS Clear To Send 9 Entrada RI Ring Indicator 14. Várias empresas fabricam um circuito integrado que permite ao microcontrolador interfacear com o padrão RS-232. O que esse CI faz é converter os níveis de tensão correspondentes à lógica TTL no padrão RS-232 e vice-versa. 15. PIC18F4520 Taxa de transferência 110 a 1.250.000bps Número de bits 8 ou 9 Bit de paridade Não suporta Stop bit 1 Controle de fluxo Não suporta 16. //inicializa USART void Configura_UART (void) { TRISCbits.TRISC7 = 1; //configura pino RX como entrada TRISCbits.TRISC6 = 1; //configura pino TX como entrada TXSTA = 0b00100100; //transmissão habilitada<5> //transmissão assíncrona<4> //transmissão em alta velocidade<2> RCSTA = 0b10010000; //porta serial habilitada<7> //recepção contínua habilitada<4> BAUDCON = 0b00000000; //TX ocioso em nível alto<4> //gerador de baud rate de 8 bits<3> SPBRG = 12; //9600bps Respostas dos Exercícios 33 Capítulo 23 1. Podemos dividir o trabalho de compilar uma aplicação em C em três partes. São elas o pré-processamento, a compilação e a linkedição. O pré-processamento permite incluir no programa-fonte diversos comandos que não fazem parte da linguagem C, mas são reconhecidos pelo compilador. Esses comandos são chamados dire- tivas de compilação. A compilação (ou pré-compilação) tem o objetivo de interpretar os comandos pertencentes à linguagem C existentes no programa-fonte e gerar um bloco de código intermediário chamado arquivo objeto. A última etapa, de linkedição, combina os diversos arquivos objeto e arquivos biblioteca com o link script para gerar o programa executável. Este último contém toda a aplicação representada em linguagem de máquina. 2. O MPLAB C18 possui um módulo chamado MPLIB librarian, responsável pela criação de arquivos biblioteca. O MPLIB combina os arquivos objeto gerados pelo MPASM assembler e pelo MPLAB C18 em um único arquivo biblioteca. O arquivo gerado pelo MPLIB, cuja extensão é .lib, pode ser utilizado como entrada para o MPLNK gerar o arquivo executável. 3. #if e #endif 4. A diretiva #error força o compilador a parar a compilação caso o pré-processador encontre um erro na compilação, como, por exemplo, um símbolo que deveria ter sido definido, mas não foi. É possível, nesse caso, o compilador emitir uma mensagem de erro. Sua principal finalidade é na depuração de uma aplicação, ou seja, um processo que consiste em encontrar e eliminar erros em uma aplicação. 5. Macro pode ser definida, de uma forma geral, como um padrão de entrada que deve ser substituído por um padrão de saída, de acordo com um conjunto de regras. Dependendo do contexto, o termo macro pode ter um significado um pouco diferente. Na linguagem C, pode-se definir macro como uma porção de código que será substituída por outro identificador na fase de pré-processamento. 6. O padrão C ANSI define um conjunto de macros que podem ser úteis em determinadas situações. São elas: __DATE__, __TIME__, __LINE__, __FILE__ e __STDC__ que iniciam com dois underlines e terminam com dois underlines. __DATE__: retorna um ponteiro para uma string armazenada na memória de programa com a data da última compilação. __TIME__: retorna um ponteiro para uma string armazenada na memória de programa com a hora da última compilação. __LINE__: retorna um inteiro com o número da linha do programa-fonte de onde ela foi chamada. 34 Microcontroladores PIC18 com Linguagem C __FILE__: retorna um ponteiro para uma string armazenada na memória de programa com o nome do programa-fonte, incluindo o caminho para chegar ao arquivo. __STDC__: retorna um inteiro informando se o programa-fonte segue o padrão C ANSI. Caso o programa siga o padrão C ANSI, ela retorna o valor 1; caso contrário, ela retorna outro valor. 7. _asm e _endasm. A diretiva _asm inicializa o bloco e a _endasm finaliza o bloco. 8. O MPLAB C18 pode ser configurado para funcionar com dois modelos de memória distintos. São eles o small memory model e o large memory model. A diferença entre os dois modelos é basicamente o tamanho do ponteiro que indica a memória de programa. No small memory model o ponteiro utilizado para o acesso às memórias de dados e de programa é de 16 bits. Sendo assim, o endereçamento da memória está limitado a 64k. No large memory model são utilizados 24 bits no endereçamento da memória. Microcontroladores que possuem mais de 64k de memória de programa precisam funcionar no large memory model. 9. O MPLAB C18 possui uma pilha de estrutura de dados chamada stack software, na qual são armazenadas as variáveis locais com classe de armazenamento auto. O tamanho da stack software pode ser configurado no linker script via diretiva STACK. A diretiva STACK possui dois argumentos, SIZE e RAM, utilizados para controlar, respectivamente, o tamanho e a localização da pilha. Por exemplo, para alocar 128 bytes no banco 3 de memória RAM, é necessário atualizar o linker script com a linha: STACK SIZE=0x80 RAM=gpr3 10. As instruções estendidas são ADDFSR, ADDULNK, CALLW, MOVSF, MOVSS, PUSHL, SUBFSR e SUBULNK. 11. O processamento tem início no vetor Reset, ou seja, no endereço 0000h da memória de programa. Antes da execução da função main() é executado um código de inicialização chamado start-up code que começa com a inicialização dos registradores FSR1 e FSR2 para referenciar a pilha stack software. Dependendo de como o start-up code é executado, uma função que inicializa a seção de dados idata na memória de programa é chamada e, posteriormente, é executado um loop infinito com chamadas à função main(). 12. É possível executar um código específico imediatamente após o Reset, antes do start-up code. Para isso é necessário editar o módulo de inicialização que será linkado com a aplicação e adicionar o código de inicialização à função _entry(). Seis módulos de inicialização podem ser utilizados nostart-up code. São eles os objetos c018i.o, c018i_e.o, c018.o, c018_e.o, c018iz.o e c018iz_e.o. Os módulos c018i.o e c018i_e.o inicializam a seção de dados idata, enquanto os módulos c018.o, c018_e.o não. 13. A otimização tem o objetivo de reduzir o código resultante em uma determinada aplicação. Podemos citar como exemplo de otimização as opções Duplicate-string merging, Branch optimizations e Banking optimizer.
Compartilhar