Ir ao conteúdo
  • Cadastre-se

PIC PIC com vida própria


Posts recomendados

Olá a todos!

Venho estudando sobre eletrônica digital no tempo livre, e aproveitando a experiência prévia com programação decidi me aventurar num projetinho próprio: Um relógio digital.

Decidi usar 4 displays de 7 segmentos, um CD4511 para driver e um pic 16F630 para controlar tudo. Sei que existem códigos prontos, mas decidi tentar fazer algo "original" (embora relógios digitais já existem faz tempo kkk) e escrevi o código:

/*
Autor: NLucas
Data de início: 05/07/19
Relógio com 4 display's de 7 segmentos
PIC: 16F630
BCDto7: CD4511
*/

#include <16F630.h>
  
                
#FUSES NOPROTECT                             
#FUSES INTRC_IO  
#FUSES NOWDT
#use delay(clock=4000000)

// CD4511
#define pA pin_A0
#define pB pin_A1
#define pC pin_A2
#define pD pin_C0
// Multiplexação
#define d1 pin_C1
#define d2 pin_C2
#define d3 pin_C3
#define d4 pin_C4
//Entradas
#define b1 pin_A4 // Config | Confirma
#define b2 pin_A5 // +
//Led Config
#define ld pin_C5

//Variáveis de horário
byte h = 0;
byte m = 0;
byte s = 0;
int h1 = 0;
int h2 = 0;
int m1 = 0;
int m2 = 0;

//Gerais
byte configId = 0;
boolean config = FALSE;
boolean ldStat = FALSE;

//Ajusta o horário a ser mostrado
void incSeg() {
if (config == FALSE){
ldStat = !ldStat;
output_bit(ld,ldStat);
 s++;
 if (s == 60){
 m++;
 s = 0;
 }
  if (m == 60){
 h++;
 m = 0;
 }
  if (h == 24){
 h = 0;
 }
}
}

void trocaNum(int num, byte display){
output_bit(d1, FALSE);
output_bit(d2, FALSE);
output_bit(d3, FALSE);
output_bit(d4, FALSE);
switch (num) {
case 0:
output_bit(pA, FALSE);
output_bit(pB, FALSE);
output_bit(pC, FALSE);
output_bit(pD, FALSE);
break;
case 1:
output_bit(pA, TRUE);
output_bit(pB, FALSE);
output_bit(pC, FALSE);
output_bit(pD, FALSE);
break;
case 2:
output_bit(pA, FALSE);
output_bit(pB, TRUE);
output_bit(pC, FALSE);
output_bit(pD, FALSE);
break;
case 3:
output_bit(pA, TRUE);
output_bit(pB, TRUE);
output_bit(pC, FALSE);
output_bit(pD, FALSE);
break;
case 4:
output_bit(pA, FALSE);
output_bit(pB, FALSE);
output_bit(pC, TRUE);
output_bit(pD, FALSE);
break;
case 5:
output_bit(pA, TRUE);
output_bit(pB, FALSE);
output_bit(pC, TRUE);
output_bit(pD, FALSE);
break;
case 6:
output_bit(pA, FALSE);
output_bit(pB, TRUE);
output_bit(pC, TRUE);
output_bit(pD, FALSE);
break;
case 7:
output_bit(pA, TRUE);
output_bit(pB, TRUE);
output_bit(pC, TRUE);
output_bit(pD, FALSE);
break;
case 8:
output_bit(pA, FALSE);
output_bit(pB, FALSE);
output_bit(pC, FALSE);
output_bit(pD, TRUE);
break;
case 9:
output_bit(pA, TRUE);
output_bit(pB, FALSE);
output_bit(pC, FALSE);
output_bit(pD, TRUE);
break;
}
switch (display) {
case 1:
 output_bit(d1, TRUE);
break;
case 2:
 output_bit(d2, TRUE);
break;
case 3:
 output_bit(d3, TRUE);
break;
case 4:
 output_bit(d4, TRUE);
break;
}
}

#int_timer0
void trata_timer0 ()
{
  int s;
  set_timer0(131+get_timer0());
  s++;
  if (s == 124)
  {
  incSeg();
  s = 0;
 }
}


void pisca(byte vez, boolean stat){
 while (vez > 0){
  Output_bit(ld,TRUE);
  delay_ms(200);
  Output_bit(ld,FALSE);
  delay_ms(100); 
  vez = vez- 1;
   if (vez == 0){
   Output_bit(ld,stat); 
   }
  }
}

void trataHora() {
if ((h >= 0) && (h < 10)){ 
h1 = 0;
h2 = h;
}else{
h1 = h/10;
h2 = h-(10*h1);
}
if ((m >= 0) && (m < 10)){ 
m1 = 0;
m2 = m;
}else{
m1 = m/10;
m2 = m-(10*m1);
}
}


