Você está na página 1de 42

Curso de Microcontroladores PIC

Programação em linguagem C
Introdução

O que é um microcontrolador?

Microcontrolador X microprocessador

Aplicações

PIC16F628A e PIC16F876A
Estrutura básica dos PICs usados
Características Elétricas
Clique para editar os estilos do texto mestre
 Segundo nível
 Terceiro nível
 Quarto nível
 Quinto nível
Hardware mínimo
GND e VDD: 2,2 a 5,5V (nos exemplos: 5V)

Pino MCLR em 5 V (em 0V reseta o uC)

Pinos OSC1 e OSC2 ligados a um cristal

O PIC16F628A dispensa o uso do MCLR e do cristal,

utilizando apenas a alimentação


Hardware mínimo
Software mínimo
Inicialização
Configuração dos pinos (entradas ou saídas)

Configuração dos periféricos utilizados

Declaração das variáveis da main()

Chamadas das funções iniciais

Loop infinito
 Leitura das entradas

 Processamento dos dados

 Atualização das saídas


Software mínimo
//---- Programa Esqueleto----
//---- Programa Esqueleto----
#include <16F876A.h>
#include <16F628A.h>
#fuses INTRC_IO, NOMCLR #fuses XT
#use delay(clock=4000000) #use delay(clock=4000000)
 
#use fast_io(a)  
#use fast_io(b) #use fast_io(a)
  #use fast_io(b)
void main(void){
#use fast_io(c)
set_tris_a (0b11111111);
set_tris_b (0xff);
   
while(true){ void main(void){
  set_tris_a (0b11111111);
}
} set_tris_b (0xff);
set_tris_c (0xff);

while(true){

}
}
Funções de saída / tris
O compilador é case insensitive!
Output_float(pino)
Output_high(pino);
Ex:
Ex: output_high(PIN_A0);
Output_float(PIN_A4);
Output_low(pino);
Ex: output_low(PIN_A1); Output_drive(pino)
Output_toggle(pino); Ex:
Ex: Output_toggle(PIN_A2); Output_drive(PIN_A5);
Output_x(dado);
Ex: Output_a(0b00010001);
Funções de delay
delay_ms(tempo em milisegundos);
delay_us(tempo em microsegundos);
delay_cycles(tempo em ciclos);
1ºEx: Hello World! //---- Programa Esqueleto----
#include <16F876A.h>

#fuses XT
//---- Programa Esqueleto---- #use delay(clock=4000000)
#include <16F628A.h>
 
#fuses INTRC_IO, NOMCLR #use fast_io(a)
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(c)
 
#use fast_io(a)
#use fast_io(b) #use fast_io(d)
 
