Ir ao conteúdo
  • Cadastre-se

PIC16f877


adalberto.maicon

Posts recomendados

Boa noite pessoal

Estou mais uma vez aqui para pedir a ajuda de vocês:

Bom procurando soluções na internet achei um programa que faz a leitura da temperatura com um lm35 e faz a comparação com um valor ajustado através de um potenciômetro, ate ai tudo bem, mas o que eu queria mesmo era que em conjunto com este programa um outro programa fazer com que precionando um botão este envia um sinal para a porta RA0 e esta aciona as saídas RC4 RC5 RC6 e RC7 do PIC 16F877A.

segue o programa de controle de temperatura e em seguida o que aciona os leds:

#include <16f877a.h>// características do 16F877
#device adc=10 // máxima resolução de 10 bits
#include <MATH.h> //biblioteca de funcões matemáticas

//============================fusiveis==========================================

#fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt

//==============================definição da rotina de delay====================

#use delay(clock=4000000,restart_wdt)

//=======================================variaveis==============================

float medicao = 0;//armazena o resultado da conversão AD do canal 2 - LM35
float ajuste = 0;//armazena o valor ajustado em um potenciômetro
float medicao1 = 0;//
float ajuste1 = 0;//

//================definicao dos ports e inicializacao===========================

#use fast_io(a)
#use fast_io(
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09

//=================definição de saidas do porte para comandar LCD===============

#bit rs = porte.0 // pino do lcd que define recepção de comandos ou dados.
#bit enable = porte.1 //pino do lcd que o habilita
#bit pushbotton = portb.1//
//output_low(pin_b3);//apaga led 3}


//=================rotina para enviar comando para o LCD========================
void comando_lcd(int caracter)
{
rs = 0; //seleciona para enviar um comando
portd = caracter; //carrega o portd com o carcter
enable = 1; //gera pulso para acionar lcd
delay_us(1); //gera um delay de 1 microsegundo, necessário para o display.
enable = 0; // desabilita o lcd
delay_us(40); // espera 40 microsegundos, necessário para o display
return; // retorna
}
//=======================rotina para enviar um dado para o LCD==================
void escreve_lcd(int caracter)
{
rs = 1; //habilita o envio de um comando
portd = caracter; //carrega portb com o caracter
enable = 1; //cria pulso no enable
delay_us(1); //espera 1uS
enable = 0; //desablita LCD
delay_us(40); //espera 40uS
return;
}
//===============================limpando o LCD=================================
void limpa_lcd()
{
comando_lcd(0x01); //limpa lcd
delay_ms (2); // espera 2 mS
return;
}
//================================inicialização do display======================
void inicializa_lcd()
{
comando_lcd(0x30); //comando para inicializar display
delay_ms(4); //espera 4 mS
comando_lcd(0x30);
delay_us(100);
comando_lcd(0x30);
comando_lcd(0x38);
limpa_lcd(); //limpa o lcd
comando_lcd(0x0c); //comando para display sem cursor/ver apostilas sobre display
comando_lcd (0x06);
return;
}
//=================================tela principal do display====================
void tela_principal()
{
comando_lcd(0x81); // posiciona o cursor na linha 0 e na coluna 2
printf (escreve_lcd, "TEMPERATURA"); //escreve no LCD
comando_lcd(0xC0); //posiciona o cursor na linha 2, coluna 1
printf (escreve_lcd,"AGUA="); //escreve mensagem no lcd
comando_lcd(0xCA); //posiciona o cursor na linha 2, coluna 11
printf (escreve_lcd,"ADJ="); //escreve mensagem no lcd
return;
}
//==================================ponto=======================================
void ponto()
{
comando_lcd(0xC8); //posiciona o cursor na linha 2, coluna 1
printf (escreve_lcd,"*"); //escreve mensagem no lcd
return;
}
//===============================ponto1=========================================
void ponto1()
{
comando_lcd(0xC8); //posiciona o cursor na linha 2, coluna 1
printf (escreve_lcd," "); //escreve mensagem no lcd
return;
}
//=============================mediçao==========================================
void medido()
{
set_adc_channel(2);//
delay_ms(1);
medicao = read_adc();//faz a conversão e salva na variavel medicao
medicao = (medicao * 5); //faz regra de 3
medicao = (medicao / 1023);//número máximo para a conversao (2 elevado a 10).
medicao = (medicao * 100);//
comando_lcd(0xC5); //envia dados para o lcd
restart_wdt();//
delay_ms(5);//
medicao1 = (medicao1 = medicao);
medicao = (medicao * 0);
printf (escreve_lcd,"%2.0f", medicao1); // 2 número inteiro e 2 casa decimais
restart_wdt();//
return;
}
//=============================ajustado=========================================
void ajustado()
{
ponto();
restart_wdt();//
set_adc_channel(1);//
delay_ms(1);//faz com que o conversor não misture um e outro (1 e 2).
ajuste = read_adc();//faz a conversao e salva ajuste
ajuste = (ajuste * 5);//
ajuste = (ajuste / 1023);//
ajuste = (ajuste * 10);//
comando_lcd(0xCE);//define posição no display.
restart_wdt();//
ajuste1 = (ajuste1 = ajuste);
ajuste = (ajuste * 0);//
printf (escreve_lcd,"%2.0f", ajuste1);//
return;
}

