MICROCONTROLADORES PIC

Documentos relacionados
Interrupções e timers

Sistemas Digitais e Microcontrolados

Um resumo do Microcontrolador PIC18xx

Curso básico de linguagem C para microcontroladores PIC. Índice

Lista de Exercícios 1

Aplicações: Conversão de Códigos e Motor de Passo. Prof. Adilson Gonzaga

TECLADO MATRICIAL. Universidade Tecnológica Federal do Paraná - UTFPR Sistemas Microcontrolados Monitor da disciplina: Luís Paulo Custódio

Sistemas Microcontrolados. Período Aula 6. 1 Saulo O. D. Luiz

Conhecendo o PIC16F877 Microcontrolador de 8 bits da Microchip Co.

Hardware Parte I. Fábio Rodrigues de la Rocha

16F628A - The Configuration Word Jon Wilder 25 de agosto de 2011.

Curso de Linguagem C. Rinaldo Câmara Gonçalves Labtools Mosaico Didactic Division Revisão 2

Programação Básica. Estrutura de um algoritmo

Placa McLab1 Upgrade PIC16F84A p/ PIC16F62x

Linguagem C. Prof.ª Márcia Jani Cícero

Sistemas Microcontrolados

Copyright 2013 VW Soluções

Microcontroladores PIC. Microcontroladores PIC

Sistemas Microprocessados baseados no PIC16F877A

Capítulo 2: Introdução à Linguagem C

Estrutura do programa

Copyright 2011 VW Soluções

Comunicação USB com o PIC Vitor Amadeu Souza Parte II vitor@cerne-tec.com.br

Seqüencial de Leds utilizando o microcontrolador PIC16F628A Vitor Amadeu

Linguagem C. Programação Estruturada. Fundamentos da Linguagem. Prof. Luis Nícolas de Amorim Trigo

Sistemas Embarcados. Introdução aos sistemas embarcados

Introdução a Programação de Jogos

MODULAÇÃO DE UM SINAL ANALÓGICO

Capítulo 2 Operadores. A função scanf()

Copyright 2014 VW Soluções

8051 PROGRAMAÇÃO EM C

Algoritmos e Estruturas de Dados I (DCC/003) 2013/1. Estruturas Básicas. Aula Tópico 4

Programação Básica em Arduino Aula 2

Computação para Informática - Prof. Adriano Joaquim de Oliveira Cruz Segunda Aula Prática - 29 de agosto de 2008

Linguagem C Controle do Fluxo de Execução. Lógica de Programação

Comunicando com um teclado PS2 Vitor Amadeu Souza

TEM VÁRIOS ESTADOS: 0V,0.1V,3V,3.3V,4V,5V,10V, ETC.

Binário para Decimal. Binário: = 19. Decimal:

Variáveis, Tipos de Dados e Operadores

INF 1005 Programação I

V1 5V +V. (14)Vdd (6)RB0 PIC 16F628A. (16) Clk-out. C1 33pF. C2 33pF. Figura 1 Circuito pisca-pisca.

(a partir da versão 1.27 Beta) Rev. 0 em Copyright Junho/2003 Renie S. Marquet

Introdução à robótica

INTRODUÇÃO A LINGUAGEM C

Comércio e Manutenção de Produtos Eletrônicos. Mapeamento de memória e conexões do Controlador CP-WS13/8DI8DO2AI2AO/USB/OEM. Versão 1.

PIC16F628a. Pinagem do PIC16F628a:

UNIVERSIDADE FEDERAL DO PARANÁ MICROCONTROLADOR PIC 18F452 / PROTEUS

Comunicação RC5 com o dspic Vitor Amadeu Souza

arduino = new roboticalivre(); Arduino Marcus Fazzi

EPAC Microcontroladores Organização do curso 30/8/2007

Introdução ao Arduino. Pessanha Santos ASPOF EN-AEL

Cerne Tecnologia e Treinamento

Introdução à Programação em C (I)

Estrutura de Programas e Tipos de Dados Simples

MICROCONTROLADORES PIC PRIMEIROS PASSOS

PROGRAMAÇÃO DE UM MICROPROCESSADOR

MICROCONTROLADORES NO RADIOAMADORISMO

Arquitetura de Computadores. Tipos de Instruções

Componentes da linguagem C++

MC102 Algoritmos e Programação de Computadores

Provisório. Development of integrated electroestimulation equipment for medical rehabilitation of spinal cord injuries. Universidade de Aveiro

Érica Ltda. Microcontroladores PIC18 com Linguagem C. Wagner da Silva Zanco. Uma Abordagem Prática e Objetiva. Com Base no PIC18F4520.

Estruturas de Repetição. for() while() do-while() break; continue;

José Romildo Malaquias

KIT INICIANTE V7 PARA ARDUINO

Edwar Saliba Júnior. Dicas, Comandos e Exemplos Comparativos entre Linguagem Algorítmica e Linguagem C

int pinosensor = A0; //define a variável como entrada analógica //no pino A0 para o sensor LM35.

Microcontroladores e FPGAs

Introdução à Programação em C (I)

2. OPERADORES ALGORITMOS, FLUXOGRAMAS E PROGRAMAS FUNÇÕES... 10

CURSO TERMO TURMA PERIODO DISCIPLINA ENGENHARIA MECATRÔNICA 8 A NOTURNO SISTEMAS DE AQUISIÇÃO DE DADOS

Linguagem C: variáveis, operadores, entrada/saída. Prof. Críston Algoritmos e Programação

Instituto Federal de Educação, Ciência e Tecnologia da Paraíba. Microcontrolador PIC 16F877

Suporta os microcontroladores: R. Leonardo da Vinci, Campinas/SP CEP F.: (19) /

Microcontroladores. Prof. Nivaldo T. Schiefler Jr. M.Eng Homepage:

Kit de desenvolvimento ACEPIC PRO V3.0

ABB Automação. Indicador Digital Processos Pt100 e TAP s MODO DE USO. Dados Técnicos Conexões elétricas Utilização do teclado Dimensional

Comunicação Serial. Comunicação Serial

Introdução a Computação

INF 1005 Programação I

Sumário. 1. Apresentação Hardware Microcontrolador PIC16F877A LCD alfanumérico Displays de 7 segmentos...

Funções em C. Lucas Ferrari de Oliveira Professor Adjunto. Linguagem de Programação Estruturada I. Universidade Federal do Paraná

Programação em BASIC para o PIC Mostrando Mensagens no Display LCD Vitor Amadeu Souza

Microprocessadores e Aplicações

Controlador de DMA. Gustavo G. Parma

Resumo da Introdução de Prática de Programação com C. A Linguagem C

Manipulação de Arquivos

Organização e Arquitetura de Computadores I

Programação Daniel Corteletti Aula 3 Parte III Página 1/7

UNICEUB CENTRO UNIVERSITÁRIO DE BRASÍLIA FATECS FACULDADE DE TECNOLOGIA E CIÊNCIAS SOCIAIS APLICADAS CURSO DE ENGENHARIA DA COMPUTAÇÃO

3. INTRODUÇÃO À LINGUAGEM C 3.1. CONCEITOS BÁSICOS. Lógica de Programação

PROGRAMAÇÃO DO TREINAMENTO:

Professor: Vlademir de Oliveira Disciplina: Microcontroladores e DSP. Memórias de Dados e de Programa

12/11/13. Obje%vos do laboratório. SST20707 Síntese de Sistemas de Telecomunicações. Síntese de máquinas de estado (FSM) Finite State Machine (FSM)

Programação em BASIC para o PIC Projetos com Display Gráfico Vitor Amadeu Souza

Departamento de Informática - PUC-Rio INF 1005 Programação I P1 22/09/2010 Nota

Faculdade de Engenharia de Ilha Solteira- Departamento de Engenharia Elétrica

Algoritmos e Programação

CATÁLOGO ENERGIA SOLAR FOTOVOLTAICA CONTROLADORES SOLARES

Transcrição:

MICROCONTROLADORES PIC PRÁTICA MSc. Gustavo Souto de Sá e Souza

INTRODUÇÃO Para fins de avaliação e estudo prático, usaremos os microcontroladores da família PIC18, mais especificamente o PIC18F45K20. É importante lembrar que as informações contidas aqui podem variar para outras famílias PIC ou até mesmo para outros chips da mesma família.

LINGUAGEM C COMPILADOR XC8 Inicialização da variável variavel : Bit ou boolean: bit variavel; Valor inteiro: int variavel; Valor inteiro com sinal (positivo ou negativo): signed int variavel; Caractere: char variavel; String (conjunto de, digamos, 10 caracteres): char variavel[10]; Valor flutuante: float variavel;

