Ir ao conteúdo

Programação C p/ PIC 16f628a


Bencz

Posts recomendados

Postado

Olá....

estou tentando desenvolver um programa para um circuito, que tem um display de 7 segmentos e 3 botões, onde, cada botão tem uma função...

o primeiro botão: tem a função de iniciar o contador, de 0 -> 90, muda de numero a cada 1 segundo

o segundo botão: tem a função de pausar o contador.

o terceiro botão: tem a função de zerar, resetar o contador...

o problema é, eu não consigo fazer essas 3 funções... o código que eu fiz, é o seguinte:


#include <16F628A.h>

#use delay(clock=4000000)
#fuses INTRC_IO,NOWDT,PUT,NOBROWNOUT,NOLVP

#define BTM1 PIN_A2
#define BTM2 PIN_A3
#define BTM3 PIN_A4

int conta=0;
int i=0;
int16 d1, d2;

int digito[10] =
{0b00111111, //Dígito 0
0b00000110, //Dígito 1
0b01011011, //Dígito 2
0b01001111, //Dígito 3
0b01100110, //Dígito 4
0b01101101, //Dígito 5
0b01111101, //Dígito 6
0b00000111, //Dígito 7
0b01111111, //Dígito 8
0b01101111 //Dígito 9
};

#INT_TIMER0
void trata_t0()
{
conta++;
if (conta>2) conta = 1;

switch(conta)
{
case 1: OUTPUT_B(digito[d1]);
OUTPUT_A(0X01);
break;
case 2: OUTPUT_B(digito[d2]);
OUTPUT_A(0X02);
break;
}

SET_TIMER0(90);
}


void main()
{
ENABLE_INTERRUPTS(GLOBAL | INT_TIMER0);
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_16);
SET_TIMER0(90);

while(true)
{
i++;
if (i>=90) i = 0;

d1 = (i/10) % 10;
d2 = (i/1) % 10;

delay_ms(1000);
}
}

Agradeço, se alguem puder me ajudar a fazer este programa...

Postado

Qual o erro que dá?

Se você tá usando interrupção, acho que não devia usar esse delay_ms(1000); o programa vai travar nesse delay de qualquer jeito por 1 segundo. Use a própria interrupção pra contar o tempo.

Ou então, se não precisar de precisão nessas pausas, usa o delay mesmo e esquece interrupção.

Postado

Claro amigo estamos aqui pra isso nao é.Bom você ja tem sua funçao de gerar os digitos no display correto?.... então podemos começar

Para o contador ,sugiro usar interrupçao do timer1,a questao do menu pode fazer uma variavel x,que tem um valor por botao,tipo botao iniciar x=0,botao pause x=1.

Em casa de iniciar você seta um flag e no timer1 você joga a condiçao de que quando este flag mudar de valor o contador devera ser iniciado.

Para pausar ,você so precisa mudar o valor do flag,porém sem zera o contador,e quando o flag voltar a condiçao você continua a contar de onde parou ate atingir o valor limite.

Para desligar ,você faz a condiçao q aciona o contador com falsa e zera o contador.

Deu pra pegar a ideia ou ta confuso?

Postado
Claro amigo estamos aqui pra isso nao é.Bom você ja tem sua funçao de gerar os digitos no display correto?.... então podemos começar

Para o contador ,sugiro usar interrupçao do timer1,a questao do menu pode fazer uma variavel x,que tem um valor por botao,tipo botao iniciar x=0,botao pause x=1.

Em casa de iniciar você seta um flag e no timer1 você joga a condiçao de que quando este flag mudar de valor o contador devera ser iniciado.

Para pausar ,você so precisa mudar o valor do flag,porém sem zera o contador,e quando o flag voltar a condiçao você continua a contar de onde parou ate atingir o valor limite.

Para desligar ,você faz a condiçao q aciona o contador com falsa e zera o contador.

Deu pra pegar a ideia ou ta confuso?

Sim, consegui entender... mas, eu não sei exatamente como fazer isso, digo.... eu não sei os comandos certos.... :(

Postado
pode usar o if ,como o switch case

bom, fiz algumas mudanças.... mas não sei se está correto...vejá:


#include <16F628A.h>

#use delay(clock=4000000)
#fuses INTRC_IO,NOWDT,PUT,NOBROWNOUT,NOLVP

#define BTM1 PIN_A2
#define BTM2 PIN_A3
#define BTM3 PIN_A4

bool flag = false;
int conta=0;
int i=0;
int16 d1, d2;

int digito[10] =
{0b00111111, //Dígito 0
0b00000110, //Dígito 1
0b01011011, //Dígito 2
0b01001111, //Dígito 3
0b01100110, //Dígito 4
0b01101101, //Dígito 5
0b01111101, //Dígito 6
0b00000111, //Dígito 7
0b01111111, //Dígito 8
0b01101111 //Dígito 9
};

#INT_TIMER1
void trata_t1()
{
conta++;
if (conta>2) conta = 1;

switch(conta)
{
case 1: OUTPUT_B(digito[d1]);
OUTPUT_A(0X01);
break;
case 2: OUTPUT_B(digito[d2]);
OUTPUT_A(0X02);
break;
}

SET_TIMER0(90);
}


void main()
{
ENABLE_INTERRUPTS(GLOBAL | INT_TIMER1);
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_16);
SET_TIMER0(90);

while(true)
{
if(input(BTM1))
{
flag = true;
}

if(input(BTM2))
{
flag = false;
}

if(input(BTM3))
{
d1 = 0;
d2 = 0;
i = 0;
}

if(flag)
{
i++;
if (i>=90) i = 0;

d1 = (i/10) % 10;
d2 = (i/1) % 10;

delay_ms(1000);
}

}
}

