Академический Документы
Профессиональный Документы
Культура Документы
Raniere Lira
Raniere Lira de Sousa Martins acadmico de Engenharia Eltrica pela UFPI (ranieresystem@hotmail.com)
Resumo Pretende-se mostrar com este trabalho a
programao avanada em linguagem C para o PIC
16F877A bem como a familiarizao com os comandos
de configurao do mdulos CCP sendo compilado no
CCS.
Palavras-chave Linguagem C, Mdulos CCP,
16F877A, duty cycle, PIC C Compiler(CCS).
I. INTRODUO
A. Mdulo Comparador
O mdulo comparador contm dois comparadores
analgicos com entradas multiplexadas em RA0 RA3,
podendo utilizar fonte de referncia externa ou interna no
chip com resoluo de 4 bits permite 16 valores de
referncia. Por sua vez o comparador pode disparar no flanco
positivo o negativo, tendo suas configuraes controladas
pelo registro CMCON no endereo 01Fh.
A Operao de comparao (no confundir com
comparador CCP) ocorre com dois sinais analgicos em
sua(s) porta(s), quando a tenso analgica em Vin+ for
menor que em Vin-, a sada do comparador ser 0 (zero) e
quando a tenso analgica em Vin+ for maior que em Vin-, a
sada do comparador ser 1 (um), sada esta digital que
apresenta uma pequena rea incerta (conforme vemos na figura ao lado) em resposta do tempo de aquisio que 150
ns(tpico e 400ns mximo).
V = Vdd - Vss
V = Vref(+) - Vref(-)
Sadas digitais
Como podemos variar, a qualquer momento, a tenso de
referncia temos uma possibilidade interessante que a
construo de gatilho via hardware, onde a tenso ao disparar
o comparador aciona flag de interrupo CMIF bit 6 do
registro PIR1, procedendo a captura de um sinal inclusive
com ajuste de disparo na subida ou descida do pulso.
A funo que nos permite ajustar as opes dos
comparadores Setup_comparator( modo ), onde modo pode
ser uma das seguintes constantes internas.
Tabela 1.
Exemplo:
setup_comparator (A0_A3_A1_A2);
setup_comparator(A0_VR_A1_VR); //A0 e A1 com
voltagem de referncia interna.
B. Tenso de Referncia
Este mdulo consiste em uma rede de 16 resistores de
preciso em srie que provm 16 valores de tenso com sada
no pino RA2, controlados pelo registro VRCON, endereo
9Fh.
set_tris_c(0b00000000);
// TODO: USER CODE!!
setup_ccp1(CCP_PWM);
while(1)
{
int16 x,t;
delay_ms(10);
//Conforme o valor lido, o
duty cycle do PWM alterado a cada 10 ms
x=read_adc();
//Efetua uma converso A/D
set_pwm1_duty((x*200)/1023);
//
output_bit(pin_c2,x);
}
}
II. DESENVOLVIMENTO
Foi escrito um programa em C para o PIC 16F877A para
efetuar a leitura de tenso de um potencimetro, utilizando
um conversor A/D e gerar um sinal PWM com frequncia de
20 kHz atravs do mdulo CCP1.
Neste programa conforme cada valor lido, o duty cycle do
PWM alterado a cada 10 ms. O cdigo fonte encontra-se
abaixo:
#include <PWM.h>
void main()
{
setup_adc(adc_clock_internal);
//configura o
conversor A/D com clock interno
setup_adc_ports(AN0);
//configura a porta A0
como entrada analgica
set_adc_channel(0);
//seleciona o canal 0
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|
RTCC_DIV_1);
//clock interno: Fosc/4
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
//clock interno: Fosc/4
setup_timer_2(T2_DIV_BY_1,49,1);
//
(Fosc(4.000.000)/4)/(49+1) = 20.000 Hz
setup_vref(FALSE);
setup_adc(adc_clock_internal);
conversor A/D com clock interno
//configura o
setup_adc_ports(AN0);
//configura a porta A0
como entrada analgica
set_adc_channel(0);
//seleciona o canal 0
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
//clock interno: Fosc/4
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
//clock interno: Fosc/4
setup_timer_2(T2_DIV_BY_1,49,1);
//
(Fosc(4.000.000)/4)/49 = 20408,16 Hz~ 20kHz
setup_ccp2(CCP_PWM);
//Configura o
modulo CCP2para gerao PWM
setup_ccp1(CCP_CAPTURE_RE);
//Configura
o modulo CCP2 para modo captura borda de subida
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
Set_tris_b(trisc);
//direo dos bits do portB
portc = 0; //zera todos os bits
while(true)
{
int16 tempo,x,cap;
float temp_cap;
delay_ms(10);
//Conforme o valor lido, o
duty cycle do PWM alterado a cada 10 ms
x=read_adc();
//Efetua uma converso
A/D
set_pwm2_duty((x*200)/1023);
//
output_bit(ccp_2,x);
captura = 0; //zera flag de captura
interrupcao= 0; //zera flag de interrupo
set_timer1(0); //zera o timer1 , incremento a cada 1us.
while( ! captura ); //executa enquanto no capturou
temp_cap=0.000026;
cap=cap_msb<<256+cap_lsb;
if(temp_cap>cap)
{
setup_ccp1(CCP_CAPTURE_FE);
//conf.
p borda de descida
tempo = ccp_1;//houve um evento em portc
capturou o tempo