Академический Документы
Профессиональный Документы
Культура Документы
Microcontroladores em Sistemas
Computacionais
Aprenda de forma simples a gravao wireless, via USB e
Multiplataforma de Microcontroladores PIC 18 com a
Ferramenta SanUSB
(MPLABX C18)
Sandro Juc
Renata Pereira
INTRODUO ................................................................................................................................................................ 6
ASSEMBLY X LINGUAGEM C ................................................................................................................................................... 6
VANTAGENS X DESVANTAGENS DA LINGUAGEM C PARA MICROCONTROLADORES ........... 8
ARQUITETURAS DOS MICROCONTROLADORES ................................................................................................... 8
O CONTADOR DE PROGRAMA (PC) .................................................................................................................................. 9
BARRAMENTOS ................................................................................................................................................................................. 9
A PILHA (STACK) ............................................................................................................................................................................ 10
CICLO DE MQUINA .................................................................................................................................................................... 10
MATRIZ DE CONTATOS OU PROTOBOARD ............................................................................................................. 11
RESISTORES..................................................................................................................................................................................... 12
CAPACITORES ................................................................................................................................................................................. 13
FONTES DE ALIMENTAO .................................................................................................................................................. 14
PROTOCOLO DE COMUNICAO USB ........................................................................................................................ 15
MTODOS DE COMUNICAO USB ............................................................................................................................... 15
UTILIZANDO O COMPILADOR C18 E A IDE MPLABX MULTIPLATAFORMA COM FUNES
EM PORTUGUS ....................................................................................................................................................... 17
FUNES EM PORTUGUS .................................................................................................................................................. 18
FUNES BSICAS DA APLICAO DO USURIO ............................................................................................ 18
FUNES DO CONVERSOR ANALGICO DIGITAL (A/D) ............................................................................... 23
FUNES DA COMUNICAO SERIAL RS-232...................................................................................................... 24
FERRAMENTA DE GRAVAO VIA USB ....................................................................................................... 25
2.1
GRAVAO DE MICROCONTROLADORES............................................................................................... 26
PRTICA 1 PISCA LED ............................................................................................................................................. 31
PRTICA 2 PISCA 3 LEDS ...................................................................................................................................... 33
2.2
GRAVANDO O MICROCONTROLADOR VIA USB NO WINDOWS .............................................. 40
2.3
GRAVAO WIRELESS DE MICROCONTROLADORES ................................................................... 43
2.4
SISTEMA DUAL CLOCK ............................................................................................................................................ 55
2.5
COMUNICAO SERIAL VIA BLUETOOTH OU ZIGBEE ................................................................... 56
2.6
GRAVANDO O MICROCONTROLADOR VIA USB NO LINUX ......................................................... 58
2.7
GRAVANDO O PIC VIA USB PELO TERMINAL DO LINUX OU MAC OSX ............................. 59
2.8
SISTEMA DUAL CLOCK ............................................................................................................................................ 61
2.9
EMULAO DE COMUNICAO SERIAL NO LINUX .......................................................................... 61
2.10 PROGRAMA COM INTERRUPO EXTERNA POR BOTO E DO TIMER 1....................... 63
2.11 OBTENO DE UM VOLTMETRO ATRAVS DO CONVERSOR AD COM A
VARIAO DE UM POTENCIMETRO ........................................................................................................................... 64
2.12 CIRCUITO COM84 PARA GRAVAO DO gerenciador.hex............................................................. 65
PERIFRICOS INTERNOS DO MICROCONTROLADOR ........................................................................... 67
3.1
CONVERSOR A/D .......................................................................................................................................................... 67
3.1.1 AJUSTE DE RESOLUO DO SENSOR E DO CONVERSOR AD DE 8 BITS ..................... 68
3.1.2 AJUSTE DA TENSO DE FUNDO DE ESCALA COM AMPOP ....................................................... 68
3.1.3 AJUSTE DA TENSO DE REFERNCIA COM POTENCIMETRO ............................................ 69
3.1.4 CONVERSOR AD DE 10 BITS ............................................................................................................................... 69
3.1.5 OBTENO DE UM VOLTMETRO ATRAVS DO CONVERSOR AD COM A
VARIAO DE UM POTENCIMETRO ........................................................................................................................... 70
3.1.6 LEITURA DE TEMPERATURA COM O LM35 ATRAVS DO CONVERSOR AD ................. 70
3.1.7 TERMISTOR ....................................................................................................................................................................... 72
3.2
MEMRIAS DO MICROCONTROLADOR ...................................................................................................... 74
3.2.1 MEMRIA DE PROGRAMA ..................................................................................................................................... 74
3.2.2 MEMRIA DE INSTRUES ................................................................................................................................. 74
3.2.3 MEMRIA EEPROM INTERNA ............................................................................................................................. 74
3.2.4 MEMRIA DE DADOS (RAM) ................................................................................................................................ 74
3.2.5 EXEMPLO DE APLICAO ..................................................................................................................................... 75
[2]
[3]
[4]
INTRODUO
Um microcontrolador um sistema computacional completo, no qual esto includos
internamente uma CPU (Central Processor Unit), memrias RAM (dados), flash
(programa) e E2PROM, pinos de I/O (Input/Output), alm de outros perifricos
internos, tais como, osciladores, canal USB, interface serial assncrona USART,
mdulos de temporizao e conversores A/D, entre outros, integrados em um
mesmo componente (chip).
O microcontrolador PIC (Periferal Interface Controler), da Microchip Technology Inc.
(empresa de grande porte, em Arizona, nos Estados Unidos da Amrica), possui uma boa
diversidade de recursos, capacidades de processamento, custo e flexibilidade de
aplicaes.
ASSEMBLY X LINGUAGEM C
A principal diferena entre uma linguagem montada (como assembly) e a linguagem de
programao C est na forma como o programa objeto (HEX) gerado. Em assembly, o
processo usado a montagem, portanto devemos utilizar um MONTADOR (assembler),
enquanto que em linguagem C o programa compilado. A compilao um processo mais
complexo do que a montagem. Na montagem, uma linha de instruo traduzida para
uma instruo em cdigo de mquina. J em uma linguagem de programao, no existem
linhas de instruo, e sim estruturas de linguagem e expresses. Uma estrutura pode ser
condicional, incondicional, de repetio, etc...
As expresses podem envolver operandos e operadores mais complexos. Neste caso,
geralmente, a locao dos registros de dados da RAM feita pelo prprio compilador. Por
isso, existe a preocupao, por paret do compilador, de demonstrar, aps a compilao, o
percentual de memria RAM ocupado, pois neste caso relevante, tendo em vista que
cada varivel pode ocupar at 8 bytes (tipo double).
Para edio e montagem (gerao do cdigo HEX) de um programa em assembly, os
softwares mais utilizados so o MPASMWIN (mais simples) e o MPLABX. Para edio e
compilao em linguagem C (gerao do cdigo HEX), o programa mais utilizado o PIC
C Compiler CCS.
Os microcontroladores PIC possuem apenas 35 instrues em assembly para a famlia
de 12 bits (PIC12) e 14 bits (PIC16), descritas nas tabelas abaixo, e 77 instrues para a
famlia de 16 bits (PIC18). A tabela abaixo mostra algumas instrues em assembly.
[6]
[7]
VANTAGENS
X
DESVANTAGENS
MICROCONTROLADORES
DA
LINGUAGEM
PARA
[8]
Figura 1. 2: Memrias.
As instrues de um programa so gravadas em linguagem de mquina
hexadecimal na memria de programa flash (ROM). No incio da operao do
microcontrolador, o contador de programa (PC) indica o endereo da primeira instruo da
memria de programa, esta instruo carregada, atravs do barramento de dados, no
Registro de Instruo da CPU.
Um opcode (cdigo de instruo), gerado na compilao em hexadecimal, contm
uma instruo e um operando. No processamento, a CPU compara o cdigo da instruo
alocada no registro de instruo com o Set de Instrues do modelo fabricado e executa a
[9]
[ 10 ]
que geram saltos no contador de programa, como chamadas de funes em outro local
da memria de programa e os retornos dessas funes.
MATRIZ DE CONTATOS OU PROTOBOARD
Para desenvolver os projetos e exerccos propostos nessa apostila ser necessrio a
uilizao de uma Matriz de Contatos (ou Protoboard em ingls), mostrada na figura abaixo,
que uma placa com diversos furos e conexes condutoras para montagem de circuitos
eletrnicos. A grande vantagem do Protoboard na montagem de circuitos eletrnicos a
facilidade de insero de componentes (no necessita soldagem).
Figura 1. 4: Protoboard.
[ 11 ]
RESISTORES
Os resistores geralmente so feitos de carbono. Para identificar qual a resistncia
de um resistor especfico, comparamos ele com a seguinte tabela:
[ 12 ]
CAPACITORES
Capacitor ou condensador um componente que armazena energia num campo
eltrico. consistem em dois eletrodos ou placas que armazenam cargas opostas. Estas
duas placas so condutoras e so separadas por um isolante ou por um dieltrico. Eles
so utilizados desde armazenar bits nas memrias volteis dinmicas (DRAM) dos
computadores, at corrigir o fator de potncia de indstrias fornecendo reatncia capacitiva
para compensar a reatncia indutiva provocada por bobinas e motores eltricos de grande
porte.
A funo mais comum filtrar rudos em circuitor eltricos e estabilizar as fontes,
absorvendo os picos e preenchendo os vales de tenso. Os capacitores descarregados
so um curto e carregados abrem o circuito, por isso so utilizados tambm para isolar
fontes CC.
[ 13 ]
FONTES DE ALIMENTAO
As fontes mais comuns em sistemas embarcados com microcontroladores so
baterias recarregveis ou conversores CA-CC como carregadores de celulares.
As baterias ou pilhas so dispositivos que armazenam energia qumica e a torna disponivel
na forma de energia eltrica.
A capacidade de armazenamento de energia de uma bateria medida atravs da
multiplicao da corrente de descarga pelo tempo de autonomia, sendo dado em amprehora (1 Ah= 3600 Coulombs). Deve-se observar que, ao contrrio das baterias primrias
(no recarregveis), as baterias recarregveis no podem ser descarregadas at 0V pois
isto leva ao final prematuro da vida da bateria. Na verdade elas tm um limite at onde
podem ser descarregadas, chamado de tenso de corte. Descarregar a bateria abaixo
deste limite reduz a vida til da bateria.
As baterias ditas 12V, por exemplo, devem operar de 13,8V (tenso a plena carga),
at 10,5V (tenso de corte), quando 100% de sua capacidade ter sido utilizada, e este o
tempo que deve ser medido como autonomia da bateria.
Como o comportamento das baterias no linear, isto , quando maior a corrente de
descarga menor ser a autonomia e a capacidade, no correto falar em uma bateria de
100Ah. Deve-se falar, por exemplo, em uma bateria 100Ah padro de descarga 20 horas,
[ 14 ]
com tenso de corte 10,5V. Esta bateria permitir descarga de 100 / 20 = 5A durante 20
horas, quando a bateria ir atingir 10,5V.
Outro fator importante a temperatura de operao da bateria, pois sua capacidade
e vida til dependem dela. Usualmente as informaes so fornecidas supondo T=25C ou
T=20C, que a temperatura ideal para maximizar a vida til.
1.12. RUDO (BOUNCING) E FILTRO (DEBOUNCING)
Em operaes de Liga/Desliga e mudana de nivel lgico, surge um rudo
(Bouncing) na transio que, caso uma interrupo esteja habilitada ou at mesmo um
contador de evento, pode provocar vrias interrupes ou contagens. As formas mais
comuns de filtro (Debouncing) so via software, programando um tempo (em torno de
100ms, dependendo da chave) aps as transies, de modo a eliminar o rudo antes de
efetuar uma instruo, ou via hardware, utilizando um capacitor de filtro em paralelo com a
chave.
[ 15 ]
[ 16 ]
Nos sitemas operacionais Windows@ e Linux, o modo mais fcil de comunicar com
o PIC USB o CDC, por uma razo simples, os programas para PCs so baseados na
comunicao via porta serial, o que torna o processo ainda mais simples. O mtodo CDC
no Linux e o HID no Windows@ so nativos, ou seja, no necessrio instalar nenhum
driver no sistema operacional para que o PC reconhea o dispositivo.
[ 17 ]
[ 18 ]
clock_int_4MHz()
Funo: Habilita o clock para a processador do oscilador interno de 4MHz.
Argumentos de entrada: No h.
Argumentos de sada: No h.
Observaes: O clock padro proveniente do sistema USB interno do PIC de 48MHz
gerado a partir do cristal de 20 MHz. Isto possvel atravs de um multiplicador interno de
clock do PIC. A funo _int_4MHz() habilita, para o processador do microcontrolador, o
oscilador RC interno em 4 MHz que adqua o perodo de incremento dos temporizadores
em 1us. aconselhvel que seja a primeira declarao da funo principal
main().Exemplo:
#include SanUSB1.h
void main (void) {
clock_int_4MHz();
nivel_alto()
Funo: Fora nivel lgico alto (+5V) em uma sada digital.
Argumentos de entrada: Nome da sada digital que ir para nivel lgico alto. Este nome
construdo pelo inicio pin_ seguido da letra da porta e do nmero do pino. Pode ser
colocado tambm o nome de toda a porta, como por exemplo, portb.
Argumentos de sada: No h.
Observaes: No h.
Exemplo:
nivel_alto(pin_b7); //Fora nivel lgico 1 na sada do pino B7
nivel_alto(portb); //Fora nivel lgico 1 em toda porta b
nivel_baixo()
Funo: Fora nivel lgico baixo (0V) em uma sada digital.
Argumentos de entrada: Nome da sada digital que ir para nivel lgico baixo. Este nome
construdo pelo inicio pin_ seguido da letra da porta e do nmero do pino. Pode ser
colocado tambm o nome de toda a porta, como por exemplo, portc.
Argumentos de sada: No h.
Observaes: No h.
Exemplo:
nivel_baixo(pin_b7); //Fora nivel lgico 0 na sada do pino B7
nivel_baixo(portc); //Fora nivel lgico 0 em toda porta c
sada_pino(pino,booleano)
Funo: Acende um dos leds da placa McData.
Argumentos de entrada: Pino que ir receber na sada o valor booleano, valor booleano 0
ou 1.
Argumentos de sada: No h.
[ 19 ]
Observaes: No h.
Exemplo:
ledpisca=!ledpisca;
saida_pino(pin_b0,ledpisca);
tempo_us()
Funo: Tempo em mltiplos de 1us.
Argumentos de entrada: Tempo de tempo que multiplica 1 us.
Argumentos de sada: No h.
Observaes: Esta instruo s finalizada ao final do tempo determinado, ou seja, esta
funo paralisa a leitura do programa durante a execuo. Exemplo:
tempo_us(200); //Tempo de 200 us
tempo_ms()
Funo: Tempo em mltiplos de 1 ms.
Argumentos de entrada: Tempo de tempo que multiplica 1 ms.
Argumentos de sada: No h.
Observaes: Esta instruo s finalizada ao final do tempo determinado, ou seja, esta
funo paralisa a leitura do programa durante a execuo. Exemplo:
tempo_ms(500); //Tempo de 500 ms
entrada_pin_xx
Funo: L nivel lgico de entrada digital de um pino.
Argumentos de entrada: No h.
Observaes: Este nome construdo pelo inicio entrada_pin_ seguido da letra da porta e
do nmero do pino.
Exemplo:
ledXOR = entrada_pin_b1^entrada_pin_b2;
pinos b1 e b2
habilita_interrupcao()
Funo: Habilita as interrupes mais comuns do microcontrolador na funo main().
Argumentos de entrada: Tipo de interrupo: timer0, timer1, timer2, timer3, ext0, ext1, ext2,
ad e recep_serial.
Argumentos de sada: No h.
Observaes: As interrupes externas j esto habilitadas com borda de descida. Caso
se habilite qualquer interruo deve-se inserir o desvio _asm goto interrupcao _endasm
na funo void _high_ISR (void){ } da biblioteca SanUSB.h
Exemplo:
habilita_interrupcao(timer0);
[ 20 ]
habilita_interrupcao(ext1);
if(xxx_interrompeu)
Funo: Flag que verifica, dentro da funo de tratamento de interrupes, se uma
interrupo especfica ocorreu.
Complemento: timer0, timer1, timer2, timer3, ext0, ext1, ext2, ad e serial.
Argumentos de sada: No h.
Observaes: A flag deve ser zerada dentro da funo de interrupo.
Exemplo:
#programa interrupt interrupcao
void interrupcao()
{
if (ext1_interrompeu)
{
//espera a interrupo externa 1 (em B1)
ext1_interrompeu = 0;
//limpa a flag de interrupo
PORTBbits.RB0 =! PORTBbits.RB0;} //inverte o LED em B0
if (timer0_interrompeu)
{
//espera o estouro do timer0
timer0_interrompeu = 0;
//limpa a flag de interrupo
PORTBbits.RB0 =! PORTBbits.RB0; //inverte o LED em B7
tempo_timer16bits(0,62500); } }
liga_timer16bits(timer,multiplicador)
Funo: Liga os timers e ajusta o multiplicador de tempo na funo main().
Argumentos de entrada: Timer de 16 bits (0,1ou 3) e multiplica que o valor do prescaler
para multiplicar o tempo.
Argumentos de sada: No h.
Observaes: O timer 0 pode ser multiplicado por 2, 4, 6, 8, 16, 32, 64, 128 ou 256. O
Timer 1 e o Timer 3 podem ser multiplicados por 1, 2, 4 ou 8.
Exemplo:
liga_timer16bits(0,16); //Liga timer 0 e multiplicador de tempo igual a 16
liga_timer16bits(3,8); //Liga timer 0 e multiplicador de tempo igual a 8
tempo_timer16bits(timer,conta_us)
Funo: Define o timer e o tempo que ser contado em us at estourar.
Argumentos de entrada: Timer de 16 bits (0,1ou 3) e tempo que ser contado em us (valor
mximo 65536).
Argumentos de sada: No h.
Observaes: O No h.
Exemplo:
habilita_interrupcao(timer0);
liga_timer16bits(0,16);
//liga timer0 - 16 bits com multiplicador (prescaler) 16
tempo_timer16bits(0,62500);
//Timer 0 estoura a cada 16 x 62500us = 1 seg.
habilita_wdt()
[ 21 ]
escreve_eeprom(posio,valor)
Funo: Escrita de um byte da memria EEPROM interna de 256 bytes do
microcontrolador.
Argumentos de entrada: Endereo da memria entre 0 a 255 e o valor entra 0 a 255.
Argumentos de sada: No h.
Observaes: O resultado da leitura armazenado no byte EEDATA.
Exemplo:
escreve_eeprom(85,09); //Escreve 09 na posio 85
le_eeprom()
[ 22 ]
dado=le_eeprom(85);
[ 23 ]
Observaes: No h.
Exemplo:
resultado = le_AD10bits(0);//L canal 0 da entrada analgica com resoluo de 10 bits
taxa_serial();
Funo: Configura a taxa de transmisso/recepo (baud rate) da porta RS-232
Argumentos de entrada: Taxa de transmisso/recepo em bits por segundo (bps)
Argumentos de sada: No h.
Observaes: O usurio deve obrigatoriamente configurar taxa_rs232() da comunicao
assncrona antes de utilizar as funes le_serial e escreve_serial. As taxas programveis
so 1200 bps, 2400 bps, 9600 bps, 19200 bps.
Exemplo:
void main() {
clock_int_4MHz();
habilita_interrupcao(recep_serial);
taxa_rs232(2400); // Taxa de 2400 bps
while(1); //programa normal parado aqui
le_serial();
Funo: L o primeiro caractere recebido que est no buffer de recepo RS-232.
Argumentos de entrada: No h.
Argumentos de sada: No h.
Observaes: Quando outro byte recebido, ele armazenado na prxima posio livre
do buffer de recepo, cuja capacidade de 16 bytes. Exemplo:
#pragma interrupt interrupcao
void interrupcao()
{ unsigned char c;
if (serial_interrompeu) {
serial_interrompeu=0;
c = le_serial();
if (c >= '0' && c <= '9')
{ c -= '0';
PORTB = c;} }}
[ 24 ]
escreve_serial();
Funo: Transmite um byte pela RS-232.
Argumentos de entrada: O dado a ser transmitido deve ser de 8 bits do tipo char.
Argumentos de sada: No h.
Observaes: A funo escreve_serial no aguarda o fim da transmisso do byte. Como
no existe um buffer de transmisso o usurio deve garantir a transmisso com a funo
envia_byte( ) para enviar o prximo byte.
Exemplo:
escreve_serial('SanUSB'); // escreve SanUSB
while (envia_byte());
Caso ocorra o errosanusb Error: Odd address at beginning of HEX file line error,
compile e grave o firmware bsico pisca.c e tente novamente compilar e gravar o firmware
desejado.
[ 25 ]
[ 26 ]
[ 27 ]
[ 28 ]
do microcontrolador serve para proteger contra corrente reversa caso a tenso da porta
USB esteja polarizada de forma inversa.
A figura abaixo mostra a ferramenta SanUSB montada em protoboard seguindo o
circuito anterior e a posio do apdaptador USB a ser ligado no PC via cabo. Voc pode
ligar de qualquer um dos lados do conector USB, observando a descrio.
[ 29 ]
[ 30 ]
Aps montar o circuito da Ferramenta SanUSB (ver figura abaixo), deve-se iniciar a
sequncia de prticas.
[ 31 ]
[ 32 ]
Para modificar o tempo de pisca do LED necessrio alterar o valor 500 entre
parnteses na funo tempo, como por exemplo para: tempo_ms(1000);
Com esta nova programao, o LED piscar a cada 1 segundo, considerando que o
comando est em milissegundos.
Pelas funes:
Inverte_saida(pin_b7); //alterna pino B7 entre nivel lgico baixo e alto: pisca o LED
tempo_ms(500); //aguarda 500 milissegundos = 0,5 segundos
[ 33 ]
Figura 5. 3: Prtica
[ 34 ]
clock_int_4MHz();
while (1) { //LAO INFINITO
nivel_alto(pin_b7); //SAIDA ALTA NO PINO B7 - LED ACENDE
tempo_ms(500); //ATRASO 0,5 SEG
nivel_baixo(pin_b7); //SAIDA BAIXA NO PINO B7 - LED APAGA
[ 35 ]
O professor deve solicitar aos alunos que alterem a frequncia de pisca do LED.
Como exerccio para avaliar o aprendizado, deve ser solicitado que elaborem um
programa para piscar o LED do pino b7 uma vez a cada 1 segundo, o LED do pino b6 duas
vezes a cada 0,5 segundos e o LED do pino b5 trs vezes a cada 0,1 segundos, utilizando
apenas as funes vistas at o momento.
Aps isto deve ser passado aos alunos o conceito de lao de repetio finito, como o
exemplo a seguir que usa a funo FOR.
#include "SanUSB1.h"
clock_int_4MHz();
while (1){//LAO INFINITO
nivel_alto(pin_b7); //SAIDA ALTA NO PINO B7 - LED ACENDE
tempo_ms(1000); //ATRASO 0,5 SEG
nivel_baixo(pin_b7); //SAIDA BAIXA NO PINO B7 - LED APAGA
tempo_ms(1000); //ATRASO 0,5 SEG
[ 36 ]
clock_int_4MHz();
int x=0,y=0;// declarao de variveis auxiliares de nome 'x' e y do tipo inteiro
void main(){//PROGRAMA PRINCIPAL
while (1){//LAO INFINITO
[ 37 ]
[ 38 ]
}}
[ 39 ]
[ 40 ]
Clique em Abrir e escolha o programa .hex que deseja gravar, como por exemplo, o
programa compilado exemplo1.hex da pasta ExemploseBibliotecasSanUSB e clique
em Gravar. Este programa pisca o led conectado no pino B7;
7.
[ 41 ]
[ 42 ]
Para mais detalhes basta acompanhar os vdeos Gravao sem fio de microcontroladores
http://www.youtube.com/watch?v=_Pbq2eYha_c
microcontroladores
via
Zigbee:
Gravao
sem
fio
de
http://www.youtube.com/watch?v=BlRjKbXpepg.
[ 43 ]
ou
ConfigDispFinal19200to19200.hex)
deixe-o
[ 44 ]
realizar
novamente
gravao
via
USB
do
firmware
aplicativo
[ 45 ]
fio
no
microcontrolador
PIC.
Os
Programas
esto
disponveis
em:
pode
ser
adquirido
[ 46 ]
[ 47 ]
VCC
GND
TX
RX
Como seu mdulo Bluetooth j foi configurado pelo Grupo SanUSB ou pela
RComponentes, ser necessrio apenas plug-lo placa e colocar o cabo USB para
gravao do firmware. O seguinte cdigo em C aciona um LED/rel conectado ao pino B7
via Bluetooth utilizando as Letras L para ligar, D para desligar e P para piscar. Lembre-se
que as letras so maisculas, mas voc pode alterar na programao.
Mas onde digitar? Caso esteja usando smartphone/tablet Android, deve-se instalar o
nosso aplicativo, enviado por e-mail e disponvel no Grupo SanUSB ou algum outro
disponvel na playstore em que seja possvel enviar/receber dados de forma serial. Caso
esteja utilizando Windows, ou seja, queira usar o Bluetooth do PC, tambm possvel,
para isso instale ou TERMINAL ZUCHI, ou algum outro semelhante. Para mais
informaes entre em contato com o grupo sanusb www.tinyurl.com/SanUSB .
CLCULO DE TAXA DE TRANSMISSO SERIAL NO MODO ASSNCRONO
Vamos analisar a tabela abaixo:
Nas frmulas da tabela acima, o valor de n inserido no registro SPBRG. possvel gerar
com 4 MHz na condio (bits BRG16=0 e BRGH=1) tanto 9600 bps como tambm 19200
bps, pois neste caso de 8 bits (bits BRG16=0 e BRGH=1), o valor de n obtido na frmula
pode ser colocado somente em um byte, no SPBRG.
MODO 8 BITS
Para 19200: SPBRG = n= ( 4.000.000 / 19200 / 16 ) - 1 =>SPBRG = 12;
Para 9600: SPBRG = n= ( 4.000.000 / 9600 / 16 ) - 1 =>SPBRG = 25;
Considerando agora uma frequncia de clock de 48 MHz na condio (bits BRG16=0 e
BRGH=1):
Para 19200:SPBRG = n= ( 48.000.000 / 19200 / 16 ) - 1 =>SPBRG = 155;
Para 9600: SPBRG = n= ( 48.000.000 / 9600 / 16 ) - 1 = SPBRG = 311;
[ 48 ]
MODO 16 BITS
Como em 9600bps 48MHz, o SPBRGH 311, ou seja, maior que 255, no possvel
utilizar somente um byte. Por isso necessrio habilitar o byte baixo SPBRG, setando o
bit BRG16 em BAUDCON, entrando na condio de 16 bits assncrono (bits BRG16=1 e
BRGH=1). Calculando agora os valores na frmula de 16 bits, tem-se que:
Para 19200 e 48 MHz: n=( 48.000.000 / 19200 / 4 ) - 1 = 624 = 0x270 ->
SPBRGH = 0x02;
SPBRG=0x70;
Para 9600 e 48 MHz: n=( 48.000.000 / 9600 / 4 ) - 1 = 1249 = 0x4E1->
SPBRGH = 0x04;
SPBRG=0xE1;
Para 19200 e 4 MHz: n=( 48.000.000 / 19200 / 4 ) - 1 = 624 = 0x33 ->
SPBRGH = 0x00;
SPBRG=0x33;
Para 9600 e 4 MHz: n=( 48.000.000 / 9600 / 4 ) - 1 = 1249 = 0x67->
SPBRGH = 0x00;
SPBRG=0x67;
Deste modo, possvel utilizar a seguinte funo em C18 para 19200 bps com frequncia
de 4MHz e de 48MHz no modo de 16 bits:
void taxa_serial(unsigned long taxa) { //Modo 16 bits(bits BRG16=1 e BRGH=1)
unsigned long baud_sanusb; //es klappt nut mit long
TRISCbits.TRISC7=1; // RX
TRISCbits.TRISC6=0; // TX
TXSTA = 0x24;
// TX habilitado e BRGH=1
RCSTA = 0x90;
// Porta serial e recepcao habilitada
BAUDCON = 0x08; // BRG16 = 1
baud_sanusb =REG+ ((48000000/4)/ taxa) - 1;
SPBRGH = (unsigned char)(baud_sanusb >> 8);
SPBRG = (unsigned char)baud_sanusb;
}
[ 49 ]
Para mais detalhes basta acompanhar os vdeos Gravao sem fio de microcontroladores
http://www.youtube.com/watch?v=_Pbq2eYha_ceGravao
sem
microcontroladoreshttp://www.youtube.com/watch?v=0PcCQtsO1Bwg
fio
(wireless)
via
de
Bluetooth.
[ 50 ]
[ 51 ]
realizar
novamente
gravao
via
USB
do
firmware
aplicativo
[ 52 ]
Agora basta acessar a pasta sanusbee pelo Prompt do Windows@ (Iniciar ->
Pesquisar -> Prompt de Comando), como na figura abaixo, e digitar, como mostrado no
vdeo PIC wireless Zigbee programming II, as linhas de comando, para transferir os
programas aplicativos.hex como o Exemplo1wireless.hex contido na pasta sanusbee.
Exemplo: sanusbee Exemplo1Wireless.hex p COM9
[ 53 ]
[ 54 ]
[ 55 ]
MHz via USB, depois para perifricos como um relgio RTC ou para a memria EEPROM
em 4 MHz via I2C e vice-versa.
2.5 COMUNICAO SERIAL VIA BLUETOOTH OU ZIGBEE
[ 56 ]
{
if (serial_interrompeu) {
serial_interrompeu=0;
comando = le_serial();
switch (comando){
case 'L':
pisca=0; nivel_alto(pin_b7); //No imprime (printf) dentro da interrupcao
break;
case 'D':
pisca=0; nivel_baixo(pin_b7);
break;
case 'P':
pisca=1;nivel_alto(pin_b7);
break;
} }}
void main(){
clock_int_4MHz();
habilita_interrupcao(recep_serial);
taxa_serial(19200);
while(1){
while (pisca==1){
inverte_saida(pin_b7);tempo_ms (300);
}//pisca rapido
printf("SanUSB\r\n"); //envia de forma sem fio a palavra para o PC ou Android
tempo_ms (2000); }}
[ 57 ]
Esta aplicao substitui a gravao via USB pelo terminal do Linux, pois uma
forma mais simples e direta de gravao. Com apenas dois cliques no instalador
automtico SanUSB.deb possvel instalar este aplicativo em qualquer mquina com
Linux (Ubuntu 10.04, equivalente ou posterior). Depois de instalado, a interface de
gravao localizada em Aplicativos -> acessrios.
Se voc j tem o Java instalado (JRE ou SDK) baixe o instalador automtico.deb
atualizado disponivel no link: http://www.4shared.com/file/RN4xpF_T/sanusb_Linux.html
contido
tambm
na
pasta
geral
https://dl.dropbox.com/u/101922388/121007SanUSBOrig.zip.
Se ainda no tem o Java (JRE ou SDK) ou ocorreu algum erro na instalao , baixe
o instalador SanUSB, j configurado
com o Java JRE e disponivel em:
https://dl.dropbox.com/u/101922388/sanusb.deb
A figura abaixo mostra a interface grfica desenvolvida para gravao direta de
microcontroladores via USB:
[ 58 ]
[ 59 ]
instale
o
sanusb.deb
disponivel
em
http://www.4shared.com/file/sIZwBP4r/100727SanUSB.html .
Para iniciar a gravao com linhas de comando importante seguir os seguintes passos:
1. Grave no microcontrolador, somente uma vez, com um gravador especfico para PIC
com o circuito simples de gravao COM84 descrito nesta apostila ou outro gravador
qualquer, o gerenciador de gravao pela USB Gerenciador.hex, que multiplataforma
(Linux, Mac OSX e Windows@).
2. Pelo Terminal do Linux ou Mac OSX acesse onde est o executvel sanusb, instalado
pelo arquivo sanusb.deb, e no Mac OSX acesse a pasta de arquivos
SanUSBMacPlugandPlay, onde est o executvel sanusb. Mais dealhes em:
http://www.youtube.com/watch?v=rSg_i3gHF3U.
3. Aps entrar na pasta do exectvel sanusb, acesse informaes do contedo deste
arquivo digitando:
. / sanusb-h
A figura abaixo mostra o printscreen de exemplo de um processo de acesso pasta
e tambm do processo de gravao pelo terminal:
[ 60 ]
[ 61 ]
[ 62 ]
[ 63 ]
while (1){
nivel_alto(pin_B6); // Pisca Led na funo principal
tempo_ms(500);
nivel_baixo(pin_B6);
tempo_ms(500);
}}
}}
[ 64 ]
[ 65 ]
[ 66 ]
[ 67 ]
Para este tpico utilizado como exemplo de ajuste da resoluo do conversor AD, o
sensor de temperatura LM35 que fornece uma sada de tenso linear e proporcional com
uma resoluo de 10mV a cada C.
3.1.2 AJUSTE DA TENSO DE FUNDO DE ESCALA COM AMPOP
Para conversores AD de 8 bits e VREF de 5V, a resoluo mxima de 19,6mV (R= VREF
/ (2n-1). Dessa forma, como a Resoluo do sensor 10mV/C (RS), necessrio aplicar
um ajuste de resoluo com um ganho na tenso de fundo de escala do sensor para que
cada grau possa ser percebido pelo conversor do microcontrolador. A forma mais comum
de ganho a utilizao de amplificadores operacionais no inversores. Veja mais detalhes
no material de apoio no final dessa apostila. A tenso de fundo de escala (VFS) est
[ 68 ]
DIGITAL
1023
(int32)read_adc()
->
->
[ 69 ]
}}
[ 70 ]
clock_int_4MHz();
setup_adc_ports(NA0); //Habilita entrada analgica A0
setup_adc(ADC_CLOCK_INTERNAL);
while(1){
set_adc_channel(0);
tempo_ms(10);
temperatura=430*read_adc()/1023; //Vref = 4,3V devido queda no diodo, ento (430*temp)
printf (\r\nTemperatura do LM35 = %lu C\r\n,temperatura);
nivel_alto(pin_b7); // Pisca Led em operao normal
tempo_ms(500);
nivel_baixo(pin_b7);
tempo_ms(500);
}}
[ 71 ]
[ 72 ]
[ 73 ]
[ 74 ]
3.2.5.1
[ 75 ]
[ 76 ]
///Teclado Matricial insere novas senhas pelo teclado com a senha mestre//
/////oscilador interno 4 de MHz//////////////////////////////////////////
//Se faltar energia ou existir um reset, as senhas armazenadas no so
//perdidas e possivel armazenar novas senhas aps a ltima senha gravada
// possvel apagar senhas lendo a EEPROM e zerando as posies da senha ex.:write_eeprom(
endereco, 0 );
#include SanUSB1.h
char caract,tecla0,tecla1,tecla2,tecla3;
unsigned int16 p=100,i,j;
unsigned int mult=8,k=0,n=0;
int1 led,flag=0,flag2=0,flag3=0;
//////////////////////////////////////////////////////////////////////////////////
#int_timer1 // Interrupo do timer 1
void trata_t1 () // Conta 62.500us x 8 = 0,5s
{--mult;
if (!mult)
{mult=8; // 8 x0,5s - 4 seg
p=100; tecla0='F';tecla1='F';tecla2='F';tecla3='F'; // volta a posio de origem a cada 4 seg
}}
//////////////////////////////////////////////////////////////////////////////////
void main() {
clock_int_4MHz();
enable_interrupts (global); // Possibilita todas interrupcoes
enable_interrupts (int_timer1); // Habilita interrupcao do timer 1
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8);// inicia o timer 1 em 8 x 62500 = 0,5s
set_timer1(3036);
//write_eeprom( 239, 0);//Pode apagar toda a memria de senhas zerando k
if(le_eeprom(239)>0 &&le_eeprom(239)<40) {k=le_eeprom(239);} // Carrega a tima posio livre
da eeprom (k) antes do reset armazenada em 239
while (1)
{
// Reconhecimento de tecla por varredura
nivel_baixo(pin_b0);nivel_alto(pin_b1);nivel_alto(pin_b2);
if(input(pin_b3)==0) {*p='1'; flag=1; while(input(pin_b3)==0);tempo_ms(200);}
if(input(pin_b4)==0) {*p='4'; flag=1; while(input(pin_b4)==0);tempo_ms(200);}
if(input(pin_b5)==0) {*p='7'; flag=1; while(input(pin_b5)==0);tempo_ms(200);}
if(input(pin_b6)==0) {*p='*'; flag=1; while(input(pin_b6)==0);tempo_ms(200);}
nivel_alto(pin_b0);nivel_baixo(pin_b1);nivel_alto(pin_b2);
if(input(pin_b3)==0) {*p='2'; flag=1; while(input(pin_b3)==0);tempo_ms(200);}
if(input(pin_b4)==0) {*p='5'; flag=1; while(input(pin_b4)==0);tempo_ms(200);}
if(input(pin_b5)==0) {*p='8'; flag=1; while(input(pin_b5)==0);tempo_ms(200);}
if(input(pin_b6)==0) {*p='0'; flag=1; while(input(pin_b6)==0);tempo_ms(200);}
nivel_alto(pin_b0);nivel_alto(pin_b1);nivel_baixo(pin_b2);
if(input(pin_b3)==0) {*p='3'; flag=1; while(input(pin_b3)==0);tempo_ms(200);}
if(input(pin_b4)==0) {*p='6'; flag=1; while(input(pin_b4)==0);tempo_ms(200);}
if(input(pin_b5)==0) {*p='9'; flag=1; while(input(pin_b5)==0);tempo_ms(200);}
if(input(pin_b6)==0) {*p='!'; flag=1; while(input(pin_b6)==0);tempo_ms(200);}
[ 77 ]
[ 78 ]
//***********************************************************************
flag=0; flag2=0; //Zera as flags para que novas senhas possam ser digitadas
led = !led; // inverte o led de operao
output_bit (pin_b7,led);
tempo_ms(100);
}}
[ 79 ]
Figura 7. 2: PWM.
[ 80 ]
clock_int_4MHz();
incton=2; inctoff=18; //Perodo de 20ms - Passo mnimo de tempo = 1ms (5% (1/20) do duty cicle )
guardaton=le_eeprom(10);guardatoff=le_eeprom(11);
if (guardaton>0 && guardaton<=20) {incton=guardaton; inctoff=guardatoff;}
while (1) {
ton=incton; toff=inctoff;
if (!input(pin_b1)) {flag1=1;}
if (incton<20 && flag1==1 && input(pin_b1) ) {flag1=0;++incton;--inctoff;nivel_alto(led);//se no
chegou no mximo (incton<50),
write_eeprom(10,incton);write_eeprom(11,inctoff); //se o boto foi pressionado (flag1==1) e se o
boto j foi solto (input(pin_b1)) incremente
}// a onda quadrada e guarde os valores na eeprom
if (!input(pin_b2)) {flag2=1;}
if (inctoff<20 && flag2==1 && input(pin_b2) ) {flag2=0;++inctoff;--incton;nivel_baixo(led);
write_eeprom(10,incton);write_eeprom(11,inctoff);
}
nivel_alto(motor);
while(ton) {--ton;tempo_ms(1); } //Parte alta da onda quadrada
nivel_baixo(motor);
while(toff) {--toff;tempo_ms(1); } //Parte baixa da onda quadrada
}}
A figura abaixo mostra o circuito montado para com este exemplo. Veja o funcionamento
desse circuito no vdeo http://www.youtube.com/watch?v=6IIH02dbboE .
[ 81 ]
INTERRUPES E TEMPORIZADORES
INTERRUPES
As interrupes so causadas atravs de eventos assncronos (podem ocorrer a
qualquer momento) causando um desvio no processamento. Este desvio tem como destino
um endereo para tratamento da interrupo. Uma boa analogia para melhor entendermos
o conceito de interrupo a seguinte: voc est trabalhando digitando uma carta no
computador quando o seu telefone toca. Neste momento voc, interrompe o que est
fazendo, para atender ao telefone e verificar o que a pessoa do outro lado da linha est
precisando. Terminada a conversa, voc coloca o telefone no gancho novamente e retoma
o seu trabalho do ponto onde havia parado. Observe que no precisamos verificar a todo
instante, se existe ou no algum na linha, pois somente quando o ramal chamado, o
telefone toca avisando que existe algum querendo falar com voc.
Aps do atendimento das interrupes, o microcontrolador retorna exatamente ao
ponto onde parou no programa antes de atend-la. As interrupes mais comuns na
famlia PIC18F so:
- pela interrupo externa 0 (Pino B0) ->enable_interrupts(int_ext);
- pela interrupo externa 1 (Pino B1) ->enable_interrupts(int_ext1);
- pela interrupo externa 2 (Pino B2) ->enable_interrupts(int_ext2);
- pelo contador/temporizador 0 ->enable_interrupts(int_timer0);
- pelo contador/temporizador 1 ->enable_interrupts(int_timer1);
- pelo contador/temporizador 2 ->enable_interrupts(int_timer2);
- pelo canal de comunicao serial ->enable_interrupts(int_rda); //serial
As interrupes do PIC so vetorizadas, ou seja, tm endereos de incio da
interrupo fixos para a rotina de tratamento. No PIC18F2550 o endereo de tratamento
0x08. No programa em C basta escrever a funo de tratamento da interrupo aps #, e
o compilador far o direcionamento do cdico automaticamente para essa posio.
INTERRUPES EXTERNAS
O modelo PIC18F2550 possui trs interrupes externas, habilitadas nos pinos B0
(ext) , B1 (ext1) e B2 (ext2), que atuam (modo default) quando os pinos so aterrados.
Quandos atuados o processamento desviado para #int_ext, #int_ext1 ou #int_ext2,
respectivamente, para que a interrupo possa ser tratada por uma funo especfica, que
no caso do exemplo void bot_ext().
Dentro da funo principal deve-se habilitar o disjuntor geral das interrupes,
enable_interrupts(global); e depois a interrupo especfica, por exemplo
enable_interrupts(int_ext); como mostra o exemplo com aplicao de interrupo externa e
tambm interruo do temporizador 1.
#include SanUSB1.h
CHAR comando;
short int led;
int x;
#int_timer1
void trata_t1 ()
[ 82 ]
{
led = !led; // inverte o led - pisca a cada 0,5 seg.
output_bit (pin_b7,led);
set_timer1(3036 + get_timer1());
}
#int_ext
void bot_ext()
{
for(x=0;x<5;x++) // pisca 5 vezes aps o pino ser aterrado (boto pressionado)
{
nivel_alto (pin_B5); // Pisca Led em B5
tempo_ms(1000);
nivel_baixo(pin_B5);
tempo_ms(1000);
}
}
void main() {
clock_int_4MHz();
enable_interrupts (global); // Possibilita todas interrupcoes
enable_interrupts (int_ext); // Habilita interrupcao externa 0 no pino B0
enable_interrupts (int_timer1); // Habilita interrupcao do timer 1
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8);// configura o timer 1 em 8 x 62500 = 0,5s
set_timer1(3036);
// Conta 62.500us x 8 para estourar= 0,5s
while (1){}; //Loop infinito (parado aqui)
}
[ 83 ]
[ 84 ]
Para habilitar a nomenclatura das as interrupes esto disponveis em view > valid
interrupts.
Quando for utilizada alguma interrupo externa, necessrio inserir um resistor de pull-up
externo de 1K a 10K para elevar o nivel lgico do pino quando o mesmo for liberado
evitando outra interrupo, pois o processador entende tristate e nveis intermedirios de
tenso como nivel lgico baixo.
Segue cdigo exemplo utilizando o comando IF INPUT ao invs da interrupo
externa:
#include SanUSB1.h//BIBLIOTECA DE INSTRUES
main()//PROGRAMA PRINCIPAL
{
while (1)//LAO INFINITO
{
[ 85 ]
Aps a prtica ser efetuada com sucesso, o professor deve solicitar aos alunos que
ao pressionar o boto do pino b0, o LED do pino b7 pisque a cada 500 ms e ao pressionar
o boto do pino b1, o mesmo LED pisque a cada 100 ms.
Sugesto de cdigo:
#include <SanUSB.h>//BIBLIOTECA DE INSTRUES
main(){//PROGRAMA PRINCIPAL
clock_int_4MHz();
}}}
O professor pode trabalhar tambm com 3 LEDs (pinos b7, b6 e b5) piscando, de
acordo com o programa abaixo:
#include <SanUSB.h>//BIBLIOTECA DE INSTRUES
main(){//PROGRAMA PRINCIPAL
clock_int_4MHz();
while (1)//LAO INFINITO
[ 86 ]
{
if (input(pin_b0)==0){// SE BOTO NO PINO B0 FOR ATERRADO
while(input(pin_b1)==1){
nivel_alto(pin_b7);// LIGA LED NO PINO B7
tempo_ms(500);
nivel_baixo(pin_b7);// LIGA LED NO PINO B7
tempo_ms(500);
nivel_alto(pin_b6);// LIGA LED NO PINO B6
tempo_ms(500);
nivel_baixo(pin_b6);// LIGA LED NO PINO B6
tempo_ms(500);
[ 87 ]
tempo_ms(50);
nivel_baixo(pin_b5);// LIGA LED NO PINO B5
tempo_ms(50);
} }
}}
[ 88 ]
[ 89 ]
PORTB = setseg[dezena]; //A porta B recebe o desenho do nmero das dezenas apontado pela
varivel dezena
flag=1; break;}
case 1: {
nivel_alto(pin_a1); //selecionei a unidade
nivel_baixo(pin_a0);
PORTB = setseg[unidade]; //A porta B recebe o desenho do nmero das unidades apontado pela
varivel unidade
flag=0; break;}}
set_timer1(55536 + get_timer1());}
void main(){
clock_int_4MHz();
PORTB=0;// Define os pinos da porta B como sada
enable_interrupts (global); // Possibilita todas interrupcoes
enable_interrupts (int_timer0); // Habilita interrupcao do timer 0
enable_interrupts (int_timer1); // Habilita interrupcao do timer 1
setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_8);// configura o prescaler do timer 0 em 64,
prescaler at 256
set_timer0(3036);
// Conta 62.500us x 8 para estourar= 0,5
seg
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);
set_timer1(55536);
// Conta 10000 us (10ms) para estourar
while (1){
nivel_alto(pin_a5);
tempo_ms(300);
nivel_baixo(pin_a5);
tempo_ms(300);
}
}
//Funo principal
OPERADOR
&&
ll
COMANDO
Operao E (AND)
Operao OU (OR)
[ 90 ]
Operao NO (NOT)
Exemplos:
if (segundodec==05 &&(minutodec==00|| minutodec==30)) {flagwrite=1;}//Analisando um
relgio para setar a flagwrite
if (x>0 && x<20) (y=x;) // Estabelecendo faixa de valores para y.
5.2 INSTRUES LGICAS BOOLANAS BIT A BIT
Considere as portas lgicas abaixo:
[ 91 ]
Figura 5. 2: Uso de resistores de pull down para aplicar funo lgica 0/1.
importante salientar que atravs das operaes bsicas E, OU, NO e OUExclusivo possvel construir outras operaes como NAND, NOR e Coincidncia, que o
inverso do OU-Exclusivo. Isto realizado transformando a expresso booleana literal em
uma expresso booleana em C e apresentando o resultado em um LED de sada.
[ 92 ]
AeB
output_bit(pin_b7,saida); //O pino_b7 mostra o resultado do circuito lgico booleano alocado em
saida
ledpisca=!ledpisca; // ledpisca igual ao inverso de ledpisca
output_bit(pin_b0,ledpisca); // b0 recebe o valor de ledpisca
tempo_ms(500);
}}
Exemplo 2: Elabore um programa e a tabela verdade para emular uma o circuito lgico
booleano abaixo.
Note que para emular qualquer outro circuito booleano com trs entradas, basta
modificar apenas a funo de converso em negrito (saida = !(!A & B) & !C). A tabela
verdade desse circuito booleano mostarada abaixo:
A
0
0
0
0
1
1
ENTRADAS
B
0
0
1
1
0
0
C
0
1
0
1
0
1
[ 93 ]
SAIDA
S
1
0
0
0
1
0
1
1
1
1
0
1
1
0
Exemplo 3: Elabore um programa e a tabela verdade para emular uma o circuito lgico
booleano abaixo.
B
0
0
0
0
1
1
1
1
0
0
C
0
0
1
1
0
0
1
1
0
0
D
0
1
0
1
0
1
0
1
0
1
[ 94 ]
SAIDA
S
1
1
1
0
1
1
1
0
1
1
1
1
1
1
1
1
0
0
1
1
1
1
1
1
0
0
1
1
0
1
0
1
0
1
1
0
1
1
1
1
A tabela verdade pode ser facilmente comprovada de forma real montando o circuito
proposto.
5.3 EMULAO DE DECODIFICADOR PARA DISPLAY DE 7 SEGMENTOS
Antes de comentar sobre os decodificadores, vamos definir o que um display de
sete segmentos. O display de sete segmentos, formado por sete leds. Quando necessitase acender o nmero 0, liga-se os leds correspondentes ao digito 0, por exemplo, os
segmentos a, b, c, d, e, f. Na figura abaixo, mostrado um display de sete-segmentos e a
respectivos pinos. No lado direito, os dois tipos de displays, anodo comum e catodo
comum. No esquea que no anodo comum o led liga com Gnd e no catodo comum o led
liga com Vcc.
[ 95 ]
[ 96 ]
void interrupcao(){}
void main(){
clock_int_4MHz();
TRISB = 0b00000000;
nivel_baixo(pin_c0);
while(1){
for(i = 0; i<10; i++){
PORTB = set_seg[i];
tempo_ms(500);
} }}
Entrada
s
X
Y
0
0
Pin_b
0
a
0
Pin_b
1
b
1
Pin_b
2
c
0
[ 97 ]
Pin_b
3
d
0
Pin_b
4
e
1
Pin_b
5
f
0
Pin_b6
g
0
t
o
P
0
1
1
1
0
1
1
1
0
1
1
0
1
0
1
0
0
1
0
0
0
0
1
0
0
0
0
/Y
/Y
/Y
/Y
/X
/X
/X
/X
/Y
/Y
/Y
/X
/X
/X
[ 98 ]
Exemplo 2: Construa um decodificador emulado para escrever, letra por letra no mesmo
display de 7 segmentos, a cada segundo, a palavra USb2. Como o display anodo
comum (+5V no anodo do display), os segmentos ascendem com zero no pino do
microcontrolador.
Entrada
s
X
Y
0
0
0
1
1
0
1
1
U
S
b
2
Pin_b
0
a
1
0
1
0
Pin_b
1
b
0
1
1
0
Pin_b
2
c
0
0
0
1
Pin_b
3
d
0
0
0
0
Pin_b
4
e
0
1
0
0
Pin_b
5
f
0
0
0
1
Pin_b6
g
1
0
0
0
/Y
/Y
/Y
/Y
/X
/X
/X
/X
/Y
/Y
/Y
/X
/X
/X
[ 99 ]
{
a=!Y;
saida_pino(pin_b0,a); //Anodo comum
b=X^Y;
saida_pino(pin_b1,b);
c=X&Y;
saida_pino(pin_b2,c);
d=0;
saida_pino(pin_b3,d);
e=!X&Y;
saida_pino(pin_b4,e);
f=X&Y;
saida_pino(pin_b5,f);
g=!X&!Y;
saida_pino(pin_b6,g);
}
void main(){
clock_int_4MHz();
while (1)
{
decodificador(0,0); // Insere as entradas X=0 e Y=0 no decodiicador fixo ? Sada letra S
tempo_ms(1000);
decodificador(0,1); // Sada letra t
tempo_ms(1000);
decodificador(1,0); // Sada letra o
tempo_ms(1000);
decodificador(1,1); // Sada letra P
tempo_ms(1000);
}}
[ 100 ]
//Vetor
com
10
B0
B1
B2
B3
B4
B5
B6
B7
Segmento
a
Segmento
b
Segmento
c
Segmento
d
Segmento
e
Segmento
f
Segmento
g
Segmento
ponto
Insira um resistor de 100 R a 1000 R em cada pino comum e conecte: Comum 1 no pino
a0 e Comum 2 no pino a1 de acordo com a programao.
[ 101 ]
Figura 5. 7: Esquemtico
[ 102 ]
[ 103 ]
[ 104 ]
Se o nmero de 1s for par, o bit de paridade X7 zero e, se for mpar, X7 um. A Tabela
de Caracteres ASCII mostrada abaixo:
[ 105 ]
[ 106 ]
Este mtodo interessante para alterar a taxa de transmisso serial durante a operao
do sistema embarcado. Possibilitando que o microcontrolador se comunique ora e 9600bps
e ora em 19200bps ou 38400 bps.
Vamos analisar a tabela abaixo:
[ 107 ]
Deste modo, possvel utilizar a seguinte funo para 19200 bps com frequncia de
4MHz e de 48MHz no modo de 16 bits:
void taxa_serial(unsignedlong taxa) { //Modo 16 bits(bits BRG16=1 e BRGH=1)
unsignedlong baud_sanusb;
TRISCbits.TRISC7=1; // RX
TRISCbits.TRISC6=0; // TX
// TX habilitado e BRGH=1
TXSTA = 0x24;
// Porta serial e recepcao habilitada
RCSTA = 0x90;
BAUDCON = 0x08; // BRG16 = 1
baud_sanusb = REG+((_XTAL_FREQ/4)/ taxa) - 1;
SPBRGH = (unsignedchar)(baud_sanusb >>8);
SPBRG = (unsignedchar)baud_sanusb; }
void serial_putc(char c)
{
while (!TXSTAbits.TRMT);
TXREG=c;
}
#pragma interrupt interrupcao
void interrupcao()
{
[ 108 ]
if (serial_interrompeu) {serial_interrompeu=0;
comando[n] = le_serial();}}
[ 109 ]
[ 110 ]
Sendo:
F = fora (em Newtons), r = raio de giro (em metros) e T = torque (em N.m).
[ 111 ]
uma coroa de 60 dentes, em cada volta dada no parafuso a coroa vai girar apenas um
dente. Como a coroa tem 60 dentes, ser necessrio dar 60 voltas no parafuso para que a
coroa gire uma volta. Assim, a rpm da coroa 60 vezes menor que a do parafuso. Se, por
exemplo, o parafuso com rosca sem-fim est girando a 1.800 rpm, a coroa girar a 1.800
rpm, divididas por 60, que resultar em 30 rpm.
Suponhamos, agora, que o parafuso com rosca sem-fim tenha duas entradas e a
coroa tenha 60 dentes. Assim, a cada volta dada no parafuso com rosca sem-fim, a coroa
girar dois dentes. Portanto, ser necessrio dar 30 voltas no parafuso para que a coroa
gire uma volta.
Assim, a rpm da coroa 30 vezes menor que a rpm do parafuso com rosca sem-fim. Se,
por exemplo, o parafuso com rosca sem-fim est girando a 1.800 rpm, a coroa girar a
1.800 divididas por 30, que resultar em 60 rpm. A rpm da coroa pode ser expressa pela
equao:
i = Nc . Zc =Np. Zp
Nc=Np. Zp /Zc
onde:
Nc = nmero de rotaes da coroa (rpm)
Zc = nmero de dentes da coroa
Np = nmero de rotaes do parafuso com rosca sem-fim (rpm)
Zp= nmero de entradas do parafuso
As possibilidades mais comuns de controle digital de motores CC so:
CHAVEAMENTO DE MOTORES CC COM TRANSISTORES MOSFET
Os transistores de efeito de campo MOSFET executam o chaveamento por tenso
na base e podem ser utilizados no lugar dos transistores Darlington para acionamento de
dispositivos de mdia potncia, devido principalmente menor queda de tenso e menor
dissipao em forma de calor.
Os MOSFETs apresentam alta taxa de velocidade no chaveamento e uma
resistncia interna muito baixa (dcimos de ohms). Deesa forma, a queda de tenso nesse
transistor muito baixa, o que no acontece com transistores Darlington. A fgura abaixo
mostra a configurao dos pinos de um MOSFET, onde o pino 1 o Gate (base), o pinos 2
o Drain e o pino 3 o Source.
[ 112 ]
Neste caso interessante definir que no princpio seguidor de parede o rob considera o
obstculo como referncia a qual ele vai seguir em movimento de avano normal. Nesse
exemplo ele cola do lado esquerdo, ou seja, o motor direito deve ser mais rpido que o
motor esquerdo, quando os dois estiverem acionados.
Seguindo as paredes do labirinto at final encontram-se quatro situaes:
[ 113 ]
[ 114 ]
[ 115 ]
PONTE H
O acionamento da ponte H permite o movimento do motor nos dois sentidos. A ponte
H pode ser feita com transistores MOSFETs, mais aconselhvel devido a baixa queda de
tenso, ou de potncia Darllington TIP ou BD. Mais
detalhes
em
://www.youtube.com/watch?v=6IIH02dbboE .
[ 116 ]
[ 117 ]
Se a primeira entrada alta, segunda entrada baixa , ento o motor se desloca para
frente, se a primeira entrada baixa e a segunda entrada alta , o motor se movimenta para
trs. Se ambas as entradas baixas ou altas, o motor pra.
SOLENIDES E RELS
Uma solenide consiste num mbolo de ferro colocado no interior de uma bobina
(indutncia) eltrica, enrolada em torno de um tubo. Quando se alimenta eletricamente a
bobina, cria-se um campo magntico que atrai o mbolo (ncleo mvel) para dentro da
bobina como mostrado na figura abaixo. No caso de um rel, fecha um contato para
circulao de outro nivel maior de corrente.
[ 118 ]
[ 119 ]
[ 120 ]
[ 121 ]
[ 122 ]
[ 123 ]
Motor de 5 fios
Motor de 6 fios
[ 124 ]
PASSO
COMPLETO
1
(FULL-STEP)
-Somente meia bobina energizada a cada passo a partir
do
comum;
-Menor
torque;
-Pouco
consumo
de
energia.
N do
passo
1-->
2-->
3-->
4-->
1a 2a 1b 2b Decimal
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
8
4
2
1
PASSO
COMPLETO
2
(FULL-STEP
2)
-Duas meia-bobinas so energizadas a cada passo;
-Maior
torque;
-Consome mais energia que o Passo completo 1.
N do
passo
1-->
2-->
3-->
4-->
1a 2a 1b 2b Decimal
1
0
0
1
1
1
0
0
0
1
1
0
0
0
1
1
8
4
2
1
[ 125 ]
H dois tipos de servos: os de posio, com giro de 180, e o de rotao, que possui
o giro contnuo. O Servo de Posio utilizado em antenas parablicas, em braos
robticos, na robtica mvel terrestre com o controle de pernas mecnicas e no controle de
cmeras. O Servo de Rotao prioritariamente escolhido para a locomoo por rodas.
Trata-se de dispositivos muito precisos que giram sempre o mesmo ngulo para um
dado sinal. Um servo tpico possui trs fios de ligao, normalmente preto, vermelho e
branco (ou amarelo). O condutor preto a referncia de massa da alimentao (0 volts), o
condutor vermelho a alimentao e o condutor branco (ou amarelo) o sinal de
posicionamento, como mostrado na figura abaixo que um carro para desvio de
obstculos, acionado por dois servo-motores de rotao. O sinal do servo-motor de
posio normalmente um pulso de 1 a 2 milisegundos (ms), repetido depois de um pulso
de 10 a 20ms. Com o pulso de aproximadamente 1 ms o servo move-se para um sentido e
com o impulso de 2 ms para o sentido oposto. Desse modo, com um impulso de 1,5 ms, o
servo roda para a posio central.
[ 126 ]
[ 127 ]
SINAL(PINO B0)
VCC (5V) +
[ 128 ]
PRETO
GND (0V) -
[ 129 ]
while(true){
nivel_alto(pin_b7);
for(x=0;x<40;x++){
nivel_alto(pin_b0);
tempo_ms(2);
nivel_baixo(pin_b0);
tempo_ms(10);
}
for(x=0;x<40;x++){
nivel_alto(pin_b0);
tempo_ms(1);
nivel_baixo(pin_b0);
tempo_ms(11);
}
for(x=0;x<40;x++){
nivel_alto(pin_b0);
tempo_ms(0);
nivel_baixo(pin_b0);
tempo_ms(12);
}
}
}
[ 130 ]
nivel_alto(pin_b0);
tempo_ms(1);
nivel_baixo(pin_b0);
tempo_ms(9);
} }}
[ 131 ]
[ 132 ]
Durante os testes desse circuito foi verificado que, devido a resistncia de 390 em
paralelo com 2K2 , quando o led conectado no circuito, h uma diminuio na variao
do sinal de sada analgico do receptor IR. O programa a seguir mostra a leitura em mV do
sensor tico via emulao serial.
#include <SanUSB.h> //Leitura de tenso em mV com variao de um //potencimetro
#include <usb_san_cdc.h>// Biblioteca para comunicao serial virtual
int32 tensao;
main() {
usb_cdc_init(); // Inicializa o protocolo CDC
usb_init(); // Inicializa o protocolo USB
usb_task(); // Une o perifrico com a usb do PC
setup_adc_ports(AN0); //Habilita entrada analgica - A0
setup_adc(ADC_CLOCK_INTERNAL);
while(1){
//ANALGICO
DIGITAL(10 bits)
set_adc_channel(0);
// 5000 mV
1023
delay_ms(10);
// tensao
read_adc()
tensao= (5000*(int32)read_adc())/1023;
printf (usb_cdc_putc,"\r\nA tensao e' = %lu mV\r\n",tensao); // Imprime pela serial //virtual
inverte_saida(pin_b7);
[ 133 ]
delay_ms(500); }}
TIL 78
receptor
TIL 32
emissor
[ 134 ]
[ 135 ]
[ 136 ]
[ 137 ]
[ 138 ]
[ 139 ]
Nmero de
Linhas
2
2
1
2
[ 140 ]
Quantidade
de pinos
14
14/15
14/16
14/16
16
20
20
20
24
24
40
40
4
1
2
4
2
4
2
4
14/16
14/16
14/16
14/16
14/16
14/16
16
16
[ 141 ]
Sentido de deslocamento
cursor ao entrar com caractere
Deslocamento da mensagem
ao entrar com caractere
Deslocamento da mensagem
sem entrada de caractere
End. da primeira posio
Cursor Piscante
0
Cursor
com 0
Alternncia
Para a esquerda
0
Para a direita
0
Para a esquerda
0
Para a direita
0
Para a esquerda
0
Para a direita
0
primeira linha
0
segunda linha
0
0
0
0D
0F
0
0
0
0
0
0
0
0
04
06
07
05
18
1C
80
C0
[ 142 ]
protoboard.
Figura 5. 14: Prtica 6 Display LCD, montada em protoboard.
[ 143 ]
[ 144 ]
int32
signed
long
signed
int32
float
char
[ 145 ]
[ 146 ]
printf(lcd_escreve,"SOLDA CAPACITIVA");
while (1) {
//********************************BOTES**********************************
if (!input(botaoinc)) {flag1=1;}
if (flag1==1 && input(botaoinc) ) {flag1=0;++vref; //se o boto foi pressionado (flag1==1) e se o
boto j foi solto (input(botao)) incremente vref
altovref=vref/256; baixovref=vref%256;
write_eeprom(10,altovref); write_eeprom(11,baixovref);
}// Como Vref>256, guarde o valor de
vref nas posices 10 e 11 da eeprom interna
if (!input(botaodec)) {flag2=1;}
if (flag2==1 && input(botaodec) ) {flag2=0;--vref; //se o boto foi pressionado (flag2==1) e se o
boto j foi solto (input(botao)) decremente vref
altovref=vref/256; baixovref=vref%256;
write_eeprom(10,altovref); write_eeprom(11,baixovref); }// guarde o valor na de vref nas posices
10 e 11 da eeprom interna
//************************************************************************
if (vatual>=vref) {nivel_alto(rele); nivel_alto(ledrele); } //Abre o rel, avisa com led
if (vatual<=20) {nivel_baixo(rele); nivel_baixo(ledrele);} //S desliga depois da descarga
//************************************************************************
valorAD = read_adc(); // efetua a converso A/D
vatual=((constante*5*valorAD)/1023); //Regra de trs:
5
//
Tenso real (mV) -------- ValorAD
lcd_pos_xy(1,2);
printf(lcd_escreve,"Vref=%lu Vat=%lu ",vref, vatual);
tempo_ms(300);
------- 1023
}}
LDR
LDR significa LightDependent Resistor, ou seja, Resistor Varivel Conforme Incidncia
de Luz. Esse resistor varia sua resistncia conforme a intensidade de radiao
eletromagntica do espectro visvel que incide sobre ele.
Um LDR um transdutor de entrada (sensor) que converte a (luz) em valores de
resistncia. feito de sulfeto de cdmio (CdS) ou seleneto de cdmio (CdSe). Sua
resistncia diminui quando a luz intensa, e quando a luz baixa, a resistncia no LDR
aumenta.
Um multmetro pode ser usado para encontrar a resistncia na escurido (geralmente
acima de 1M) ou na presena de luz intensa (aproximadamente 100).
O LDR muito frequentemente utilizado nas chamadas fotoclulas que controlam o
acendimento de poste de iluminao e luzes em residncias. Tambm utilizado em
sensores foto-eltricos.
[ 147 ]
12
20
36
60
94
130
180
240
338
430
530
674
827
1000
1183
1404
1651
1923
Volt
4,9
4,9
4,8
4,7
4,5
4,3
4,1
3,8
3,6
3,3
3,1
2,8
2,7
2,5
2,4
2,3
2,1
(Lux)
2000
1500
1000
500
0
2
2,3
2,5
2,8
3,1
3,6
4,3
4,7
4,9
(V)
[ 148 ]
(Lux)
2000
1500
1000
500
0
2
(V)
[ 149 ]
SUPERVISRIO
Esta interface foi desenvolvida utilizando ambiente de programao Delphi e
atravs da emulao via USB de um canal serial COM virtual. A figura 8 mostra a tela do
supervisrio para iluminncia e temperatura.
[ 150 ]
[ 151 ]
[ 152 ]
tens=5*(float)read_adc()/1023;
if (tens>2 && tens<2.8) {
lux=(3936.4-(1249*tens))/0.8; }
if (tens>=2.8 && tens<=3.8) {
if (tens>3.8) {
lux=2057.2-494*tens; }
lux=(900-180*tens)/1.2; }
[ 153 ]
[ 154 ]
INTERFACE I2C
I2C significa Inter-IC (Integrated Circuit). Este barramento serial foi desenvolvido
pela Philips como o objetivo de conectar CIs e perifricos de diferentes fabricantes em um
mesmo circuito, como microcontroladores, memrias externas e relgio em tempo real,
usando o menor nmero de pinos possvel. Este protocolo serial necessita somente de
duas linhas: uma linha serial de dados (SDA) e uma de clock (SCL). Quando o baramento
no est em uso, as duas linhas ficam em nivel lgico alto foradas pelos resistores de
pull-up.
[ 155 ]
Cada bit da linha de dados s lido quando o nivel da linha de clock est em nivel
alto.
[ 156 ]
uma transio de L para H da linha SDA(stop bit) durante o perodo H da linha SCL,
define uma condio de parada.
[ 157 ]
[ 158 ]
i2c_start();
i2c_escreve_byte(0xa0 | (dispositivo << 1)); // enderea o dispositivo
i2c_le_ack();
i2c_escreve_byte((endereco >> 8));
// envia a parte alta do endereo de 16 bits
i2c_le_ack();
i2c_escreve_byte(endereco);
// envia a parte baixa do endereo de 16 bits
i2c_le_ack();
i2c_start();
//repetido start
// envia comando para o escravo enviar o dado
i2c_escreve_byte(0xa1 | (dispositivo << 1)); enderea o dispositivo e colocando em leitura
0xa1
i2c_le_ack();
dado = i2c_le_byte()
// l o dado
i2c_nack();
i2c_stop();
return dado;
---------------------------------------------------------------------------------------------------------------
[ 159 ]
[ 160 ]
printf(usb_cdc_putc, "\n\r");
}}}
//*****************************************************************************
inverte_saida(pin_b7);
tempo_ms(1000);
}}
[ 161 ]
[ 162 ]
[ 163 ]
if (valorrtc2>='0'&&valorrtc2<='9') {numquant=numquant*10+(valorrtc2-0x30);
valor=numquant;
if (endereco==0) { if(valor>59) {valor=0;}}
if (endereco==1) { if(valor>59) {valor=0;}}
if (endereco==2) { if(valor>23) {valor=0;}}
if (endereco==4) { if(valor>31) {valor=1;}}
if (endereco==5) { if(valor>12) {valor=1;}}
if (endereco==6) { if(valor>99) {valor=0;}}
//---------Converte byte hexadecimal para byte BCD decimal -------------valorbcd=dec_para_bcd(valor);
//----------------------------------------------------------------------escreve_rtc(endereco,valorbcd); //Valor1 byte BCD (decimal).
printf("\r\nA5 %2x:%2x:%2x",le_rtc(2), le_rtc(1),le_rtc(0)); //BCD em hexadecimal representa o
decimal
printf(" %2x%2x%2x\r\n",le_rtc(4), le_rtc(5), le_rtc(6));
}
}
break;
//////////////////////FUNCAO 5: L RELGIO/////////////////////Ex: A5- L o relgio e o calendrio
case '5':
printf("\r\nA5 %2x:%2x:%2x",le_rtc(2), le_rtc(1),le_rtc(0));//BCD em hexadecimal representa o
decimal
printf(" %2x%2x%2x\r\n",le_rtc(4), le_rtc(5), le_rtc(6));
break;
}}}
//*****************************************************************************
led = !led; // inverte o led de teste
output_bit (pin_b7,led);
tempo_ms(500);
}}
[ 164 ]
Este sistema de aquisio de dados USB Dual Clock, ou seja, utiliza duas fontes
de clock, uma para o canal USB de 48MHz, proveniente do oscilador externo de 20MHz, e
outra para o processador na execuo do protocolo i2c, proveniente do oscilador RC
interno de 4 MHz. (#byte OSCCON=0XFD3 //Aponta o registro do oscilador interno para
configurao de 4MHz na funo Main -> OSCCON=0B01100110;).
[ 165 ]
#include SanUSB1.h
//#device ADC=8
#include ".\include\usb_san_cdc.h"// Biblioteca para comunicao serial
#include <i2c_dll16sanc.c>
char escravo,funcao,sensor,endrtc,
valorrtc1,valorrtc2,posmeme1,posmeme2,posmeme3,posmeml1,posmeml2,posmeml3,posquant1,p
osquant2;
unsigned int ender, endereco, val, valor,valorbcd;
unsigned int mult=2,end=0, reg, numquant;
unsigned
int16
hora,horadec,minuto,minutodec,segundo,segundodec,dia,diadec,mes,mesdec,ano,anodec;
unsigned int16 i, j,numpose, numposl,num16,endpromext,k,puloext,bufferdia;
int8 regi[2];
boolean led,ledint,flagwrite;
/*****************************************************************
* Converso BCD P/ DECIMAL
*******************************************************************/
int bcd_to_dec(int valorb)
{
int temp;
temp = (valorb & 0b00001111);
temp = (temp) + ((valorb >> 4) * 10);
return(temp);
}
/**************************************************************
* Converso DECIMAL p/ BCD
***************************************************************/
int dec_para_bcd(unsigned int valord)
{
return((0x10*(valord/10))+(valord%10));//Coloca a parte alta da diviso por 10 no nibble mais
significativo
}
//////////////////////////////////////////////////////////////////////////////////
#int_timer1
void trata_t1 ()
{--mult;
if (!mult)
{mult=2; // 2 *(48MHz/4MHz) - 4 seg
hora=le_rtc(2);
minuto=le_rtc(1);
segundo=le_rtc(0);
dia=le_rtc(4);
mes=le_rtc(5);
ano=le_rtc(6);
ledint = !ledint; // inverte o led de teste - pisca a cada 2 *12 interrupcoes = 1 seg.
output_bit (pin_b0,ledint);
reg= read_adc(); //Tenso e corrente
//escreve_eeprom(0,end,reg); no funciona a escrita i2c dentro da interrupo do timer
write_eeprom( end, reg );
[ 166 ]
++end; if(end>=127){end=0;}
segundodec=bcd_to_dec(segundo);minutodec=bcd_to_dec(minuto);horadec=bcd_to_dec(hora);
diadec=bcd_to_dec(dia);mesdec=bcd_to_dec(mes);anodec=bcd_to_dec(ano);
if (segundodec==05 &&
(minutodec==00||minutodec==10||minutodec==20||minutodec==30||minutodec==40||minutodec==5
0))
//if
((segundodec==00||segundodec==10||segundodec==20||segundodec==30||segundodec==40||segu
ndodec==50))
{flagwrite=1;}
//endpromext=(minutodec/10)+(horadec*6)+((diadec-1)*24*6*2)+24*6*k;
//endpromext=(segundodec/10)+(minutodec*6); }//No aceita DE JEITO NENHUM escrever na
eeprom ext por interrupo do timer via i2c
//printf("\n\rEndpromext = %lu e reg = %u \n\r, segundodec = %lu\n\r",endpromext,reg,segundodec);
//Aceita imprimir via USB
set_timer1(3036 + get_timer1()); }} // Conta 62.500 x 8 = 0,5s
//////////////////////////////////////////////////////////////////////////////////
void main() {
usb_cdc_init(); // Inicializa o protocolo CDC
usb_init(); // Inicializa o protocolo USB
usb_task(); // Une o perifrico com a usb do PC
OSCCON=0B01100110; //Clock interno do processador de 4MHZ
setup_adc_ports(AN0_TO_AN1); //Habilita entradas analgicas - A0 A1
setup_adc(ADC_CLOCK_INTERNAL); //Configurao do clock do conversor AD
enable_interrupts (global); // Possibilita todas interrupcoes
enable_interrupts (int_timer1); // Habilita interrupcao do timer 1
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8);// inicia o timer 1 em 8 x 62500 = 0,5s
set_timer1(3036);
setup_wdt(WDT_ON); //Habilita o temporizador co de guarda - resseta se travar o programa
principal ou ficar em algum getc();
while (1) {
//************************************************************************
if (flagwrite==1) {flagwrite=0; //Flag de gravao setada na interrupo do timer quando chega a
hora de gravar
k=0;
for(k=0;k<2;k++)
{
set_adc_channel(k);
tempo_ms(20);
regi[k]= read_adc(); //Tenso M1[0], correnteM1[1]
endpromext=(minutodec/10)+(horadec*6)+((diadec-1)*24*6*2)+24*6*k;
//endpromext=(segundodec/10)+(minutodec*6)+((diadec-1)*60*6*2)+60*6*k; //Para teste 60 em vez
de 24
escreve_eeprom(0,endpromext, regi[k]);
printf("\r\nPosicao = %lu -> Sensor[%lu] = %u\r\n",endpromext,k,regi[k]);
}
}
//************************************************************************
[ 167 ]
if (valorrtc1>='0'&&valorrtc1<='9') {numquant=(valorrtc1-0x30);}
if (valorrtc2>='0'&&valorrtc2<='9') {numquant=numquant*10+(valorrtc2-0x30);
valor=numquant;
if (endereco==0) { if(valor>59) {valor=0;}}
if (endereco==1) { if(valor>59) {valor=0;}}
if (endereco==2) { if(valor>23) {valor=0;}}
if (endereco==4) { if(valor>31) {valor=1;}}
if (endereco==5) { if(valor>12) {valor=1;}}
if (endereco==6) { if(valor>99) {valor=0;}}
//---------Converte byte hexadecimal para byte BCD decimal -------------valorbcd=dec_para_bcd(valor);
//----------------------------------------------------------------------escreve_rtc(endereco,valorbcd); //Valor1 byte BCD (decimal).
//printf("\r\nVALOR ESCRITO = %2x\r\n",valorbcd);
//printf(r\nPOSICAO = %2x\r\n",endereco);
hora=le_rtc(2);minuto=le_rtc(1);segundo=le_rtc(0);
printf(r\nA4%2x:%2x:%2x",hora, minuto,segundo);
printf(%2x%2x%2x\r\n",le_rtc(4), le_rtc(5), le_rtc(6));
}
[ 168 ]
}
break;
//////////////////////FUNCAO 5: L RELGIO////////////////////////Ex: A5- L o relgio e o calendrio
case '5':
printf(usb_cdc_putc,"\r\nA5 %2x:%2x:%2x",le_rtc(2), le_rtc(1),le_rtc(0));
printf(usb_cdc_putc," %2x%2x%2x\r\n",le_rtc(4), le_rtc(5), le_rtc(6));
break;
//////////////////////FUNCAO 6: L BUFFER EEPROM/////////////////////Ex: A6 09(DIA) 0(SENSOR)
case '6':{
posmeme1=getc();
posmeme2=getc();
sensor=getc();
if (posmeme1>='0' && posmeme1<='9') {bufferdia=(posmeme1-0x30);}
if (posmeme2>='0' && posmeme2<='9') {bufferdia=bufferdia*10+(posmeme2-0x30);}
if (sensor>='0' && sensor<='1') {k=(sensor-0x30);}
printf(usb_cdc_putc,"Buffer Sensor %lu - Dia %lu\r\n",k,bufferdia);
tempo_ms(10);
//puloext=((bufferdia-1)*60*6*2)+60*6*k;// Seleciona buffer de teste de tensao
puloext=((bufferdia-1)*24*6*2)+24*6*k;// Seleciona buffer
for(i=0; i<6; ++i)
{
//for(j=0; j<60; ++j) {printf(usb_cdc_putc,"%2u ", le_eeprom(0,puloext+(i*60+j)) );}
//"%2u\n\r" para gerar grfico no excell
for(j=0; j<24; ++j){printf(usb_cdc_putc,"%2u ", le_eeprom(0,puloext+(i*24+j)) );}
tempo_ms(15);
}
printf(usb_cdc_putc,"\r\n"); //posiciona prxima linha
}
break;
}}}
}
}
[ 169 ]
Significado
+CMGS
Envia mensagem
+CMSS
+CMGW
+CMGD
Apaga mensagem
+CMGC
Envia comando
+CMMS
[ 170 ]
Comando AT
Significado
+CNMI
+CMGL
Lista mensagens
+CMGR
L menssagens
+CNMA
[ 171 ]
[ 172 ]
MODELO DE COMUNICAO
O protocolo Modbus baseado em um modelo de comunicao mestre-escravo,
onde um nico dispositivo, o mestre, pode iniciar transaes denominadas queries. O
[ 173 ]
MODOS DE TRANSMISSO
Existem dois modos de transmisso: ASCII (American Code for Information
Interchange) e RTU (Remote Terminal Unit), que so selecionados durante a configurao
dos parmetros de comunicao.
Como a comunicao geralmente utilizada em automao industrial em modo
RTU, o projeto proposto foi desenvolvido nesta forma de comunicao.
[ 174 ]
[ 175 ]
O modo Modbus RTU com microcontrolador PIC desse projeto, mostrado no link
http://www.youtube.com/watch?v=KUd1JkwGJNk , suporta funes de leitura (3) e escrita
(16).
#include SanUSB1.h
#include <usb_san_cdc.h>// Biblioteca para comunicao serial
long int checksum = 0xffff;
unsigned int x,i,y,z;
unsigned char lowCRC;
unsigned char highCRC;
int tamanhodata;
int32 buffer[100];
void CRC16 (void) //Modo RTU
{
for (x=0; x<tamanhodata; x++)
{
checksum = checksum^(unsigned int)buffer[x];
for(i=8;i>0;i--)
{
if((checksum)&0x0001)
checksum = (checksum>>1)^0xa001;
else
checksum>>=1;
}
}
highCRC = checksum>>8;
checksum<<=8;
lowCRC = checksum>>8;
buffer[tamanhodata] = lowCRC;
buffer[tamanhodata+1] = highCRC;
checksum = 0xffff;
}
void ler (void)
{
buffer[2]=getc();
buffer[3]=getc();
buffer[4]=getc();
buffer[5]=getc();
buffer[6]=getc();
buffer[7]=getc();
tempo_ms(3);
buffer[2]=0x02;
buffer[3]=0x00;
buffer[4]=port_a; //o buffer[4] leva o valor de entrada da porta A do microcontrolador para o
//SCADA
tamanhodata = 5;
CRC16();
}
void rxler (void) //Leu a porta a no buffer[4] e escreve o CRC no buffer[5] e [6], pois tamanhodata
=5
[ 176 ]
{
printf(usb_cdc_putc,"%c%c%c%c%c%c%c",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],b
uffer[6]); // 6 bytes
}
void escrever (void)
{
buffer[2]=getc();
buffer[3]=getc();
buffer[4]=getc();
buffer[5]=getc();
buffer[6]=getc();
buffer[7]=getc();
buffer[8]=getc();
buffer[9]=getc();
buffer[10]=getc();
tempo_ms(3);
tamanhodata = 6;
CRC16();
PORTB = buffer[8]; //A porta B do microcontrolador recebe o valor enviado pelo SCADA
}
void rxescrever (void)
{
printf(usb_cdc_putc,"%c%c%c%c%c%c%c%c",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5
],buffer[6],buffer[7]); //7 bytes
}
void main()
{
clock_int_4MHz();
PORTB= 0b00000000;
while(1)
{
if (kbhit(1))
{
//verifica se acabou de chegar um novo dado no buffer USB, depois o kbhit zerado para //prximo
dado
buffer[0]=getc();
z = buffer[0];
if (z==1) //verifica se o endereco do slave e igual a 1
{
buffer[1]=getc(); //verifica a funo contida no segundo byte buffer[1]
y = buffer[1];
}
if (y==3) //verifica se a funo para leitura e encaminha para leitura de varivel do
//microcontrolador
{
ler();
rxler();
}
if (y==16) //verifica se a funo para escrita no microcontrolador, ou seja, comando de //atuao
[ 177 ]
do uC
{
escrever();
rxescrever();
}}}}
[ 178 ]
rtos_run () inicia a operao de RTOS. Todas as operaes de controle de tarefas so implementadas aps chamar essa funo.
rtos_terminate () termina a operao de RTOS. O controle retorna ao programa original sem RTOS. Na verdade, esta funo um retorno de rtos_run
().
rtos_enable () esta funo ativa a tarefa para que ela possa ser chamado pelo rtos_run ().
rtos_disable () esta funo desativa a tarefa para que ela no possa mais ser chamado pelo rtos_run (), a menos que seja reativada pela funo
rtos_enable ().
rtos_msg_send () recebe esta funo envia um byte para a tarefa especificada, onde ele colocado na tarefa mensagem.
rtos_msg_read () l o byte localizado na tarefa mensagem.
rtos_msg_ poll () retorna true se houver dados na tarefa mensagem.
[ 179 ]
// Define qual o timer utilizado para o multitasking e o maior tempo de cada tarefa (minor_cycle) do
RTOS
#use rtos(timer=0, minor_cycle=10ms)
#task(rate=250ms, max=10ms) // Declara TAREFA 1 - chamada a cada 250ms
void task_B7()
{inverte_saida(PIN_B7); }// comuta B7 inverte o estado de B7
#task(rate=500ms, max=10ms) // Declara TAREFA 2 - chamada a cada 500ms
void task_B6()
{inverte_saida(PIN_B6);} // comuta B6
#task(rate=1s, max=10ms) // Declara TAREFA 3 - chamada a cada segundo
void task_B0()
{inverte_saida(PIN_B0); } // comuta B0
void main()
{
clock_int_4MHz();//Funo necessria para habilitar o dual clock (48MHz para USB e 4MHz para
CPU)
PORTB=0; // Configura PORTB como sada
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //ciclo de mquina de 1us
rtos_run(); // inicia o RTOS (sistema operacional em tempo real)
}
Em um sistema multitarefa, inmeras tarefas exigem tempo da CPU, e uma vez que
existe apenas uma CPU, necessria alguma forma de organizao e coordenao para
cada tarefa tenha o tempo que necessita. Na prtica, cada tarefa tem um intervalo de
tempo muito curto, assim parece que as tarefas so executadas de forma paralela e
simultnea.
Quase todos os sistemas baseados em microcontroladores executam mais de uma
atividade e trabalham em tempo real. Por exemplo, um sistema de monitoramento da
temperatura composto de trs tarefas que, normalmente, que se repete aps um
pequeno intervalo de tempo, a saber:
- Tarefa 1 l a temperatura;
- Tarefa 2 Formata o valor da temperatura;
- Tarefa 3 exibe a temperatura;
MQUINAS DE ESTADO
As mquinas de estado so simples construes usadas para executar diversas
atividades, geralmente em uma seqncia. Muitos sistemas da vida real que se enquadram
nesta categoria. Por exemplo, o funcionamento de uma mquina de lavar roupa ou
mquina de lavar loua facilmente descrito com uma mquina de estado de construo.
Talvez o mtodo mais simples de implementar uma mquina de estado em C usar um
switch-case. Por exemplo, nosso sistema de monitoramento de temperatura tem trs
tarefas, nomeado Tarefa 1, Tarefa 2, Tarefa 3 e, como mostrado na Figura abaixo.
[ 180 ]
[ 181 ]
#include <18F4550.h> //This library 18F4550.h is valid for the whole family USB
PIC18Fx5xx
#device ADC=10
#fuses
USBDIV,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG
HSPLL,PLL5,
#byte OSCCON=0XFD3
#use tempo(clock=48000000)// USB standard frequency (cpu and timers 12 MIPS =
4/48MHz)
//#use tempo(clock=4000000) // internal Oscillator Clock of 4MHz
[ 182 ]
C18 compiler
/* www.tinyurl.com/SanUSB
*/
#include "p18F4550.h"
void low_isr(void);
void high_isr(void);
#pragma code low_vector=0x1018
void interrupt_at_low_vector(void){
_asm GOTO low_isr _endasm
}
#pragma code
[ 183 ]
SDCC
Example Format
/* www.tinyurl.com/SanUSB
*/
#include <pic18f4550.h>
#pragma code _reset 0x001000
void _reset( void ) __naked{
__asm
[ 184 ]
EXTERN __startup
goto __startup
__endasm;}
#pragma code _high_ISR 0x001008
void _high_ISR( void ) __naked{
__asm
retfie
__endasm;}
#pragma code _low_ISR 0x001018
void _low_ISR( void ) __naked{
__asm
retfie
__endasm;}
void main() { }
MikroC
Example Format for Bootloader
/* www.tinyurl.com/SanUSB
*/
[ 185 ]
Hi-Tech C Compiler
step1:goto Build option
step2:linker tap
step3:set offset : 1000
Microchip ASM compiler
/* www.tinyurl.com/SanUSB
*/
processor PIC18F4550
#include"p18f4550.inc"
org 0x1000
goto init
org 0x1020
goto int_isr
init
[ 186 ]
...
; initialization
loop
...
; code
goto loop
int_isr
...
; interrupt code
retfie
end
[ 187 ]
[ 188 ]
considerarmos a condio ideal, se Vi1 = Vi2, a sada ser nula, isto , um AmpD um
circuito que amplifica s a diferena entre duas tenses rejeitando os sinais de entrada
quando estes forem iguais.
[ 189 ]
[ 190 ]
Na prtica os Amp-Ops so circuitos integrados que, como qualquer sistema fsico tem
suas limitaes. Um dos Amp-Ops mais difundidos at hoje o 741, que recebe inmeras
codificaes de acordo com seu fabricante, como por exemplo: uA741, LM741 entre
outras. Os pinos 1 e 5 so destinados ao ajuste da tenso de off-set. O Amp-Op 741
mostrado na figura a seguir:
[ 191 ]
Vo=A (V1-V2)
[ 192 ]
(1)
[ 193 ]
Esse sistema em malha aberta tambm conhecido como comparador de tenso entre
Vi (tenso de entrada) e Vref (tenso de referncia), que nesse tem a Vref igual ao Gnd.
possvel
ver
uma
prtica
de
LM
741
no
link:
http://www.youtube.com/watch?v=EDol0zL96Ms
[ 194 ]
Caractersticas:
- A tenso na sada (Vo) ser nula ou a desejada quando as entradas inversora (-) e no
inversora (+) apresentem o mesmo potencial.
- Como a entrada no inversora (+) est aterrada, a entrada inversora (-) ser um
terra virtual.
- Nenhuma das entradas (em teoria) permite a passagem de corrente eltrica do exterior
para o amplificador operacional (impedncia de entrada infinita).
- Se a entrada inversora um terra virtual, temos que, simplesmente, resolver o circuito
abaixo, onde o terra virtual representado:
Para que haja o terra virtual necessrio que Iin = - Iout, ento:
Vin V
V V
V
R
= out
out = 2
R1
R2
Vin
R1
Quase todas as aplicaes de AmpOps envolvem realimentao negativa. Nesse
caso, quando a tenso de sada aumenta, uma parte da tenso de sada realimentada
para a entrada inversora, i reduzindo a sada. Muito rapidamente, o AmpOp encontra seu
ponto operacional. Note que o ganho do AmpOp depende da relao entre R2 e R1.
Exemplo de um amplificador inversor:
[ 195 ]
[ 196 ]
Na prtica pode se considerar o valor de R4 muito maior que R para limitar o valor da
tenso mxima de sada em 5V. Uma prtica interessante construir um conversor DA a
partir de sinais digitais de uma porta do microcontrolador e conferindo o valor convertido
com um multmetro.
[ 197 ]
do
conversor
AD.
Masi
detalhes
podem
ser
visots
em:
http://www.youtube.com/watch?v=Z8zXBsPa1_k .
Amplificador de Instrumentao
Muito utilizados por sensores com sinais de tenso diferenciais como termopares e
sensores de corrente. O amplificador de instrumentao representado na figura abaixo,
adota dois amplificadores no inversores (AmpOps 1 e 2) na entrada e um amplificador de
diferena (AmpOp 3) na sada. Neste caso, a resistncia de entrada vista por cada uma
das duas fontes infinita (com a mesma resistncia de entrada dos terminais positivos dos
AmpOps 1 e 2), e o ganho de tenso dado pelo produto de dois cocientes entre as
resistncias no amplificador diferencial. Nesse caso a tenso de referncia na entrada
[ 198 ]
vs2 pode ser flutuante, ou seja, possvel amplificar faixas de tenses entre as entradas
vs1 e vs2 no simtricas.
Rx . (vs1-vs2) / R
[ 199 ]
REFERNCIAS BIBLIOGRFICAS
[ 200 ]
Grupo SanUSB (2011). Arquivos do Grupo SanUSB. Retirado em 05/01/11, no World Wide
Web: www.tinyurl.com/SanUSB/.
Jornal O Povo (2011). Da escola pblica para o mundo. Retirado em 05/01/11, no World
Wide Web:
http://www.opovo.com.br/app/opovo/cienciaesaude/2011/01/08/noticiacienciaesaudejorn
al,2086691/da-escola-publica-para-o-mundo.shtml.
Juc, S. et al.(2011). A low cost concept for data acquisition systems applied to
decentralized renewable energy plants. Retirado em 05/01/11, no World Wide Web:
http://www.mdpi.com/1424-8220/11/1/743 .
Juc, S. et al.(2011). Gravao de microcontroladores PIC via USB pelo terminal do Linux.
Retirado em 05/03/11, no World Wide Web:
http://www.vivaolinux.com.br/artigo/Gravacao-de-microcontroladores-PIC-via-USB-peloterminal-do-Linux/.
Jornal O Povo (2010). De Maracana para Eslovquia. Retirado em 05/01/11, no World
Wide Web: http://publica.hom.opovo.com.br/page,489,109.html?i=2051467.
Dirio do Nordeste (2010). Rob cearense. Retirado em 05/01/11, no World Wide Web:
http://diariodonordeste.globo.com/materia.asp?codigo=861891.
TV Dirio (2010). Feira do Empreendedorismo SEBRAE. Retirado em 05/01/11, no World
Wide Web: http://www.youtube.com/watch?v=8Y7gOPd_zN4.
TV Cidade (2009). Projetos Comsolid/Setapi IFCE. Retirado em 05/01/11, no World Wide
Web: http://www.youtube.com/watch?v=i_waT0_201o.
Juc, S. et al.(2009). SanUSB: software educacional para o ensino da tecnologia de
microcontroladores. Retirado em 05/01/11, no World Wide Web:
http://www.cienciasecognicao.org/pdf/v14_3/m254.pdf .
Dirio do Nordeste (2007). Alunos estimulados a construir robs. Retirado em 05/01/11, no
World Wide Web: http://diariodonordeste.globo.com/materia.asp?codigo=491710.
[ 201 ]