Postado
Funcionou? ,você testou?

Bom... quando eu aperto no BTM1 ele inicia.... mas depois, que ele inicia a contagem, eu não consigo pausar e nem zerar o contador... como posso fazer p/ corrigir isso ?

Postado

bom a ideia é a seguinte,quando pressionar botao iniciar uma variavel de controle ligara o contador, para pausar ,você precisara fazer esta variavel ficar false, porém tera q salvar o valor de contador em outra variavel e então zerar contador,para quando iniciar novamente ela assumir o valor de contador e a partir dali continuar contando ate chegar ao final,para zerar é mais simples,zere a variavel de controle e o contador.

Postado
bom a ideia é a seguinte,quando pressionar botao iniciar uma variavel de controle ligara o contador, para pausar ,você precisara fazer esta variavel ficar false, porém tera q salvar o valor de contador em outra variavel e então zerar contador,para quando iniciar novamente ela assumir o valor de contador e a partir dali continuar contando ate chegar ao final,para zerar é mais simples,zere a variavel de controle e o contador.

Não consegui fazer funcionar a sua ideia... pelo que pude notar... o problema é com o

delay_ms(1000);

, pois o PIC fica esperando esse tempo... certo ? Então.... o delay está atrapalhando nesse processo todo.... acredito eu...

Postado

Bom amigo,nao gosto de dar a coisa pronta mais cabe a você tentar entender e nao apenas copiar e colar.

Atente aos botões q precisam levar o pinos de entrada a nivel 0,outra coisa é os bits do display,o q usei é anodo comum.


#include <16f628a.h>
#fuses intrc_io, nowdt, noprotect, put, nobrownout, mclr, nolvp, nocpd
#use delay(clock=4000000)
#define start pin_a0
#define pause pin_a1
#define stop pin_a2
#define Display1 pin_a6
#define Display2 pin_a7

void display();
int8 numero,dezena,unidade;
int8 save_contador,contador,x=0;
int8 seg;
int8 y;

int digito[10]={0b00000001,//0
0b11001111,//1
0b10010010,//2
0b00000110,//3
0b11001100,//4
0b00100100,//5
0b00100000,//6
0b00001111,//7
0b00000000,//8
0b00000100,//9
};

void DISPLAY(numero)
{
unidade = numero / 10; // Calcula a unidade
dezena = numero - (unidade * 10); // Calcula a dezena
output_b (digito[unidade]); // Apresenta Digito[unidade_do_contador]
output_high (Display1); // Habilita display 1
delay_ms (50); // Aguarda 50ms para dar uma pausa no PIC
output_low (Display1); // Desabilita display 1
output_b (digito[dezena]); // Apresenta Digito[dezena_do_contador]
output_high (Display2); // Habilita display 2
delay_ms (50); // Aguarda 50ms para dar uma pausa no PIC
output_low (Display2);

}

#int_TIMER1 //Interrupção do Timer1
void temp1s(void) //Funcão. O que deverá ser feiro a cada interrupão.
{
if(x==1){
seg++;
}
if(seg==2){
seg=0;
contador++;
}

if(contador>99){
contador=0;
x=0;
}


set_timer1 (3036); //Preload do Timer1

}


void main(){
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configuração do Timer1 para clock interno = 1E6 dividido por 8
set_timer1 (3036);
enable_interrupts(INT_TIMER1);
enable_interrupts(global);

while(true){

if(!input(start)){
delay_ms(50);
if(y==1){
contador=save_contador;
y=0;
}
x=1;
}
if(!input(pause)){
delay_ms(50);
x=0;
y=1;
save_contador=contador;
}
if(!input(stop)){
delay_ms(50);
x=0;
contador=0;
}
display(contador);
}

}

Obs:Codigo testado no proteus funcioando perfeitamente,se for montar ele nao precisa de oscilador pois usa o interno ,e os pinos para oscilador externo foi usado como i/0.Abraços....

Postado

Olá, jorgeletronico (:

Muito obrigado.... também não gosto de passar as coisas de mão beijada.... mas as vezes, não tem como, as vezes, é necessário aquela LUZ ):

Muito obrigado (:

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!