//=============================principal========================================

void main()
{
setup_adc_ports (a_analog);
setup_adc (adc_clock_div_32);
setup_counters (rtcc_internal,WDT_2304ms);
set_adc_channel(2);//escolhe o canal 2 RA2 como entrada para o LM35.

//===============================configura tris=================================
set_tris_a(0b111110);//todas entradas
set_tris_b(0b11110111);// todas entradas, menos rb3 (pino 36 do 16f877a) que vai acionar uma carga.
set_tris_c(0b11111111);//todas entradas
set_tris_d(0b00000000);// todas saidas pois vão controlar o LCD
set_tris_e(0b00000100);// 1 corresponde a CS

//========================================lcd===================================

inicializa_lcd();
tela_principal();

//=================================rotina principal=============================
while(true)
{
if (pushbotton == 0)
{
ajustado();
}
else
{
if (medicao1 >= ajuste1)
{
medido();
ponto1();
output_high(pin_b3);
delay_ms(10000);
medido();
}
if (medicao1 <= ajuste1)
{
medido();
ponto1();
output_low(pin_b3);
delay_ms(10000);
medido();
}
}
}
return;
}

//=======================FINAL CONTROLE DA TEMPERATURA==========================


[COLOR="Red"]E este e o que eu quero encaixar no programa acima:[/COLOR]


main() // Função principal

{
while (1) // Loop infinito

{
if(input(pin_a0)==0)

{
output_c(0b0000001);
delay_ms (500);
output_c(0b0000010);
delay_ms (500);
output_c(0b0000100);
delay_ms (500);
output_c(0b0001000);
delay_ms (500);
}
else
{

output_c(0b0000000);
}
}
}

Toda ajuda e bem vinda...

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Em vez de usar o pino RA0, porque não usa a interrupção externa do pino RB0?

Assim basta usar a interrupção externa para executar uma ação correspondente a esse botão.

Dei uma olha no seu código, e ele está bem ineficiente. Usar delays enormes no meio das funções não é algo muito legal, pois trava todo o resto do programa. O melhor é usar uma interrupção por timer para eliminar esses delays.

Link para o comentário
Compartilhar em outros sites

É o que o colega tá dizendo, não tem erro, cria a rotina de interrupção e coloca esse código dentro dela, tipo assim:

#int_EXT

void EXT_isr(void)

{

if(input(pin_a0)==0)

{

output_c(0b0000001);

delay_ms (500);

output_c(0b0000010);

delay_ms (500);

output_c(0b0000100);

delay_ms (500);

output_c(0b0001000);

delay_ms (500);

}

else

{

output_c(0b0000000);

}

}

E para melhorar esses delays ai, estouros de timer, pro programa não ficar travado nesse tempo.

#int_RTCC

void RTCC_isr(void)

{

//aqui você coloca a variável a ser incrementada

}

E no main você adiciona essas linhas: (no caso usei o timer0)

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);

setup_timer_1(T1_DISABLED);

setup_timer_2(T2_DISABLED,0,1);

enable_interrupts(INT_RTCC);

enable_interrupts(INT_EXT);

enable_interrupts(GLOBAL);

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...
Opa valeu pela dica

ja deu uma clareada mas nao entendi esta parte:

#int_RTCC

void RTCC_isr(void)

{

//aqui você coloca a variável a ser incrementada

}

Essa é a função do timer, ela vai ficar incrementando uma variável qualquer, ai você pode usar isso em vez de delay, por exemplo: se você quer um delay de 1segundo e você configurou o timer pra estourar em 1ms então fica assim:

#int_RTCC

void RTCC_isr(void)

{

x++;

}

if (x==1000) // se o timer estoura a cada 1ms então 1s = 1000ms

{

output_high(pin_A2); // aqui executa o que você quiser

x=0; // aqui zera a variável pra começar de novo

}

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...