LINGUAGEM C COMPILADOR XC8 Definição de variável: Decimal: variavel = 100; Binário: variavel = 0b1100100; Hexadecimal: variavel = 0x64; Caractere: variavel = d ;

LINGUAGEM C COMPILADOR XC8 Operações: Definição de variável: variavel = 255; Soma: variavel = 15 + b; Subtração: variavel = 15 - b; Multiplicação: variavel = 15 * b; Divisão: variavel = 15 / b; Rotação de N bits para esquerda: variavel = variavel << N; Rotação de N bits para a direita: variavel = variavel >> N;

LINGUAGEM C COMPILADOR XC8 Operações: Operação E: variavel = variavel & 55; Operação OU: variavel = variavel 55; Operação NÃO (inverte apenas 1 bit): variavel =!variavel; Incrementar em 1: variavel++; Decrementar em 1: variavel--;

LINGUAGEM C COMPILADOR XC8 Condições (retornam 1 se verdadeiro, 0 se falso): Verificar se é igual: (variavel == b); Verificar se é diferente: (variavel!= b); Verificar se é maior: (variavel > b); Verificar se é menor: (variavel < b); Verificar se é maior ou igual: (variavel >= b); Verificar se é menor ou igual: (variavel <= b); Condição E: (variavel <= b && variavel!= 0); Condição OU: (variavel <= b variavel!= 0);

LINGUAGEM C COMPILADOR XC8 Definições: Define _constante como 5: #define _constante 5 Define PINO_DO_LED como LATD1: #define PINO_DO_LED LATD1 Inclusões de bibliotecas: Inclui biblioteca do compilador: #include <stdlib.h> Inclui biblioteca da pasta local: #include lcd.h