void main(void){ #use fast_io(e)
set_tris_a (0b11111110);
 
set_tris_b (0xff); void main(void){
  set_tris_a (0b11111110);
while(true){
  ouput_high(pin_a0); set_tris_b (0xff);
delay_ms(500); set_tris_c (0xff);
output_low(pin_a0);
set_tris_d (0xff);
delay_ms(500);
set_tris_e (0xff);
}
}
while(true){
1ºEx: Hello World!
1ºEx: Hello World!
Push-button e o Resistor de Pull-
down

Em uma entrada utilizada para ler um botão,


deve-se usar um resistor ligado ao terra. Sem
o resistor (chamado de pull-down), se o botão
não estiver pressionado, o nivel lógico na
entrada não será zero, pois este está em alta
impedância. Esse estado pode ser
denominado floating (flutuando), onde o sinal
não tem um valor fixo, fica variando
aleatoriamente em função de ruídos locais.
Funções entrada digital
Input(pino);
Ex: if(input(pin_a0)){
...
}
Input_x();
Ex: a = Input_a();
Input_state(pino);
Ex: estado = input_state(PIN_A2);
2ºEx: Push-button //-------- Pisca LED ---------
#include <16F877A.h>
#fuses XT
//-------- Pisca LED --------- #use delay(clock=4000000)
#include <16F628A.h>  
#fuses INTRC_IO, NOMCLR #use fast_io(a)
#use delay(clock=4000000) #use fast_io(b)
  #use fast_io(c)
#use fast_io(a) #use fast_io(d)
#use fast_io(b) #use fast_io(e)
   
void main(void){ void main(void){
set_tris_a (0b11111110); set_tris_a (0b11111110);
set_tris_b (0xff); set_tris_b (0xff);
  set_tris_c (0xff);
while(true){ set_tris_d (0xff);
  if(input(pin_c4)) set_tris_e (0xff);
ouput_high(pin_a0);
else output_low(pin_a0); while(true){
} if(input(pin_c4))
} ouput_high(pin_a0);
else output_low(pin_a0);
}
}
2ºEx: Push-button
Interrupção externa
Podemos engatilhar uma rotina específica
dentro do nosso microcontrolador a partir de
sinais externos ou mesmo eventos internos do
microcontrolador, sendo esta uma forma mais
eficiente de controlar as suas atividades já
que desta forma não há perda de tempo ao se
realizar a leitura do estado do pino a cada
ciclo de trabalho.
Funções básicas: Interrupção
Enable_interrupts(parâmetros)
 Ex: enable_interrupts(GLOBAL|INT_RB0)

Ext_int_edge(parâmetros)
ex: ext_int_edge(L_TO_H)

Definição da interrupção:
#INT_RB
Void funcao(){
código
}
3ºEx: Interrupção Externa
/----Interrupção Externa----/

#INT_RB
#include <16F877A.h> void piscaled(void)
#fuses XT {
#use delay(clock=4000000) if(input(pin_b0))
#use fast_io(a) {
#use fast_io(b)
delay_ms(20);
#use fast_io(c)
if(input(pin_b0))
#use fast_io(d)
{
#use fast_io(e)
output_toggle(pin_a0);
 
}
void main(void){
}
set_tris_a (0b11111110);

set_tris_b (0xff);
}
set_tris_c (0xff);

set_tris_d (0xff);

set_tris_e (0xff);

ext_int_edge(L_TO_H);

enable_interrupts(GLOBAL|INT_RB);

while(true){

sleep();

}
Display LCD
• #include <lcdt.c>
• Biblioteca de comunicação com o LCD,

• lcd_init()
• Inicializa o LCD

• Lcd_gotoxy(posição x, posição y)
• Vai para a posição x,y do lcd. O canto superior esquerdo é a
posição (1,1)
• lcd_getc(posição x, posição y)
• Pega o caracter da posição x,y

• Printf(lcd_putc,”Mensagem”)
• Escreve a mensagem na tela a partir da posição atual.
Display LCD
 \f - Apaga todo o conteúdo do lcd e volta à
posição (1,1)
 \b – Volta 1 caractere no lcd

 \n – pula uma linha


void main(void){

4ºEx: Display unsigned int i;


set_tris_a(0b11111110);

set_tris_c(0b01111111);
//--------- LCD lcd_init();
--------- printf(lcd_putc,"\fIS WEEEE!! ");
#include <16F877A.h>
printf(lcd_putc,"\n PICapturando");
#fuses XT lig(bl);
#use des(led);
delay(clock=4000000) for(i=0;i<6;i++){
seta(led,!input(led)); esp(400);
  }
#use fast_io(a) while(true){
#use fast_io(b)
#use fast_io(c) if(input(bot)){
#use fast_io(d) printf(lcd_putc,"\f Feliz");
printf(lcd_putc,"\n :)");
#use fast_io(e) lig(led); lig(bl);
}else{
printf(lcd_putc,"\f Triste");
#include <lcdt.c> printf(lcd_putc,"\n :(");
des(led); des(bl)
#define lig output_high }
#define des output_low esp(200);
#define seta output_bit }
4ºEx: Display
Conversão Analógico -Digital
Neste exemplo o uC será
configurado para uma
conversão de 8 bits, e o
range de tensão a ser
convertida será o padrão,
(0–5V). Portanto, essa
faixa será dividida em 256
partes iguais, e o
resultado de uma
conversão será o byte
correspondente a parte
em que se encontra a
tensão convertida.
Conversão AD
 Setup_adc_ports(parâmetros)
 Ex: setup_adc_ports(all_analog);

 Setup_adc()
 Setup_adc(adc_clock_internal)

 Set_adc_channel()
 Setup_adc_channel(0);

 Read_adc()
 Variavel=read_adc
5ºEx: ADC
Sensor de Temperatura : LM35
 Para cada para cada grau de temperatura
a tensão de saída do LM35 é de 10 mV
5ºEx: Termômetro (LM35)
#include <16F877A.h>
setup_adc(ADC_CLOCK_INTERNAL);
#fuses XT setup_adc_ports(AN0);
#use delay(clock=4000000) set_adc_channel(0);

lcd_init();
#use fast_io(a) printf(lcd_putc, "Testando LCD");
#use fast_io(b) output_high(pin_c7);
#use fast_io(c)
#use fast_io(d) while(true){
temp=(float)read_adc()*5.0/
#use fast_io(e) (256.0*0.01);
printf(lcd_putc, "\fTemperatura:\n%f",
temp);
#include <lcdt.c> delay_ms(200);
}
void main(void){ }
float temp = 0;
set_tris_a (0b11111111);

set_tris_c (0x01111111);
Comunicação Serial (UART)
A UART é definida como um periférico de
comunicação entre dispositivos digitais. Este
módulo se baseia no protocolo RS-232, o mais
popular padrão de comunicação assíncrona, ou
seja, entre dispositivos com fontes de relógio
distintas. A grande maioria dos uCs possuem
este hardware integrado. Uma comunicação
síncrona permite uma taxa de transmissão mais
elevada, pois o instante da leitura do sinal é bem
definido devido à referência do relógio. O nosso
exemplo abordará a comunicação assíncrona.
Clique para editar os estilos do texto mestre
 Segundo nível
 Terceiro nível
 Quarto nível
 Quinto nível

Start bit: Avisa que a transferência de um dado será feita. Possui


nível lógico zero.

Stop bit: Avisa que a transferência do dado foi finalizada. Possui


nível lógico um.

Baud rate: Determina quantos bits estarão contidos em um


segundo de comunicação.

Tempo de bit: É o tempo de duração de um bit, tem o valor 1/


(baud rate).

Payload: É a carga de dados da comunicação, nesse caso o


caractere “a”.
Comunicação Serial (UART)
use rs232(parâmetros)
– Ex: #use rs232(baud=9600,rcv=PIN_C7,xmit=PIN_C6)
Putc(caracter)

 Ex: putc(‘a’)
Variável = Getc();

 Ex: caractere = getc();


Puts(mesagem) ou printf(“mensagem”)

 Ex: puts(“mensagem feliz”)


Variável = Gets();

 Ex: msg = gets();


Kbhit();

 Ex: if(kbhit());
8ºEx: UART TX
#include <16f628A.h>
#fuses INTRC_IO, NOMCLR
#use delay(clock=4000000)

#use rs232(baud=9600, rcv=pin_b1, xmit=pin_b2)

#use fast_io(a)
#use fast_io(b)
void main(void){
char dado='a';
set_tris_a(0b11111111);
set_tris_b(0b11111011);
while(true){
if(input(pin_a0)){
delay_ms(20);
if(input(pin_a0)){
putc(dado++);
if(dado == 'h') dado =
'a';
delay_ms(200);
}}
}
8º Ex: UART TX

Clique para editar os estilos do texto mestre


 Segundo nível
 Terceiro nível
 Quarto nível
 Quinto nível
8ºEx: UART RX
while(true){
#include <16F877A.h> if(kbhit()){
#fuses XT dado = getc();
#use delay(clock = 4000000) printf(lcd_putc,"\fDado:\n
%c",
#use fast_io(a) dado);
#use fast_io(b) }
#use fast_io(c) }
#use fast_io(d) }
#define use_portb_lcd true
#include <lcdt.c>

#use rs232(baud=9600 , rcv = pin_c7


, xmit = pin_c6)

void main(void){
char dado;
set_tris_a(0b11111110);
set_tris_c(0b10111111);
lcd_init();
8º Ex: UART RX
8ºEx: RX Int. recebimento
#include <16f877A.h>
#fuses XT
#use delay(clock=4000000)

#use fast_io(a) void main(void){


#use fast_io(b) set_tris_a(0xff);
#use fast_io(c) set_tris_c(0b10111111);
#use fast_io(d)

#use fast_io(e) lcd_init();


enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
#include <lcdt.c>
while(TRUE){
#use rs232(baud=9600, if(flag){
xmit=pin_c6, parity=N, printf (lcd_putc,"\f Dado:
rcv=pin_c7) ");
printf (lcd_putc,"\n %1c",
short flag=1; dado);
char dado=‘K’; flag = 0;
}
#INT_RDA }
Timer
Os Timers são periféricos responsáveis pela
contagem de tempo, mas que também podem
ser usados para contar pulsos de um sinal
externo. São muito úteis quando se deseja um
intervalo de tempo preciso entre eventos.
Podem realizar o papel da função
“delay_ms(X);”, mas permitindo que o
programa trabalhe em outras atividades
enquanto o tempo está sendo contado.
Interrupção Timer
 setup_timer_x(parâmetros);

 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);

set_timerx(valor);
 Ex: set_timerx(131);

enable_interrupts(parâmetros);
 enable_interrupts(GLOBAL|INT_TIMER0);

#INT_timerx

 Define a função de tratamento de


interrupção
11º Ex: Timer 0
//----- Pisca LED ------ void main(void){
#include <16F877A.h> set_tris_a(0b11111110);
#fuses XT set_tris_b(0b11111111);
#use delay(clock=4000000) set_tris_c(0b11111111);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
#use fast_io(a) set_timer0(131);
#use fast_io(b) enable_interrupts(GLOBAL|INT_TIMER0);
#use fast_io(c) while(true){
#use fast_io(d) }
#use fast_io(e) }

short led;
unsigned int cont;
#INT_TIMER0
void trata_tmr0(void){
set_timer0(131+get_timer0());
if(++cont==125){
cont=0;
led=!led;
output_bit(pin_a0,led);
}
}
Clique para editar os estilos do texto mestre
 Segundo nível
 Terceiro nível
 Quarto nível
 Quinto nível
FIM

Você também pode gostar