Escolar Documentos
Profissional Documentos
Cultura Documentos
Apostila
Microcontroladores PIC
Programando em C
Professores
Fabio Caldas
&
Marcos Felipe
Prof. Fabio Caldas & Marcos Felipe
Pgina 1
Pgina 2
/***************************EXERCCIO DE FIXAO********************************
********************************************************************************
******DIGA O SIGNIFICADO DE CADA LINHA DO FRAGUIMENTO DE PROGRAMA ABAIXO ******/
#INCLUDE <16F877.H>
#USE DELAY(CLOCK=4000000)
#FUSES NOWDT, XT, BROWNOUT, NOPUT, NOPROTECT, NOCPD, NOLVP
VOID MAIN(VOID)
{
}
// AS CONTRABARRAS (//) INDICA COMENTRIO DE UMA LINHA APENAS.
// A CONTRABARRA SEGUIDO DE ESTERISTICO (/* */ INDICA COMENTRIO DE MULTIPLAS LINHAS
/* DEPOIS QUE O CDIGO CRIADO, SER PRECISO GERAR UM ARQUIVO HEX. QUE A LINGUAGEM
QUE A MQUINA ENTENDE. ESSE PROCESSO CHAMAMOS DE COMPILAR.
PARA EXECUTAR A COMPILAO BASTA PRECIONARMOS NO TECLADO F9 OU MENU -> COMPILE -> F9*/
Pgina 3
Pgina 4
Pgina 5
Pgina 6
Pgina 7
Pgina 8
Pgina 9
Pgina 10
Pgina 11
Pgina 12
Pgina 13
PIN_E2
PIN_E1
void Inicializa(void)
{
//delay_ms(2000); manter essa linha comentada para usar no pic simulator ide
setup_adc(ADC_CLOCK_DIV_8);
// Configura clock da converso
setup_adc_ports(RA0_RA1_RA3_ANALOG); // Configura A/D
//set_adc_channel(0);
// L a entrada 0
//set_adc_channel(1);
// L a entrada 0
setup_wdt(WDT_2304MS);
// Configura WDT para 2,304 s
Lcd_Inst(0x30);
delay_ms(3);
Lcd_Inst(0x30);
Lcd_Inst(0x30);
Lcd_Inst(0x38);
Lcd_Inst(0x01);
delay_ms(1);
// Inicializa o display
Pgina 14
Lcd_Inst(0x0C);
Lcd_Inst(0x06);
}
void Atualiza_tela1(void)
{
set_adc_channel(1);
Lcd_Inst(0x81);
tensao= read_adc();
tensao*=0.01953125;
printf(lcd_dado,"Tensao %1.3f V", tensao);
}
void Atualiza_tela2(void)
{
set_adc_channel(0);
Lcd_Inst(0xC1);
// Posiciona cursor no display
temperatura= read_adc();
temperatura*=2;
printf(lcd_dado,"Temper %1.1f C", temperatura);
}
void Lcd_Inst(char dado)
{
disable_interrupts(GLOBAL);
output_low(RS);
output_d(dado);
delay_cycles(2);
output_high(EN);
delay_cycles(2);
output_low(EN);
delay_ms(1);
enable_interrupts(GLOBAL);
}
void Lcd_Dado(char dado)
{
disable_interrupts(GLOBAL);
output_high(RS);
output_d(dado);
delay_cycles(2);
output_high(EN);
delay_cycles(2);
output_low(EN);
delay_ms(1);
enable_interrupts(GLOBAL);
}
// Desliga as interrupes
// Pe pino de RS em baixo, modo comando
// Pe o dado no portd
// Aguarda 2 us, acomodao
// Gera pulso de clock
// Aguarda 1ms
// Liga as interrupes
// Desliga as interrupes
// Seta o pino RS, modo dado
// Pe o dado no portd
// Aguarda 2us, acomodao
// Gera pulso de clock
// Aguarda 1ms
// Liga as interrupes
Pgina 15
Pgina 16
Pgina 17
Pgina 18
Pgina 19
setup_adc_ports(no_analogs);
set_timer0(0);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
#int_timer0
void Ist_Timer0(void)
{
indice++;
switch(indice)
{
case 1:
output_d(SEL_LINHA1);
tecla1=0;
// Limpa a tecla pressionada
tecla2=0;
// Limpa a tecla pressionada
tecla3=0;
// Limpa a tecla pressionada
if (!input(COL1)) tecla1=1; // Verifica se tecla est pressionada
if (!input(COL2)) tecla2=1; // Verifica se tecla est pressionada
if (!input(COL3)) tecla3=1; // Verifica se tecla est pressionada
break;
// Liga display selecionado
case 2:
output_d(SEL_LINHA2);
// Seleciona no barramento a linha 1
tecla4=0;
// Limpa a tecla pressionada
tecla5=0;
// Limpa a tecla pressionada
tecla6=0;
// Limpa a tecla pressionada
if (!input(COL1)) tecla4=1; // Verifica se tecla est pressionada
if (!input(COL2)) tecla5=1; // Verifica se tecla est pressionada
if (!input(COL3)) tecla6=1; // Verifica se tecla est pressionada
break;
// Liga display selecionado
case 3:
output_d(SEL_LINHA3);
// Seleciona no barramento a linha 3
tecla7=0;
// Limpa a tecla pressionada
tecla8=0;
// Limpa a tecla pressionada
tecla9=0;
// Limpa a tecla pressionada
if (!input(COL1)) tecla7=1; // Verifica se tecla est pressionada
if (!input(COL2)) tecla8=1; // Verifica se tecla est pressionada
if (!input(COL3)) tecla9=1; // Verifica se tecla est pressionada
break;
// Liga display selecionado
case 4:
Pgina 20
Pgina 21
#include <16F877.h>
//microcontrolador utilizado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Configuraes para gravao
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#fuses xt,nolvp,wdt,nolvp,nobrownout,put,nodebug,noprotect,nowrt,nocpd
// Configuraes da Mquina
// Oscilador: XT, LVP: Off, WDT: On
// Brown-out: Off, Power-up: Off, Debug: Off
// CP: Off, CPD: Off
#use delay(clock=4000000)
// Utiliza biblioteca de delay
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Definio e inicializao das variveis
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as variveis globais do sistema
int1 tecla0=0, tecla1=0, tecla2=0, tecla3=0, tecla4=0, tecla5=0, tecla6=0,
tecla7=0, tecla8=0, tecla9=0, teclaE=0, teclaC=0;
int indice=0;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Constantes internas
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as constantes utilizadas pelo sistema
#define SEL_LINHA1
0b00001110
// Seleo da linha 1
#define SEL_LINHA2
0b00001101
// Seleo da linha 2
#define SEL_LINHA3
0b00001011
// Seleo da linha 3
#define SEL_LINHA4
0b00000111
// Seleo da linha 4
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Entradas
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as entradas do sistema
#define COL1
PIN_A4
#define COL2
PIN_A5
#define COL3
PIN_A0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Sadas
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as sadas do sistema
#define RS
PIN_E2
// Pino de seleo de modo do display
#define EN
PIN_E1
// Pino de habilitao do display
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Prototipagem das funes
*
Pgina 22
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos declarar todas as funes definidas pelo usurio
void Inicializa(void);
// Prototipagem da procedure
void Tela_Inicial(void);
// Prototipagem da procedure
void Atualiza_PWM_0(int dado);
// Prototipagem da procedure
void Atualiza_PWM_20(int dado);
// Prototipagem da procedure
void Atualiza_PWM_40(int dado);
// Prototipagem da procedure
void Atualiza_PWM_60(int dado);
// Prototipagem da procedure
void Atualiza_PWM_80(int dado);
// Prototipagem da procedure
void Atualiza_PWM_100(int dado);
// Prototipagem da procedure
void Lcd_Inst(char dado);
// Prototipagem da procedure
void Lcd_Dado(char dado);
// Prototipagem da procedure
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina Principal
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Nessa parte ficar o loop principal do sistema
void main (void)
{
Inicializa();
// Chama rotina para inicializar o sistema
while(1)
// Entra em loop infinito
{
restart_wdt();
// Limpa o wdt
if (tecla1)
Atualiza_PWM_0(0x8B); // Atualiza PWM e LCD
if (tecla2) Atualiza_PWM_20(0x8B); // Atualiza PWM e LCD
if (tecla3) Atualiza_PWM_40(0x8B); // Atualiza PWM e LCD
if (tecla4) Atualiza_PWM_60(0x8B); // Atualiza PWM e LCD
if (tecla5) Atualiza_PWM_80(0x8B); // Atualiza PWM e LCD
if (tecla6) Atualiza_PWM_100(0x8B); // Atualiza PWM e LCD
if (tecla7)
Atualiza_PWM_0(0xCB); // Atualiza PWM e LCD
if (tecla8) Atualiza_PWM_20(0xCB); // Atualiza PWM e LCD
if (tecla9) Atualiza_PWM_40(0xCB); // Atualiza PWM e LCD
if (teclaC) Atualiza_PWM_60(0xCB); // Atualiza PWM e LCD
if (tecla0) Atualiza_PWM_80(0xCB); // Atualiza PWM e LCD
if (teclaE) Atualiza_PWM_100(0xCB); // Atualiza PWM e LCD
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Inicializao do Sistema
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Inicializa(void)
{
delay_ms(2000);
setup_adc_ports(no_analogs); // Todos os ADs desligados
setup_ccp1(CCP_PWM);
// Confirura modo CCP para PWM
setup_ccp2(CCP_PWM);
Pgina 23
output_low(PIN_C1);
output_low(PIN_C2);
// Garante estado do port
set_pwm1_duty(0);
set_pwm2_duty(0);
// Garante estado inicial do modo CCP
setup_timer_2(T2_DIV_BY_4,249,1);
set_timer0(0);
// Inicializa timer 0 com 0
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1); // Timer configurado para clock
// Interno com prescaler de 1:4
setup_wdt(WDT_2304MS);
// Configura WDT para 2,304 s
enable_interrupts(INT_TIMER0); // Habilita interrupo de timer 0
enable_interrupts(GLOBAL); // Habilita todas as interrupes
Lcd_Inst(0x30);
// Inicializa o display
delay_ms(3);
Lcd_Inst(0x30);
Lcd_Inst(0x30);
Lcd_Inst(0x38);
Lcd_Inst(0x01);
delay_ms(1);
Lcd_Inst(0x0C);
Lcd_Inst(0x06);
Tela_Inicial();
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Apresentar a Tela Inicial
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Tela_Inicial(void)
{
Lcd_Inst(0x80);
// Atualiza a tela do LCD
printf(lcd_dado,"CCP1(Vent): 0 %");
Lcd_Inst(0xC0);
// Atualiza a tela do LCD
printf(lcd_dado,"CCP2(Resi): 0 %");
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Atualizar o Duty-Cycle do PWM para 0%
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Atualiza_PWM_0(int dado)
{
Lcd_Inst(dado);
printf(lcd_dado," 0 ");
if(dado==0x8B)
{ set_pwm1_duty(0);}
else
{ set_pwm2_duty(0);}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Atualizar o Duty-Cycle do PWM para 20%
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Atualiza_PWM_20(int dado)
{
Lcd_Inst(dado);
Pgina 24
printf(lcd_dado," 20");
if(dado==0x8B)
{ set_pwm1_duty(50);}
else
{ set_pwm2_duty(50);}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Atualizar o Duty-Cycle do PWM para 40%
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Atualiza_PWM_40(int dado)
{
Lcd_Inst(dado);
printf(lcd_dado," 40");
if(dado==0x8B)
{ set_pwm1_duty(101);}
else
{ set_pwm2_duty(101);}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Atualizar o Duty-Cycle do PWM para 60%
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Atualiza_PWM_60(int dado)
{
Lcd_Inst(dado);
printf(lcd_dado," 60");
if(dado==0x8B)
{ set_pwm1_duty(152);}
else
{ set_pwm2_duty(152);}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Atualizar o Duty-Cycle do PWM para 80%
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Atualiza_PWM_80(int dado)
{
Lcd_Inst(dado);
printf(lcd_dado," 80");
if(dado==0x8B)
{ set_pwm1_duty(203);}
else
{ set_pwm2_duty(203);}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina para Atualizar o Duty-Cycle do PWM para 100%
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Pgina 25
Pgina 26
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
indice=0;
break;
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Fim do Programa
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Pgina 27
Pgina 28
Pgina 29
//delay_ms(2) ; // aguarda 2 ms
lcd_inst(0x81) ; // posiciona o cursor na linha 1 e coluna 2
printf(lcd_dado, "relogio digital") ; // escreve a frase
lcd_inst(0xc4) ; // posiciona o cursor na linha 2 e coluna 5
printf(lcd_dado,"\f%02u:%02u:%02u", HORA, MINUTO, SEGUNDO);
delay_ms(1000);
}
}
void inicializa(void)
{
setup_wdt(WDT_2304MS);
setup_adc_ports(no_analogs);
set_timer0(0);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
// aguarda 2s
//delay_ms(2) ; comentar essa linha para utilizar no pic simulator
// rotina de inicializao do display
lcd_inst(0x30) ;
delay_ms(3) ;
lcd_inst(0x30) ;
lcd_inst(0x30) ;
lcd_inst(0x38) ;
lcd_inst(0x01) ;
delay_ms(1) ;
lcd_inst(0x0c) ;
lcd_inst(0x06) ;
}
void lcd_inst(char dado)
{
disable_interrupts(global) ; // desliga As interrupes
output_low(rs) ; // pe pino de rs em baixo, modo comando
output_d(dado) ; // pe o dado no PORTD
delay_cycles(2) ; // aguarda 2 us, acomodao
output_high(en) ; // gera pulso de clock
delay_cycles(2) ;
output_low(en) ;
delay_ms(1) ; // aguarda 1ms
enable_interrupts(global) ; // liga As interrupes
}
Pgina 30
break;
case 3:
output_c(SEL_LINHA3); // Seleciona no barramento a linha 3
tecla7=0;
// Limpa a tecla pressionada
tecla8=0;
// Limpa a tecla pressionada
tecla9=0;
// Limpa a tecla pressionada
if (!input(COL1)) tecla7=1; // Verifica se tecla est pressionada
Pgina 31
break;
case 4:
}
}
Pgina 32