void main() {
setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_64 );  
set_timer0(131);                                         
enable_interrupts (global | int_timer0); 
Output_bit(ld,FALSE);
 While(TRUE){
if (config == FALSE){
 if (input_state(b1)){
  pisca(1, TRUE);
  config = TRUE;
  configId++;
  delay_ms(200);
 }
}else{
 switch(configId){
  case 1:
   if (input_state(b2)){
    h++;
    if (h == 24){ h = 0;}
    delay_ms(300);
   }
  if (input_state(b1)){
   pisca(2, TRUE);
   configId++;
   delay_ms(200);
  }
  break;
  case 2:
   if (input_state(b2)){
    m++;
    if (m == 60){ m = 0;}
    delay_ms(300);
   }
   if (input_state(b1)){
    pisca(3, FALSE);
    configId = 0;
    delay_ms(200);
  }
  break;
 }
}
trocaNum(h1, 1);
delay_ms(1);
trocaNum(h2, 2);
delay_ms(1);
trocaNum(m1, 3);
delay_ms(1);
trocaNum(m2, 4);
delay_ms(1);
 }
}

  Simulei no Proteus e roda bonitinho. (Daí fiz a plaquinha com base nesse circuito inclusive).. - Circuito no anexo

 

O que ocorre é que os números simplesmente não aparecem. E quando aparecem, aparecem errados. Modifiquei o código e testei o pic + cd + 1 display pra exibir um número qualquer na protoboard e não funcionou também. Suspeitei que era o PIC, coloquei um código besta no main() pra acender o led (mantive a configuração do Interrupt nela), e o pic simplesmente não me obedece! Se acende um led com uma porta, ao mesmo tempo, na outra porta acende fraquinho. Detalhe: o led configurado pra porta C5 pisca certinho, ligando e desligando conforme a função incSeg() (esse led vai ser pra piscar tipo aqueles 2 pontinhos que tem em relógios).

Resumindo: Se alguem puder me dar uma luz por gentileza... Já tentei configurar outros fuses e nada.. Testei o CD com fios, e indica o número certinho.

 

(Obs: Sou meio novato com pic's e por falta de dinheiro e tempo pra um curso, estudo com materiais livres na net e por fórums (aqui inclusive).. Se cometi algum erro ou puder existir algo pra melhorar o código acima, aceito críticas e sugestões.)

(Edit: Usei o CCS compiler, o PicKit 2 e o QSPICD pra gravar)

Obrigado dsd já!

 

circuito.jpg

Link para o comentário
Compartilhar em outros sites

6 horas atrás, Isadora Ferraz disse:

Ligou o reset? Pinos de mc tem múltiplas funções. Definiu previamente como a correta? No seu caso parece ser tudo IO.

Pro proteus não precisa mesmo mas falta resistor chute 1k na base dos bc's.

 

Opa, beleza?

Então, na hora de adicionar o código aqui, editei e fiz besteira, mas originalmente eu tinha configurado o #nomclr mas não estava funcionando mesmo assim (já tinha colocado porque de alguma forma sem esse fusível o proteus não simula nada).. Sobre os resistores eu adicionei na plaquinha física (1k inclusive kkk) mas obrigado pelo toque!

Será que teria algo a ver com o oscilador interno? Configurei errado? O delay() influencia (ou é influenciado) pelo interrupt?

Obrigado!

 

Link para o comentário
Compartilhar em outros sites

Consegui resolver o problema. Quem estiver com dificuldades idênticas, procure por RMW effect.. Pesquisei bastante, encontrei esse tema e li artigos sobre (Pelo que vi, tem um bug nos pic 16F, em relação ao "set" dos PORT's).O código que passei no primeiro Post é de minha autoria (tirando o trecho da trata_timer0 (o qual eu troquei posteriormente também, vou deixar o código abaxo)), mas quem quiser estudá-lo fique a vontade (pelo menos na parte da multiplex e no trato da hora parece que acertei kkk)

 

Código novo do TMR0:

#INT_TIMER0
void trataTimer ()
{
set_timer0(6); 
contador++;
  if (config == TRUE){
   if (contador == 125){
   ldStat = !ldStat;
   contador = 0;
   }
  }
  if (contador == 250)
  {
  incSeg();
  contador = 0;
  }
}

main(){
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);   
    set_timer0(6);  
    enable_interrupts (INT_TIMER0);
    enable_interrupts (GLOBAL);
//restante continua normal
}

Pode fechar o tópico...

Obrigado a todos!

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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

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