LINGUAGEM C COMPILADOR XC8 Se: if: if (variavel == 10) { // executa se condição for verdadeira else { // executa se condição for falsa

LINGUAGEM C COMPILADOR XC8 Se: if: if (variavel == 10) { Condição // executa se condição for verdadeira else { // executa se condição for falsa

LINGUAGEM C COMPILADOR XC8 Loops: While: while (variavel!= 0) { // código em loop

LINGUAGEM C COMPILADOR XC8 Loops: While: while (variavel!= 0) { // código em loop Condição (executa enquanto for 1)

LINGUAGEM C COMPILADOR XC8 Loops: for: for (variavel = 1; variavel < 100; variavel++) { // código em loop

LINGUAGEM C COMPILADOR XC8 Valor inicial Loops: for: for (variavel = 1; variavel < 100; variavel++) { // código em loop

LINGUAGEM C COMPILADOR XC8 Condição (executa enquanto for 1) Loops: for: for (variavel = 1; variavel < 100; variavel++) { // código em loop

LINGUAGEM C COMPILADOR XC8 Incremento Loops: for: for (variavel = 1; variavel < 100; variavel++) { // código em loop

LINGUAGEM C COMPILADOR XC8 Loops: break: for (variavel = 1; variavel < 100; variavel++) { // código em loop if (variavel < 0) { break;

LINGUAGEM C COMPILADOR XC8 Loops: break: for (variavel = 1; variavel < 100; variavel++) { // código em loop if (variavel < 0) { break; Finaliza e sai do loop aqui

LINGUAGEM C COMPILADOR XC8 Funções: Principal: void main (void) { // Código principal do programa vem aqui

LINGUAGEM C COMPILADOR XC8 Funções: Interrupção: void interrupt int_func (void) { // Código da interrupção

LINGUAGEM C COMPILADOR XC8 Funções: Interrupção de baixa prioridade: void interrupt low_priority int_low_funcao (void) { // Código da interrupção de baixa prioridade

LINGUAGEM C COMPILADOR XC8 Funções: Secundárias: void LigaTimer (void) { TMR0ON = 1;

LINGUAGEM C COMPILADOR XC8 Funções: Secundárias com valores de entrada e saída: int SomaDez (int valor_de_entrada) { valor_de_entrada = valor_de_entrada + 10; return valor_de_entrada;

LINGUAGEM C COMPILADOR XC8 Chamando Funções: LigaTimer(); variavel = SomaDez(variavel);

LINGUAGEM C COMPILADOR XC8 Função de atraso por milissegundo: delay_ms(tempo_em_milissegundos);!!! Requer que a velocidade do oscilador seja definido antes, por meio da linha #define _XTAL_FREQ 1000000 (para um oscilador de 1 MHz) Também requer a library xc.h incluída por meio da linha: #include <xc.h> Pode causar erro se o valor de entrada for muito grande, relativo à velocidade do oscilador.

LINGUAGEM C COMPILADOR XC8 Comentando o código: TRISA = 0; // A parte comentada vem depois de // duas barras /* Ou você pode comentar todo um trecho do código usando asterisco e barra */ ok++;

LINGUAGEM C COMPILADOR XC8 sprintf: imprime e manipula strings e caracteres. Requer que a biblioteca stdio.h seja incluída. #include <stdio.h> char linha1[16]; sprintf(linha1, Hello, world! ); // Grava o texto Hello, world! na variável linha1

LINGUAGEM C COMPILADOR XC8 char linha1[16]; contador = 15; sprintf(linha1, Contagem: %i, contador); // Grava o texto Contagem: 15 na variável linha1 // %i imprime um número inteiro

LINGUAGEM C COMPILADOR XC8 char linha1[16]; contador = 15; sprintf(linha1, Contagem: %3.2i, contador); // Grava o texto Contagem: 15.00 na variável linha1 // %X.Yi imprime um número inteiro com X casas fixas // antes do separador decimal e Y fixas casas depois

LINGUAGEM C COMPILADOR XC8 char linha1[16]; temperatura = 37.52; sprintf(linha1, Graus: %2.2f, temperatura); // Grava o texto Graus: 37.52 na variável linha1 // %f imprime um número de ponto flutuante

LINGUAGEM C COMPILADOR XC8 char linha1[16]; caractere_u = 0x55; sprintf(linha1, Letra U: %c, caractere_u); // Grava o texto Letra U: U na variável linha1 // %c imprime um caractere correspondente à tabela // ASCII

LINGUAGEM C COMPILADOR XC8 Definindo bits de Configuração: #pragma config LVP = OFF; // Desabilita o bit ICSP de fonte de alimentação simples (única)

LINGUAGEM C COMPILADOR XC8 Bits de Configuração essenciais: FOSC: // Frequência do oscilador Define a origem do oscilador principal do microcontrolador. Mais usados: #pragma config FOSC = INTIO; (oscilador interno) #pragma config FOSC = XT; (cristal externo) #pragma config FOSC = HS; (cristal externo rápido)

LINGUAGEM C COMPILADOR XC8 Bits de Configuração essenciais: WDTEN: Watchdog Timer enable. Habilita o reset automático do Watchdog Timer. Caso o comando ClrWdt() não seja executado num dado número de instruções, o microcontrolador será ressetado: #pragma config WDTEN = OFF; #pragma config WDTPS = 32768; No PIC18F4550: #pragma config WDT = OFF; // desabilita watchdog timer #pragma config WDTPS = 32768;

LINGUAGEM C COMPILADOR XC8 Bits de Configuração essenciais: MCLRE: Master Clear enable. Habilita ou desabilita o pino de reset no microcontrolador. #pragma config MCLRE = OFF;

LINGUAGEM C COMPILADOR XC8 Bits de Configuração essenciais: PBADEN: Habilita ou desabilita o conversor Analógico-Digital na porta B. Caso for utilizar interrupção na porta B ou usá-la como entrada/saída digital, este deve estar desabilitado. Por padrão é habilitado: #pragma config PBADEN = OFF;

LINGUAGEM C COMPILADOR XC8 Bits de Configuração não tão essenciais (podem ficar no valor padrão): PWRT: Aguarda um tempo depois de ligar para iniciar o programa. Habilitá-lo evita instabilidade no programa devido a oscilações na alimentação e oscilador: #pragma config PWRT = ON;

LINGUAGEM C COMPILADOR XC8 Bits de Configuração não tão essenciais (podem ficar no valor padrão): BOREN: Brown-out reset enable. Habilita o reset automático em caso de baixa tensão de alimentação: #pragma config BOREN = SBORDIS;

LINGUAGEM C COMPILADOR XC8 Registradores essenciais: OSCCON: Byte que define a frequência do oscilador interno do PIC18F45K20: OSCCON=0b01110000; // Frequência: 16 MHz OSCCON=0b01100000; // Frequência: 8 MHz OSCCON=0b01010000; // Frequência: 4 MHz OSCCON=0b00110000; // Frequência: 1 MHz (padrão)

LINGUAGEM C COMPILADOR XC8 Registradores essenciais: OSCCON: Byte que define a frequência do oscilador interno do PIC18F4550: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 IDLEN IRCF2 IRCF1 IRCF0 OSTS IOFS SCS1 SCS0 Bits de seleção da frequência OSCCON=0b01110000; OSCCON=0b01100000; OSCCON=0b01010000; OSCCON=0b01000000; OSCCON=0b00110000; OSCCON=0b00100000; // Frequência: 8 MHz // Frequência: 4 MHz // Frequência: 2 MHz // Frequência: 1 MHz (padrão) // Frequência: 500 khz // Frequência: 250 khz

LINGUAGEM C COMPILADOR XC8 Registradores importantes - interrupção: GBIE: bit que habilita a interrupção global: GBIE = 1; // Habilita interrupção PBIE: bit que habilita a interrupção de periféricos (timer2, adc): PBIE = 1; // Habilita interrupção de periféricos INTXIE: bit que habilita a interrupção externa X (X = 0, 1 ou 2): INT0IE = 1; // Habilita interrupção externa 0

LINGUAGEM C COMPILADOR XC8 Registradores importantes - interrupção: ADIF: bit que habilita a interrupção do conversor AD: ADIF = 1; // Habilita interrupção do ADC TXIE: bit que habilita a interrupção de transmissão da serial: TXIE = 1; // Habilita interrupção do TX da serial RCIE: bit que habilita a interrupção de recepção da serial: RCIE = 1; // Habilita interrupção do RX da serial

LINGUAGEM C COMPILADOR XC8 Registradores importantes - interrupção: TMRXIE: bit que habilita o timer X (X pode ser 0, 1, 2 ou 3): TMR3IE = 1; // Habilita interrupção do TMR3

LINGUAGEM C COMPILADOR XC8 Registradores importantes interrupção (flags): INTXIF: bit que sinaliza a flag da interrupção externa X (X=0, 1, 2): INT0IF = 0; // Limpa a flag do INT0 TMRXIF: bit que sinaliza a flag de interrupção do timer X (X=0, 1, 2, 3): TMR3IF = 0; // Limpa a flag do TMR3 ADIF: bit que sinaliza a flag de interrupção do ADC: ADIF = 0; // Limpa a flag do ADC

LINGUAGEM C COMPILADOR XC8 Registradores importantes ADC : ADCON0bits.GO: bit que inicia a conversão analógica: ADCON0bits.GO = 1; // Inicia a conversão AD ADCON0bits.DONE: flag que sinaliza o fim da conversão analógica: while (!ADCON0bits.DONE) { // Aguarda finalização da conversão AD

LINGUAGEM C COMPILADOR XC8 Registradores importantes ADC : ANSEL e ANSELH: bytes que selecionam quais canais analógicos ficam ativos: ANSEL = 0b00010100; // Habilita ADC nas portas // AN2 e AN4 ANSELH = 0b00011111; // Habilita ADC nas portas // AN8 até AN12

LINGUAGEM C COMPILADOR XC8 Registradores importantes ADC (PIC18F4550): ADCON0: Registrador de Controle do ADC Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 X X CHS3 CHS2 CHS1 CHS0 GO/DONE\ ADON Bits de seleção do Canal Analógico Status da conversão Habilita ADC ADCON0bits.CHS = 0b0000 Seleção do Canal AN0 ADCON0bits.CHS = 0b0001 Seleção do Canal AN1 ADCON0bits.ADON = 1 Liga o ADC ADCON0bits.GO = 1 Inicia a conversão A/D

LINGUAGEM C COMPILADOR XC8 Registradores importantes ADC (PIC18F4550): ADCON1: Registrador de Controle do ADC Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 X X VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0 Bits de configuração da tensão de referência ADCON1bits.VCFG = 0b00; Tensões de referência: Vss e Vdd

LINGUAGEM C COMPILADOR XC8 Registradores importantes ADC (PIC18F4550): ADCON2: Registrador de Controle do ADC Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 ADFM - ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0 Formato do resultado Bits de seleção do Tempo de Aquisição de dados ADCON2bits.ADCS = 0b110 Clock do AD: Fosc/64 Bits de seleção do Clock de conversão ADCON2bits.ACQT = 0b010 Tempo de aquisição: 4 T AD ADCON2bits.ADFM = 0b1 Formato do resultado: justificado à direita

LINGUAGEM C COMPILADOR XC8 Registradores importantes ADC : ADRESL: byte que guarda os 8 bits menos significativos da conversão AD: ADRESH: byte que guarda os 8 bits mais significativos da conversão AD: valor_convertido = (ADRESH * 0x0100) + ADRESL; // guarda o valor da conversão AD na variável // de 16 bits valor_convertido

LINGUAGEM C COMPILADOR XC8 Registradores importantes PWM: CCPR2L: byte que define o duty cycle do PWM2: CCPR2L = 26; // Define PWM com duty-cycle de 10% CCPR2L = 255; // Define PWM com duty-cycle de 100% CCPR2L = 128; // Define PWM com duty-cycle de 50% CCPR2L = 77; // Define PWM com um duty-cycle de 30%

EXEMPLO PISCAR LED Inicio Configuração Inverte sinal do pino D0 Atrasa 100 ms

EXEMPLO PISCAR LED #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF void main(void) { OSCCON = 0b01100000; TRISD = 0b00000000; // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Define velocidade do oscilador para 4MHz // Habilita porta D como saída while(1) { LATDbits.LATD0 =!LATDbits.LATD0; delay_ms(100); // Inicia loop infinito // Inverte sinal do pino D0 // Atraso de 100 ms Fim de Código

EXEMPLO PISCAR LED 1 SEGUNDO Inicio Configuração Inverte sinal do pino D0 Atrasa 100 vezes 10 ms

EXEMPLO PISCAR LED 1 SEGUNDO #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado void SuperDelay(long counter) { // Função com valor de entrada counter counter = counter / 10; // Divide o valor informado por 10 for (long i = 1; i <= counter; i++) { // E usa o resultado como base delay_ms(10); // Para repetir uma contagem de 10 ms void main(void) { OSCCON = 0b01010000; TRISD = 0b00000000; // Define velocidade do oscilador para 4MHz // Habilita porta D como saída

EXEMPLO PISCAR LED 1 SEGUNDO while(1) { LATDbits.LATD0 =!LATDbits.LATD0; SuperDelay(1000); // Inicia loop infinito // Inverte sinal do pino D0 // Atraso de 1 s Fim de Código

EXEMPLO ROTACIONAR LED Inicio Configuração Rotaciona para a esquerda sim LED aceso na borda direita? não não LED aceso na borda esquerda? sim Rotaciona para a direita

EXEMPLO ROTACIONAR LED #define _XTAL_FREQ 1000000 #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador de 4 MHz // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado void main(void) { TRISA = 0b00000000; // Habilita porta A como saída LATA = 1; // Liga o primeiro pino da porta A while(1) { // Inicia loop infinito while(lata!= 0b00000001) { LATA = (LATA >> 1 LATA << 7); // Rotacionando com estilo pra esquerda delay_ms(100); // Atraso de 100 ms while(lata!= 0b10000000) { LATA = (LATA << 1 LATA >> 7); // Rotacionando com estilo pra direita delay_ms(100); // Atraso de 100 ms Fim de Código

EXEMPLO ROTACIONAR LED - EXPLICAÇÃO Digamos que LATA = 0b00000001 LATA >> 1 retorna o seguinte valor: 0b00000000, pois rotacionou o 1 para a direita e ele caiu fora dos 8 bits. O oitavo bit é preenchido com 0. LATA << 7 retorna o seguinte valor: 0b10000000, pois rotacionou o 1 um total de sete bits para a esquerda e ele ficou no lugar do oitavo bit. Os 7 primeiros bits são preenchidos com 0. Fazendo a operação OU entre ambos, temos (LATA >> 1 LATA << 7) = 0b10000000; Continuemos com LATA = 0b10000000 LATA >> 1 retorna o seguinte valor: 0b01000000, pois rotacionou o 1 para a direita e ele caiu no lugar do sétimo bit. O oitavo bit é preenchido com 0. LATA << 7 retorna o seguinte valor: 0b00000000, pois rotacionou o 1 um total de sete bits para a esquerda e ele saiu do espaço dos bits. Os 7 primeiros bits são preenchidos com 0. Fazendo a operação OU entre ambos, temos (LATA >> 1 LATA << 7) = 0b01000000;

EXEMPLO LCD Inicio Configuração Adiciona 1 em contador Atualiza LCD com valor de contador

EXEMPLO LCD #define _XTAL_FREQ 1000000 #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h>

EXEMPLO LCD char linha1[16]; // Variável linha1 com 16 caracteres char linha2[16]; // Variável linha2 com 16 caracteres int contador = 0; // Variável contador com valor inicial 0 void main(void) { TRISD = 0; // Define porta D inteira como saída Lcd_Init(); // Inicia o LCD sprintf(linha1, "Hello world! "); // Grava texto em linha1 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD while(1) { sprintf(linha2, "Contador: %i ",contador); // Grava texto em linha2 contador ++; // Incrementa contador Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD Fim de Código

EXEMPLO LCD + CONTADOR FLOAT Inicio Configuração Adiciona 1 em contador Atualiza LCD com valor de contador

EXEMPLO LCD + CONTADOR FLOAT #define _XTAL_FREQ 1000000 #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h>

EXEMPLO LCD + CONTADOR FLOAT char linha1[16]; // Variável linha1 com 16 caracteres char linha2[16]; // Variável linha2 com 16 caracteres float contador = 0.0; // Variável contador com valor inicial 0.0 void main(void) { TRISD = 0; // Define porta D inteira como saída Lcd_Init(); // Inicia o LCD sprintf(linha1, "Hello world! "); // Grava texto em linha1 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD while(1) { sprintf(linha2, "Contador: %3.2f",contador); // Grava texto em linha2 contador = contador + 0.01; // Incrementa contador em 0.01 Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD Fim de Código

EXEMPLO INTERRUPÇÃO (INT0) Inicio Configuração Aguarda interrupção não Interrupção ativada? sim Inverte sinal do LED

EXEMPLO INTERRUPÇÃO (INT0) #define _XTAL_FREQ 1000000 #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF #pragma config PBADEN = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Conversor AD da porta B desligado void setupint(void) { GIE = 1; // Habilita interrupção global INT0IE = 1; // Interrupção da INT 0 INT0F = 0; // Flag de interrupção da INT 0 INTEDG0 = 1; // Interrupção por borda crescente.

EXEMPLO INTERRUPÇÃO (INT0) void interrupt interrupcao(void) { if (INT0F) { LATAbits.LA0 =!LATAbits.LA0; INT0F = 0; void main(void) { TRISA = 0x00; TRISB = 0x01; setupint(); while(1) { // Função de interrupção // Caso a flag da INT0 esteja habilitada // Inverte o sinal no pino A0 // Desabilita a flag da INT0 // Porta A com todos pinos de saída // Somente pino B1 como entrada (INT0) // Função de inicializar Interrupção // Loop infinito // O código acima inverte o sinal no pino A0 a cada pressionar de um botão ligado à INT0 Fim de Código

EXEMPLO TEMPORIZADOR 0 Inicio Configuração (temporizador configurado para gerar interrupção a cada 50 ms) Aguarda interrupção não Interrupção ativada? sim Inverte sinal do LED

EXEMPLO TEMPORIZADOR 0 #define _XTAL_FREQ 4000000 #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador a 4 MHz. O número de instruções por // segundo é de 1 milhão. O tempo para executar uma // instrução (e do tick do timer) é de 1 us. // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado void setupint(void) { GIE = 1; // Habilita interrupção global TMR0IE = 1; // interrupção do Timer 0 void setuptmr0() { T08BIT = 0; // Modo 16 bits T0CS = 0; // Source do clock PSA = 1; // Desabilita Prescaler TMR0H = 0x3C; // Começa a contar de 15535 TMR0L = 0xAF; // até 65535 (conta 50 mil vezes) TMR0ON = 1; // Liga o timer

EXEMPLO TEMPORIZADOR 0 void interrupt interrupcao(void) { // Função de interrupção if (TMR0IF) { // Caso a flag do temporizador esteja ativa LATAbits.LA0 =!LATAbits.LA0; // Inverte pino A0 TMR0H = 0x3C; // Começa a contar de 15535 TMR0L = 0xAF; // até 65535 (conta 50 mil vezes) TMR0IF = 0; // Flag do timer 0 em 0 void main(void) { OSCCON = 0b01010000; // Oscilador a 4 MHz (1 tick do timer = 1 us) setupint(); // Função de habilitar interrupção setuptmr0(); // Função de configurar timer 0 TRISA = 0x00; // Porta A como saída while(1) { // Loop infinito // O código acima inverte o sinal do pino A0 a cada 50000 us, via temporizador 0. Fim de Código

EXEMPLO TEMPORIZADOR 0 + PRESCALER Inicio Configuração (temporizador configurado para gerar interrupção a cada 1s) Aguarda interrupção não Interrupção ativada? sim Inverte sinal do LED

EXEMPLO TEMPORIZADOR 0 + PRESCALER #define _XTAL_FREQ 4000000 #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador a 4 MHz. O número de instruções por // segundo é de 1 milhão. O tempo para executar uma // instrução (e do tick do timer) é de 1 us. // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado void setupint(void) { GIE = 1; // Habilita interrupção global TMR0IE = 1; // interrupção do Timer 0 void setuptmr0() { T08BIT = 0; T0CS = 0; PSA = 0; T0PS0 = 0; T0PS1 = 0; T0PS2 = 1; // Modo 16 bits // Source do clock // Habilita Prescaler // Multiplicador Prescaler // 32 vezes // 32 x 31250 us = 1 segundo

EXEMPLO TEMPORIZADOR 0 + PRESCALER TMR0H = 0x85; // Começa a contar de 34285 TMR0L = 0xED; // até 65535 (conta 31250 vezes) TMR0ON = 1; // Liga o timer void interrupt interrupcao(void) { // Função de interrupção if (TMR0IF) { // Caso a flag do temporizador esteja ativa LATAbits.LA0 =!LATAbits.LA0; // Inverte pino A0 TMR0H = 0x85; // Começa a contar de 34285 TMR0L = 0xED; // até 65535 (conta 31250 vezes) TMR0IF = 0; // Flag do timer 0 em 0 void main(void) { OSCCON = 0b01010000; // Oscilador a 4 MHz (1 tick do timer = 1 us) setupint(); // Função de habilitar interrupção setuptmr0(); // Função de configurar timer 0 TRISA = 0x00; // Porta A como saída while(1) { // Loop infinito

EXEMPLO TEMPORIZADOR 0 + PRESCALER // O código acima inverte o sinal do pino A0 a cada 1 s, via temporizador 0. Fim de Código

EXEMPLO TEMPORIZADOR 2 Inicio Configuração (temporizador configurado para gerar interrupção a cada 10 ms) Aguarda interrupção não Interrupção ativada? sim Inverte sinal do LED

EXEMPLO TEMPORIZADOR 2 #define _XTAL_FREQ 4000000 #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador a 4 MHz. O número de instruções por // segundo é de 1 milhão. O tempo para executar uma // instrução (e do tick do timer) é de 1 us. // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado void setupint(void) { GIE = 1; // Habilita interrupção global PEIE = 1; // Timer 2 exige interrupção de periféricos habilitada TMR2IE = 1; // interrupção do Timer 2 void setuptmr2() { T2CKPS0 = 1; // Prescaler x 4 T2CKPS1 = 0; // T2OUTPS0 = 0; // Postscaler x 10 T2OUTPS1 = 1; // T2OUTPS2 = 0; // Conta 250 (PR2, abaixo) x 4 (prescaler) x 10 (postscaler) vezes T2OUTPS3 = 1; // totalizando 10000 vezes (~10 ms) por interrupção

EXEMPLO TEMPORIZADOR 2 TMR2 = 0x00; // Começa a contar de 0 PR2 = 249; // até 249 (conta 250 vezes + recarga automatica) TMR2ON = 1; // Liga o timer void interrupt interrupcao(void) { // Função de interrupção if (TMR2IF) { // Caso a flag do temporizador esteja ativa LATAbits.LA0 =!LATAbits.LA0; // Inverte pino A0 TMR2IF = 0; // Flag do timer 2 em 0 void main(void) { OSCCON = 0b01100000; // Oscilador a 4 MHz (1 tick do timer = 1 us) setupint(); // Função de habilitar interrupção setuptmr2(); // Função de configurar timer 0 TRISA = 0x00; // Porta A como saída while(1) { // Loop infinito // O código acima inverte o valor do pino A0 a cada 10 ms usando o Timer 2. Fim de Código

EXEMPLO CONVERSOR ANALÓGICO-DIGITAL Inicio Configuração Inicia leitura da tensão no pino A0 não Finalizou leitura? sim Grava valor da leitura nos bits da porta C e D

EXEMPLO CONVERSOR ANALÓGICO-DIGITAL #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF void main(void) { OSCCON = 0b01100000; TRISD = 0b00000000; TRISC = 0b00000000; TRISA = 0x00000001; // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Define velocidade do oscilador para 4MHz // Habilita porta D como saída // Habilita porta C como saída // Habilita pino A0 como entrada ADCON2 = 0b10101111; // ADCON1 = 0b00000000; // Tensões de referência: Vss e Vdd ANSEL = 0x00000001; // Seleciona o canal AN0

EXEMPLO CONVERSOR ANALÓGICO-DIGITAL ADCON0bits.ADON = 1; // Habilita o conversor AD while(1) { ADCON0bits.GO = 1; while (!ADCON0bits.GODONE) { LATD = ADRESL; LATC = ADRESH; delay_ms(100); // Inicia loop infinito // Inicia a conversão // Aguarda fim da conversão // Transfere valor para porta D // Transfere valor para porta C // Atraso de 100 ms Fim de Código

EXEMPLO ADC + LCD Inicio Configuração Inicia leitura da tensão no pino A0 não Finalizou leitura? sim Calcula tensão no pino e exibe valor lido e tensão calculada no LCD

EXEMPLO ADC + LCD #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h> char linha1[16]; char linha2[16]; // Variável linha1 com 16 caracteres // Variável linha2 com 16 caracteres

EXEMPLO ADC + LCD int contador = 0; // Variável contador com valor inicial 0 float tensao = 0.0; // Variável tensao com valor inicial 0.0 void setupadc(void) { TRISA = 0b00000001; ADCON2bits.ADCS = 0b111; ADCON2bits.ACQT = 0b110; ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; ANSEL = 0x00000001; // Habilita pino A0 como entrada // Tempo de aquisição: 4 Tad // Clock do AD: Fosc/64 // Formato: à direita // Tensões de referência: Vss e Vdd // Seleciona o canal AN0 ADCON0bits.ADON = 1; // Liga o AD void main(void) { OSCCON = 0b01010000; TRISD = 0b00000000; // Define velocidade do oscilador para 4MHz // Habilita porta D como saída

EXEMPLO ADC + LCD setupadc(); Lcd_Init(); // Inicia o LCD while(1) { // Inicia loop infinito ADCON0bits.GO = 1; // Inicia a conversão A/D while (!ADCON0bits.GODONE) { // Aguarda fim da conversão contador = (ADRESH * 0x100) + ADRESL; // Transfere valor para variável tensao = ((5 * contador) * 0.0009765625); // Calcula tensão real sprintf(linha1, "Conversor: %4i ", contador); // Grava texto em linha1 sprintf(linha2, "Tensao: %1.2f ",tensao); // Grava texto em linha2 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD Fim de Código

EXEMPLO ADC + LCD + DOIS CANAIS Inicio Configuração Lê tensão no pino A0 Atualiza LCD com valor lido Atualiza LCD com valor lido Lê tensão no pino A1

EXEMPLO ADC + LCD + DOIS CANAIS #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h> char linha1[16]; char linha2[16]; // Variável linha1 com 16 caracteres // Variável linha2 com 16 caracteres

EXEMPLO ADC + LCD + DOIS CANAIS int contador = 0; // Variável contador com valor inicial 0 float tensao1 = 0.0; // Variável tensao com valor inicial 0.0 float tensao2 = 0.0; // Variável tensao com valor inicial 0.0 void setupadc(void) { TRISA = 0b00000011; ADCON2bits.ADCS = 0b111; ADCON2bits.ACQT = 0b110; ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; ANSEL = 0b00000011; // Habilita pinos A0 e A1 como entrada // Tempo de aquisição: 4 Tad // Clock do AD: Fosc/64 // Formato: à direita // Tensões de referência: Vss e Vdd // Habilita canais AN0 e AN1 como AD ADCON0bits.ADON = 1; // Liga o circuito AD void main(void) { OSCCON = 0b01010000; // Define velocidade do oscilador para 4MHz

EXEMPLO ADC + LCD + DOIS CANAIS TRISD = 0b00000000; // Habilita porta D como saída setupadc(); Lcd_Init(); // Inicia o LCD while(1) { // Inicia loop infinito ADCON0bits.CHS = 0b0000; // Seleciona canal AN0 ADCON0bits.GO = 1; // Inicia a conversão while (!ADCON0bits.GODONE) { // Aguarda fim da conversão contador = (ADRESH * 0x100) + ADRESL; // Transfere valor para variável tensao1 = ((5 * contador) * 0.0009765625); // Calcula tensão real ADCON0bits.CHS = 0b0001; ADCON0bits.GO = 1; while (!ADCON0bits.GODONE) { // Seleciona canal AN1 // Inicia a conversão // Aguarda fim da conversão

EXEMPLO ADC + LCD + DOIS CANAIS contador = (ADRESH * 0x100) + ADRESL; tensao2 = ((5 * contador) * 0.0009765625); // Transfere valor para variável // Calcula tensão real sprintf(linha1, "Tensao 1: %1.2f ",tensao1); // Grava texto em linha1 sprintf(linha2, "Tensao 2: %1.2f ",tensao2); // Grava texto em linha2 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD Fim de Código

EXEMPLO ADC + LCD + 4 CANAIS #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h> char linha1[16]; char linha2[16]; // Variável linha1 com 16 caracteres // Variável linha2 com 16 caracteres

EXEMPLO ADC + LCD + 4 CANAIS Inicio Configuração Atualiza LCD (chama rotina que lê tensão nos pinos A0 a A4 automaticamente)

EXEMPLO ADC + LCD + 4 CANAIS void setupadc(void) { TRISA = 0b00001111; ADCON2bits.ADCS = 0b1111; ADCON2bits.ACQT = 0b110; ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; ANSEL = 0b00001111; // Habilita pinos A0 a A3 como entrada // Clock do AD: Fosc/64 // Tempo de aquisição automático: 16 Tad // Formato: à direita // Tensões de referência: Vss e Vdd // Habilita canais AN0 a AN3 como AD ADCON0bits.ADON = 1; // Liga o circuito AD float letensao(int canal_adc) { ADCON0bits.CHS = canal_adc; // Seleciona canal ADCON0bits.GO = 1; // Inicia a conversão while (!ADCON0bits.GODONE) { // Aguarda fim da conversão int contador = (ADRESH * 0x100) + ADRESL; // Transfere valor para variável

EXEMPLO ADC + LCD + 4 CANAIS float tensao = ((5 * contador) * 0.0009765625); return tensao; // Calcula tensão real void main(void) { OSCCON = 0b01010000; // Define velocidade do oscilador para 4MHz TRISD = 0b00000000; // Habilita porta D como saída setupadc(); Lcd_Init(); // Inicia o LCD while(1) { // Inicia loop infinito sprintf(linha1, "T0: %1.1f T1: %1.1f", letensao(0), letensao(1)); // Grava texto em linha1 sprintf(linha2, "T2: %1.1f T3: %1.1f", letensao(2), letensao(3)); // Grava texto em linha2 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD Fim de Código

EXEMPLO ADC + LCD + 8 CANAIS + INT Inicio Configuração (x = 0) Atualiza LCD com as variáveis tensão[0] a tensão[7]; Inicia leitura do pino ANx Leitura finalizada? Atualiza variável tensão[x] com o valor da tensão no pino Ax; Incrementa x não sim x é não maior que 7? sim x = 0

EXEMPLO ADC + LCD + 8 CANAIS + INT #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h> char linha1[16]; char linha2[16]; // Variável linha1 com 16 caracteres // Variável linha2 com 16 caracteres

EXEMPLO ADC + LCD + 8 CANAIS + INT int canal = 0; float tensao[8]; bit atualizado; // Variável que diz qual canal é lido atualmente // Vetor que guarda a tensão em cada um dos canais // Flag que indica se todos canais já foram lidos void setupadc(void) { TRISA = 0b00101111; TRISE = 0b00000111; ADCON2bits.ADCS = 0b1111; ADCON2bits.ACQT = 0b110; ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; ANSEL = 0b11111111; ADCON0bits.ADON = 1; // Habilita pinos A0 a A3 e A5 como entrada // Habilita pinos E0 a E2 como entrada // São os pinos relativos a AN0 a AN7 // Clock do AD: Fosc/64 // Tempo de aquisição automático: 16 Tad // Formato: à direita // Tensões de referência: Vss e Vdd // Habilita canais AN0 a AN7 como AD // Liga o circuito AD

EXEMPLO ADC + LCD + 8 CANAIS + INT void setupinterrupcao(void) { GIE = 1; // Habilita interrupção global PEIE = 1; // ADC exige interrupção de periféricos habilitada ADIE = 1; // Liga interrupção pelo AD void interrupt adc_interrupt(void) { if (ADIF) { int contador = (ADRESH * 0x100) + ADRESL; // Transfere valor para variável tensao[canal] = ((5 * contador) * 0.0009765625); // Calcula tensão real if (canal == 7) { // Verificação para alternar canal = 0; // o canal lido a cada interrupcao ADCON0bits.CHS = canal; // Seleciona canal atualizado = 1; // Marca a flag caso ja leu os 4 canais else { canal++; // Atualiza o canal ADCON0bits.CHS = canal; // Seleciona canal ADCON0bits.GO = 1; ADIF = 0; // Inicia a conversão // Desmarca flag da interrupção ADC

EXEMPLO ADC + LCD + 8 CANAIS + INT void main(void) { OSCCON = 0b01010000; TRISD = 0b00000000; Lcd_Init(); setupadc(); setupinterrupcao(); atualizado = 0; ADCON0bits.CHS = canal; ADCON0bits.GO = 1; // Define velocidade do oscilador para 4MHz // Habilita porta D como saída // Inicia o LCD // Configura o ADC // Configura a interrupção // Marca a flag para atualizar os 8 canais // Seleciona canal // Inicia a conversão while(1) { // Inicia loop infinito sprintf(linha1, "1:%1.0f 2:%1.0f 3:%1.0f 4:%1.0f", tensao[0], tensao[1], tensao[2], tensao[3]); // Grava texto em linha1 sprintf(linha2, "5:%1.0f 6:%1.0f 7:%1.0f 8:%1.0f", tensao[4], tensao[5], tensao[6], tensao[7]); // Grava texto em linha2

EXEMPLO ADC + LCD + 8 CANAIS + INT Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD atualizado = 0; // Marca a flag para atualizar os 4 canais ADCON0bits.GO = 1; // Inicia a conversão Fim de Código

EXEMPLO ADC + LCD + TIMER Inicio Configuração (configura timer para interromper a cada 10 ms) Atualiza LCD com o valor da variável tensão e contador não Interrupção do conversor AD? sim Grava tensão do pino AN0 na variável tensão ; Incrementa contador ; Interrupção do timer? sim Inicia leitura no conversor AD

EXEMPLO ADC + LCD + TIMER #define _XTAL_FREQ 4000000 #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include <xc.h> #include "lcd.h" #include <stdio.h> char linha1[16]; // Variável linha1 com 16 caracteres char linha2[16]; // Variável linha2 com 16 caracteres int contador = 0; // Variável contador com valor inicial 0

EXEMPLO ADC + LCD + TIMER float tensao = 0.0; // Variável que guarda a tensão lida no conversor AD long contagem = 10000; // Variável que define quantos us serão contados a cada conversão void interrupt interrupcao() { if (ADIF) { int leitura_adc = (ADRESH * 0x100) + ADRESL; tensao = ((5 * leitura_adc) * 0.0009765625); contador++; ADIF = 0; if (TMR3IF) { // Transfere valor para variável // Calcula tensão real // Incrementa contador // Desmarca flag da interrupção ADC TMR3H = (0xFFFF - contagem) >> 8; // Cálculo do valor inicial do TMR3 TMR3L = ((0xFFFF - contagem) & 0xFF); // Cálculo do valor inicial do TMR3 LATDbits.LD0 =!LATDbits.LD0; // Inverte sinal no pino D0 TMR3IF = 0; // Limpa a Flag da interrupção ADCON0bits.GO = 1; // Inicia conversao AD

EXEMPLO ADC + LCD + TIMER void setuptmr3() { T3CKPS0 = 0; T3CKPS1 = 0; TMR3CS = 0; // Prescaler // Prescaler // Clock origina do clock interno TMR3H = (0xFFFF - contagem) >> 8; TMR3L = ((0xFFFF - contagem) & 0xFF); // Cálculo do valor inicial do TMR3 // Cálculo do valor inicial do TMR3 TMR3ON = 1; // Liga o timer void setupadc(void) { TRISA = 0b00000001; ADCON2bits.ADCS = 0b1111; ADCON2bits.ACQT = 0b110; ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; // Habilita pino A0entrada // Clock do AD: Fosc/64 // Tempo de aquisição automático: 16 Tad // Formato: à direita // Tensões de referência: Vss e Vdd

EXEMPLO ADC + LCD + TIMER ANSEL = 0b00000001; ADCON0bits.ADON = 1; // Habilita canal AN0 // Liga o circuito AD void setupint(void) { GIE = 1; // Habilita interrupção global PEIE = 1; // Habilita interrupção de periféricos TMR3IE = 1; // Interrupção do timer 3 ADIE = 1; // Habilita interrupção do ADC void main(void) { OSCCON = 0b01010000; TRISA = 1; TRISD = 0; setupadc(); setupint(); // Oscilador interno a 4 MHz // A0 como entrada // Define porta D inteira como saída // Configuração do ADC // Configuração da Interrupção

EXEMPLO ADC + LCD + TIMER setuptmr3(); // Configuração do Timer 3 Lcd_Init(); // Inicia o LCD while(1) { sprintf(linha1, "N: %i", contador); // Grava texto em linha1 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD sprintf(linha2, "Tensao: %3.2f", tensao); // Grava texto em linha2 Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD Fim de Código

EXEMPLO PWM Inicio Configuração (configura temporizador e PWM)... É, não faz nada.

EXEMPLO PWM #define _XTAL_FREQ 4000000 #pragma config FOSC = INTIO #pragma config WDT = OFF #pragma config MCLRE = OFF #pragma config CCP2MX = PORTC // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Saída do PWM na porta C #include <xc.h> void setuptmr2() { TMR2 = 0x00; // Começa a contar de 0 PR2 = 249; // até 250 (conta 250 vezes + recarga automatica) void setuppwm (void) { TRISCbits.RC1 = 1; // "desliga" bit de saída setuptmr2(); // Configura timer 2 CCP2CONbits.CCP2M = 0b1100; // Modo PWM ativo CCPR2L = 128; // Configura % do PWM (0-255), portanto 128 = 50%

EXEMPLO PWM TMR2IF = 0; TMR2ON = 1; TRISCbits.RC1 = 0; // Limpa flag do TMR2 // Dispara o timer // "liga" bit de saída void main(void) { OSCCON = 0b01010000; setuppwm(); // Oscilador interno a 4 MHz while(1) { // Gera um sinal PWM na saída do pino RC1 Fim de Código

EXEMPLO PWM + ADC Inicio Configuração Inicia conversão AD no pino AN0 não Interrupção do conversor AD? sim Atualiza valor do duty cycle do PWM baseado no valor de tensão lido no pino AN0

EXEMPLO PWM + ADC #define _XTAL_FREQ 4000000 #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF #pragma config CCP2MX = PORTC // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Saída do PWM na porta C #include <xc.h> long contagem = 0; // Variável auxiliar void interrupt interrupcao() { if (ADIF) { contagem = (ADRESH * 0x100) + ADRESL; // Transfere a leitura do AD para a contagem = contagem >> 2; // variavel 'contagem' CCPR2L = contagem; // % é igual aos 8 MSB do ADC ADIF = 0; // Desmarca flag da interrupção ADC if (TMR2IF) { // Caso a flag do temporizador esteja ativa, TMR2IF = 0; // desmarca a mesma

EXEMPLO PWM + ADC void setuptmr2() { TMR2 = 0x00; // Começa a contar de 0 PR2 = 249; // até 250 (conta 250 vezes + recarga automatica) void setupadc(void) { TRISA = 0b00000001; ADCON2bits.ADCS = 0b1111; ADCON2bits.ACQT = 0b110; ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; ANSEL = 0b00000001; // Habilita pino A0entrada // Clock do AD: Fosc/64 // Tempo de aquisição automático: 16 Tad // Formato: à direita // Tensões de referência: Vss e Vdd // Habilita canal AN0

EXEMPLO PWM + ADC ADCON0bits.ADON = 1; // Liga o circuito AD void setupint(void) { GIE = 1; // Habilita interrupção global PEIE = 1; // Habilita interrupção de periféricos TMR2IE = 1; // Interrupção do timer 1 ADIE = 1; // Habilita interrupção do ADC void setuppwm (void) { TRISCbits.RC1 = 1; // "desliga" bit de saída setuptmr2(); // Configura timer 2 CCP2CONbits.CCP2M = 0b1100; // Modo PWM ativo CCPR2L = 128; // Configura % do PWM (0-255) TMR2IF = 0; // Limpa flag do TMR2 TMR2ON = 1; // Dispara o timer

EXEMPLO PWM + ADC TRISCbits.RC1 = 0; // "liga" bit de saída void main(void) { OSCCON = 0b01010000; TRISD = 0; LATD = 1; setupadc(); setupint(); setuppwm(); // Oscilador interno a 4 MHz // Define porta D inteira como saída // Acende o primeiro LED da porta D // Configuração do ADC // Configuração da Interrupção // Configuração do PWM while(1) { ADCON0bits.GO = 1; // Lê ADC, para recarregar valor no PWM while (ADCON0bits.NOT_DONE) { // Gera um sinal PWM na saída com ciclo variando de acordo com a tensão no pino A0 Fim de Código

EXEMPLO - SERIAL Inicio Configuração; Envia texto pra porta serial; Aguarda interrupção não Interrupção da recepção serial? sim Envia texto para a porta serial com caractere digitado;

EXEMPLO - SERIAL #include <stdio.h> #include <string.h> #include <stdlib.h> #define _XTAL_FREQ 4000000 //para usar funçoes de string deve se adicionar este header // Oscilador interno de 4 MHz #include <xc.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado char caracter; bit flag_interrupcao = 0; void interrupt RS232(void) { caracter = RCREG; flag_interrupcao = 1; RCIF = 0; //vetor de interrupção // Lê caractere recebido do registrador // Habilita variável indicando que houve recepção // Limpa flag de interrupção de recepção

SERIAL void inicializa_rs232(long velocidade,int modo) { RCSTA = 0X90; // Habilita porta serial, recepção de // 8 bits em modo continuo, assíncrono. int valor; if (modo == 1) { // modo = 1, modo alta velocidade TXSTA = 0X24; // modo assíncrono, transmissão 8 bits. valor =(int)(((_xtal_freq/velocidade)-16)/16); // Cálculo do baud rate else { //modo = 0,modo baixa velocidade TXSTA = 0X20; //modo assincrono,trasmissao 8 bits. valor =(int)(((_xtal_freq/velocidade)-64)/64); //calculo do valor do gerador de baud rate SPBRG = valor; RCIE = 1; //habilita interrupção de recepção TXIE = 0; //deixa interrupção de transmissão desligado //(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo)

SERIAL void escreve(char valor) { TXIF = 0; TXREG = valor; while(txif ==0); void imprime(const char frase[]) { char indice = 0; char tamanho = strlen(frase); while(indice < tamanho ) { escreve(frase[indice]); indice++; // limpa flag que sinaliza envio completo. // Envia caractere à porta serial // espera caractere ser enviado // índice da cadeia de caracteres // tamanho total da cadeia a ser impressa // verifica se todos foram impressos // Chama rotina que escreve o caractere // incrementa índice

SERIAL void main(void) { OSCCON = 0b01010000; // Oscilador interno a 4 MHz TRISB = 0X02; // configura portb B1 (pino RX) como entrada PORTB = 0; // limpar as portas que estão configuradas como saidas inicializa_rs232(9600,1); // modo de alta velocidade GIE = 1; // GIE: Global Interrupt Enable bit PEIE = 1; // habilita interrupção de periféricos do pic imprime("usando a serial MPLAB X XC8 \n\r"); imprime( Digite algo: \n\r"); while (1) { if(flag_interrupcao == 1) { //tem dados para ler imprime(" \n\rcaractere digitado :"); escreve(caracter); flag_interrupcao = 0; //loop infinito Fim de Código

EXEMPLO SERIAL + LCD Inicio Configuração; Envia texto pra porta serial e LCD; Aguarda interrupção Organiza posição do caractere na segunda linha do LCD não Interrupção da recepção serial? sim Envia texto para a porta serial e LCD com caractere digitado;

EXEMPLO SERIAL + LCD #define _XTAL_FREQ 4000000 // Oscilador interno de 4 MHz #include <xc.h> #define RS LATD2 // < Pinos do LCD #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD > #include "lcd.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF //para usar funçoes de string deve se adicionar este header // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado

EXEMPLO SERIAL + LCD char caracter; char linha1[16]; char linha2[16]; bit flag_interrupcao = 0; void interrupt RS232(void) { caracter = RCREG; flag_interrupcao = 1; RCIF = 0; // Variável linha1 com 16 caracteres // Variável linha2 com 16 caracteres //vetor de interrupção // Lê caractere recebido do registrador // Habilita variável indicando que houve recepção // Limpa flag de interrupção de recepção void inicializa_rs232(long velocidade,int modo) { RCSTA = 0X90; int valor; if (modo == 1) { // Habilita porta serial, recepção de // 8 bits em modo continuo, assíncrono. // modo = 1, modo alta velocidade

EXEMPLO SERIAL + LCD TXSTA = 0X24; // modo assíncrono, transmissão 8 bits. valor =(int)(((_xtal_freq/velocidade)-16)/16); // Cálculo do baud rate else { //modo = 0,modo baixa velocidade TXSTA = 0X20; //modo assincrono,trasmissao 8 bits. valor =(int)(((_xtal_freq/velocidade)-64)/64); //calculo do valor do gerador de baud rate SPBRG = valor; RCIE = 1; //habilita interrupção de recepção TXIE = 0; //deixa interrupção de transmissão desligado //(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo) void escreve(char valor) { TXIF = 0; TXREG = valor; while(txif ==0); // limpa flag que sinaliza envio completo. // Envia caractere à porta serial // espera caractere ser enviado

EXEMPLO SERIAL + LCD void imprime(const char frase[]) { char indice = 0; char tamanho = strlen(frase); while(indice < tamanho ) { escreve(frase[indice]); indice++; // índice da cadeia de caracteres // tamanho total da cadeia a ser impressa // verifica se todos foram impressos // Chama rotina que escreve o caractere // incrementa índice void main(void) { OSCCON = 0b01010000; // Oscilador interno a 4 MHz TRISB = 0X02; // configura portb B1 (pino RX) como entrada PORTB = 0; // limpar as portas que estão configuradas como saidas inicializa_rs232(9600,1); // modo de alta velocidade GIE = 1; // GIE: Global Interrupt Enable bit PEIE = 1; // habilita interrupção de perifericos do pic

EXEMPLO SERIAL + LCD TRISD = 0x00; Lcd_Init(); int posicao = 1; // configura portd como saída // Inicia o LCD // Variável que guarda posição do caractere no LCD imprime("usando a serial MPLAB X XC8 \n\r"); imprime("digite algo: \n\r"); // Envia texto para a serial Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 sprintf(linha1, "Digite algo:"); // Grava texto em linha1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD while (1) { if(flag_interrupcao == 1) { imprime(" \n\rcaractere digitado: "); escreve(caracter); // Tem dados para ler Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 sprintf(linha1, "Ultima tecla: %c", caracter); // Grava texto em linha1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD

EXEMPLO SERIAL + LCD Lcd_Set_Cursor(2,posicao); // Posiciona o cursor na linha 2, ultima posicao sprintf(linha1, "%c", caracter); // Grava texto em linha2 Lcd_Write_String(linha1); // Escreve texto de linha2 no LCD if (posicao == 16) { posicao = 1; else { posicao++; flag_interrupcao = 0; //loop infinito Fim de Código

EXEMPLO SERIAL + ADC Inicio Configuração; Envia texto pra porta serial; Inicia leitura da tensão no pino AN0 não Finalizou a leitura? sim Envia texto para a porta serial com tensão lida;

EXEMPLO SERIAL + ADC #define _XTAL_FREQ 4000000 #include <xc.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF // Oscilador interno de 4 MHz //para usar funçoes de string deve se adicionar este header // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado char caracter; bit flag_interrupcao = 0; char linha[22]; int contador; float tensao; void inicializa_rs232(long velocidade,int modo) { RCSTA = 0X90; // Habilita porta serial, recepção de

EXEMPLO SERIAL + ADC // 8 bits em modo continuo, assíncrono. int valor; if (modo == 1) { // modo = 1, modo alta velocidade TXSTA = 0X24; // modo assíncrono, transmissão 8 bits. valor =(int)(((_xtal_freq/velocidade)-16)/16); // Cálculo do baud rate else { //modo = 0,modo baixa velocidade TXSTA = 0X20; //modo assincrono,trasmissao 8 bits. valor =(int)(((_xtal_freq/velocidade)-64)/64); //calculo do valor do gerador de baud rate SPBRG = valor; RCIE = 1; //habilita interrupção de recepção TXIE = 0; //deixa interrupção de transmissão desligado //(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo) void escreve(char valor) { TXIF = 0; // limpa flag que sinaliza envio completo.

EXEMPLO SERIAL + ADC TXREG = valor; while(txif ==0); // Envia caractere à porta serial // espera caractere ser enviado void imprime(const char frase[]) { char indice = 0; char tamanho = strlen(frase); while(indice < tamanho ) { escreve(frase[indice]); indice++; // índice da cadeia de caracteres // tamanho total da cadeia a ser impressa // verifica se todos foram impressos // Chama rotina que escreve o caractere // incrementa índice void setupadc(void) { TRISA = 0b00000001; ADCON2bits.ADCS = 0b111; ADCON2bits.ACQT = 0b110; // Habilita pino A0 como entrada // Tempo de aquisição: 4 Tad // Clock do AD: Fosc/64

EXEMPLO SERIAL + ADC ADCON2bits.ADFM = 0b1; ADCON1bits.VCFG = 0b00; ANSEL = 0x00000001; ADCON0bits.ADON = 1; // Formato: à direita // Tensões de referência: Vss e Vdd // Seleciona o canal AN0 // Liga o AD void SuperDelay(long counter) { // Função com valor de entrada counter counter = counter / 10; // Divide o valor informado por 10 for (long i = 1; i <= counter; i++) { // E usa o resultado como base delay_ms(10); // Para repetir uma contagem de 10 ms void main(void) { OSCCON = 0b01010000; // Oscilador interno a 4 MHz

EXEMPLO SERIAL + ADC TRISB = 0X02; // configura portb B1 (pino RX) como entrada PORTB = 0; // limpar as portas que estão configuradas como saidas inicializa_rs232(9600,1); // modo de alta velocidade setupadc(); // Configuração do AD sprintf(linha, "Tensão lida: 0.000"); imprime(linha); // Grava texto em linha1 while (1) { ADCON0bits.GO = 1; // Inicia leitura do ADC while(adcon0bits.not_done) { // Aguarda leitura do ADC contador = (ADRESH * 0x100) + ADRESL; // Transfere valor para variável tensao = ((5 * contador) * 0.0009765625); // Calcula tensão real sprintf(linha, "\b\b\b\b\b%1.3f", tensao); // Grava texto em linha1 imprime(linha); SuperDelay(1000); //loop infinito Fim de Código

PROGRAMAS COM BUGS #1 ROTAÇÃO DE LEDS Comportamento esperado: Os LEDs rotacionem no estilo bate-e-volta. Sintoma: Ao iniciar o programa, os LEDs começam a rotacionar corretamente, mas depois de várias rotações, ele volta a rotacionar do primeiro LED.

PROGRAMAS COM BUGS #1 ROTAÇÃO DE LEDS #define _XTAL_FREQ 1000000 #include <xc.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = ON #pragma config MCLRE = OFF // Oscilador de 1 MHz // Oscilador interno // Watchdog Timer ligado // Master Clear desabilitado void main(void) { TRISA = 0b00000000; // Habilita porta A como saída LATA = 1; // Liga o primeiro pino da porta A while(1) { // Inicia loop infinito while(lata!= 0b00000001) { LATA = (LATA >> 1 LATA << 7); // Rotacionando com estilo pra esquerda delay_ms(100); // Atraso de 100 ms while(lata!= 0b10000000) { LATA = (LATA << 1 LATA >> 7); // Rotacionando com estilo pra direita delay_ms(100); // Atraso de 100 ms Fim de Código

PROGRAMAS COM BUGS #2 ROTAÇÃO DE LEDS Comportamento esperado: Os LEDs rotacionem no estilo bate-e-volta. Sintoma: Ao iniciar o programa, nada acontece.

PROGRAMAS COM BUGS #2 ROTAÇÃO DE LEDS #define _XTAL_FREQ 1000000 #include <xc.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = ON #pragma config MCLRE = OFF // Oscilador de 1 MHz // Oscilador interno // Watchdog Timer ligado // Master Clear desabilitado void main(void) { TRISA = 0b00000000; // Habilita porta A como saída LATA = 1; // Liga o primeiro pino da porta A while(1) { // Inicia loop infinito while(lata!= 0b00000001) { LATA = (LATA >> 1 LATA << 7); // Rotacionando com estilo pra esquerda delay_ms(100); // Atraso de 100 ms while(lata!= 0b10000000) { LATA = (LATA << 1 LATA >> 7); // Rotacionando com estilo pra direita delay_ms(100); // Atraso de 100 ms Fim de Código

PROGRAMAS COM BUGS #3 ROTAÇÃO DE LEDS Comportamento esperado: Os LEDs rotacionem no estilo bate-e-volta. Sintoma: Ao iniciar o programa, nada acontece. A tensão nos pinos de saída dos LEDs não mostram nenhum valor bem definido.

PROGRAMAS COM BUGS #3 ROTAÇÃO DE LEDS #define _XTAL_FREQ 1000000 #include <xc.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF // Oscilador de 1 MHz // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado void main(void) { LATA = 1; // Liga o primeiro pino da porta A while(1) { // Inicia loop infinito while(lata!= 0b00000001) { LATA = (LATA >> 1 LATA << 7); // Rotacionando com estilo pra esquerda delay_ms(100); // Atraso de 100 ms while(lata!= 0b10000000) { LATA = (LATA << 1 LATA >> 7); // Rotacionando com estilo pra direita delay_ms(100); // Atraso de 100 ms Fim de Código

PROGRAMAS COM BUGS #4 PISCAR LED Comportamento esperado: Piscar um LED na porta D0 a cada 100 ms. Sintoma: O LED pisca, mas o osciloscópio mostra que ele pisca a cada 25 ms.

PROGRAMAS COM BUGS #4 PISCAR LED #define _XTAL_FREQ 1000000 // Oscilador de 1 MHz #include <xc.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF void main(void) { OSCCON = 0b01010000; TRISD = 0b00000000; // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Define frequência do oscilador para 4MHz // Habilita porta D como saída while(1) { LATDbits.LATD0 =!LATDbits.LATD0; delay_ms(100); // Inicia loop infinito // Inverte sinal do pino D0 // Atraso de 100 ms Fim de Código

PROGRAMAS COM BUGS #5 PISCAR LED Comportamento esperado: Piscar um LED na porta D0 a cada 100 ms. Sintoma: O LED fica ligado o tempo todo.

PROGRAMAS COM BUGS #5 PISCAR LED #define _XTAL_FREQ 4000000 // Oscilador de 4 MHz #include <xc.h> #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF void main(void) { OSCCON = 0x01010000; TRISD = 0b00000000; // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado // Define frequência do oscilador para 4MHz // Habilita porta D como saída while(1) { LATDbits.LATD0 =!LATDbits.LATD0; delay_ms(100); // Inicia loop infinito // Inverte sinal do pino D0 // Atraso de 100 ms Fim de Código

PROGRAMAS COM BUGS #6 LCD Comportamento esperado: Escrever Hello, world! e um contador na tela do LCD. A cada contagem, o LED da porta D0 deve piscar. Sintoma: Ao iniciar o programa, o LCD não mostra nada escrito. Apesar disso, o LED pisca.

PROGRAMAS COM BUGS #6 LCD #define _XTAL_FREQ 1000000 #include <xc.h> #define RS LATD2 // < Pinos do LCD ligados na porta D #define EN LATD3 #define D4 LATD4 #define D5 LATD5 #define D6 LATD6 #define D7 LATD7 // Pinos do LCD ligados na porta D > #pragma config FOSC = INTIO67 #pragma config WDTEN = OFF #pragma config MCLRE = OFF // Oscilador interno // Watchdog Timer desligado // Master Clear desabilitado #include "lcd.h" #include <stdio.h>

PROGRAMAS COM BUGS #6 LCD char linha1[16]; // Variável linha1 com 16 caracteres char linha2[16]; // Variável linha2 com 16 caracteres int contador = 0; // Variável contador com valor inicial 0 void main(void) { Lcd_Init(); // Inicia o LCD, ligado na porta D TRISD = 0; // Define porta D inteira como saída sprintf(linha1, "Hello world! "); // Grava texto em linha1 Lcd_Set_Cursor(1,1); // Posiciona o cursor na linha 1, caractere 1 Lcd_Write_String(linha1); // Escreve texto de linha1 no LCD while(1) { sprintf(linha2, "Contador: %i ",contador); // Grava texto em linha2 contador ++; // Incrementa contador Lcd_Set_Cursor(2,1); // Posiciona o cursor na linha 2, caractere 1 Lcd_Write_String(linha2); // Escreve texto de linha2 no LCD LATDbits.LATD0 =!LATDbits.LATD0; // Pisca LED na porta D0 Fim de Código

PROGRAMAS COM BUGS #7 INTERRUPÇÃO Comportamento esperado: O LED deve acender ou apagar a cada pressionar do botão ligado à porta B0 (ou INT0) Sintoma: Nada acontece ao pressionar o botão.