• Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   14-02-2016

      Prezados membros do Fórum do Clube do Hardware,

      Está aberto o processo de seleção de novos moderadores para diversos setores do fórum. Os requisitos são:
        Pelo menos 1000 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas ao formulário abaixo:    Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
Entre para seguir isso  
Seguidores 0
adalberto.maicon

PIC16f877

7 posts neste tópico

#1   Postado (editado)

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...

Editado por Bcpetronzio
Inserir code

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal estou postando o esquema elétrico do que estou pretendendo, ainda falta dimensionar alguns parâmetros mas e apenas para dar a ideia do que eu to querendo.

post-945277-13884962610322_thumb.jpg

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal uma ajuda com isso to ficando louco ja.

Compartilhar este post


Link para o post
Compartilhar em outros sites

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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

#5   Postado (editado)

É 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);

Editado por chacalgbi
Erro de digitação

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

}

Compartilhar este post


Link para o post
Compartilhar em outros sites
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

}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!


Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.


Entrar agora
Entre para seguir isso  
Seguidores 0