Ir ao conteúdo

Posts recomendados

Postado

Olá , estou tentando desenvolver um contador up/down com 2 displays de 7 segmentos, 2 CI 4511 utilizando o PIC16F628a   ,Uso o Mikro C e já iniciei mais estou tendo algumas dificuldades.

Gostaria que esse contador tivesse o limite superior no numero 60  e inferior no 00, depois vou querer gravar na eeprom do pic um valor selecionado, para isso vai ter uma tecla de gravação  e leitura.

até agora só conseguir a contagem crescente e mais nada.

Se alguém der uma luz eu agradeço.

void nibbleDown(char number);
void nibbleUp(char number);

char counter1 = 0, counter2 = 0;

void main()
{
   CMCON = 0x07;
   TRISA = 0b00000011;
   TRISB = 0x00;
   PORTA = 0x03;
   PORTB = 0x00;

   while(1)
   {
   
if(button(&porta,0,40,0))
{
     counter1++;


     nibbleDown(counter1);
     nibbleUp(counter2);

     if(counter1 == 10)
     {
      counter2++;
      counter1 = 0;
      nibbleDown(counter1);
      nibbleUp(counter2);
          if(counter2 == 10)
          {
            counter2 = 0;
            nibbleUp(counter2);
          }
     }

      delay_ms(300);

   }
}
}

void nibbleDown(char number)
{
  switch(number)
  {
     case 0:
       portb.f0= 0x00;
       portb.f1= 0x00;
       portb.f2= 0x00;
       portb.f3= 0x00;
       break;
     case 1:
       portb.f0= 0x01;
       portb.f1= 0x00;
       portb.f2= 0x00;
       portb.f3= 0x00;
       break;
     case 2:
       portb.f0= 0x00;
       portb.f1= 0x01;
       portb.f2= 0x00;
       portb.f3= 0x00;
       break;
     case 3:
       portb.f0= 0x01;
       portb.f1= 0x01;
       portb.f2= 0x00;
       portb.f3= 0x00;
       break;
     case 4:
       portb.f0= 0x00;
       portb.f1= 0x00;
       portb.f2= 0x01;
       portb.f3= 0x00;
       break;
     case 5:
       portb.f0= 0x01;
       portb.f1= 0x00;
       portb.f2= 0x01;
       portb.f3= 0x00;
       break;
     case 6:
       portb.f0= 0x00;
       portb.f1= 0x01;
       portb.f2= 0x01;
       portb.f3= 0x00;
       break;
     case 7:
       portb.f0= 0x01;
       portb.f1= 0x01;
       portb.f2= 0x01;
       portb.f3= 0x00;
       break;
     case 8:
       portb.f0= 0x00;
       portb.f1= 0x00;
       portb.f2= 0x00;
       portb.f3= 0x01;
       break;
     case 9:
       portb.f0= 0x01;
       portb.f1= 0x00;
       portb.f2= 0x00;
       portb.f3= 0x01;
       break;
  } //end switch

}


void nibbleUp(char number)
{
  switch(number)
  {
     case 0:
       portb.f4= 0x00;
       portb.f5= 0x00;
       portb.f6= 0x00;
       portb.f7= 0x00;
       break;
     case 1:
       portb.f4= 0x01;
       portb.f5= 0x00;
       portb.f6= 0x00;
       portb.f7= 0x00;
       break;
     case 2:
       portb.f4= 0x00;
       portb.f5= 0x01;
       portb.f6= 0x00;
       portb.f7= 0x00;
       break;
     case 3:
       portb.f4= 0x01;
       portb.f5= 0x01;
       portb.f6= 0x00;
       portb.f7= 0x00;
       break;
     case 4:
       portb.f4= 0x00;
       portb.f5= 0x00;
       portb.f6= 0x01;
       portb.f7= 0x00;
       break;
     case 5:
       portb.f4= 0x01;
       portb.f5= 0x00;
       portb.f6= 0x01;
       portb.f7= 0x00;
       break;
     case 6:
       portb.f4= 0x00;
       portb.f5= 0x01;
       portb.f6= 0x01;
       portb.f7= 0x00;
       break;
     case 7:
       portb.f4= 0x01;
       portb.f5= 0x01;
       portb.f6= 0x01;
       portb.f7= 0x00;
       break;
     case 8:
       portb.f4= 0x00;
       portb.f5= 0x00;
       portb.f6= 0x00;
       portb.f7= 0x01;
       break;
     case 9:
       portb.f4= 0x01;
       portb.f5= 0x00;
       portb.f6= 0x00;
       portb.f7= 0x01;
       break;
  } //end switch

}

 

Será que essa lógica é a melhor para se fazer isso? 

Até tentei fazer uma outra lógica fazendo sub_rotinas para cada numero apresentado no display, mais o programa fica muito grande

 

  • Membro VIP
Postado

Existem métodos um pouco  melhores que o seu e que usa meia dúzia de linhas e nem precisa de 4511. Envolve conceitos de interrupção e varredura. Infelizmente não consigo explicar rapidamente mas sei quem consegue...é ele mesmo!. Clique e confira

Esta blogueiro diz que fez em c mas infelizmente não conferi pra você ok?

http://larios.tecnologia.ws/iBlog/archives/2931

 

Postado

Obrigado Isadora, dei uma olhada no site e vi que a linguagem C  que ele usa é bem diferente do MIKRO C, algumas linhas até consigo entender, mais a maioria é bem confusa.

Estou pesquisando uma maneira mais simples de apresentar os números no display, da uma enxugada no código.

até consegui fazer para um display um código bem simples, o problema é colocar o segundo display.

 

#define  S2     porta.f0
#define  S1     porta.f1
#define  led2   porta.f2
#define  led1   porta.f3

void changeCont();                      //Muda o valor do contador
void gravaEEPROM();                     //Grava o valor atual do display da EEPROM


 int cont = 0x00;                      //cont incremento/decremento do display (dado a ser armazenado na EEPROM)

 unsigned char catodo;                 //catodo recebe o valor de cont

 unsigned char segmento[10] = {0x3f,   // display '0'
                               0x06,   // display '1'
                               0x5b,   // display '2'
                               0x4f,   // display '3'
                               0x66,   // display '4'
                               0x6d,   // display '5'
                               0x7d,   // display '6'
                               0x07,   // display '7'
                               0x7f,   // display '8'
                               0x67};  // display '9'

void main()
{

 CMCON = 0x07; //desabilita comparadores

 TRISA = 0x03;
 TRISB = 0x00; //todo PORTB configurado como saída
 PORTA = 0x03;
 PORTB = 0x00; //PORTB inicia em nível baixo

     cont = EEPROM_Read(0x00);

    while(1)
    {

        changeCont();

        if(!S2) gravaEEPROM();

        catodo = segmento[cont]; //numero a ser enviado para PORTB

        PORTB = catodo;          //envia pattern para PORT B

        delay_ms(100);

    } //end while

} //end void main

void changeCont()
{
   if(!S1)
   {
     cont++;
     delay_ms(100);

     if(cont > 0x09) cont = 0x00;

   }

} //end changeCont


void gravaEEPROM()
{
   EEPROM_Write(0x00, cont);
   delay_ms(10);
   led1 = 0x01;
   delay_ms(500);
   led1 = 0x00;
}

 

  • Curtir 1
  • Membro VIP
Postado
1 hora atrás, Jason Aspire disse:

o problema é colocar o segundo display.

Aí entra o conceito de varredura... algo como o dado é escrito bem rapidinho nos displays e você nem nota que está acendendo um de cada vez. Algo como...

display%207seg_3.png

http://pictronics.com.br/index.php?option=com_content&view=article&id=76:multiplexando-displays-de-7-segmentos-com-pic16f877a&catid=36

... pode lhe servir como introdução pois não é tão inteligente como o método que te disse ...

2 horas atrás, Isadora Ferraz disse:

conceitos de interrupção e varredura.

... por timer... Neste caso pode colocar quantos displays quiser. Lembrando que os segmentos estão em paralelo e apenas o catodo (ou anodo) comum são controlados por fora.

 

Imagine algo como escrever 34 no display

-ao passar pela interrupt você desliga RC7=0, coloca 0x4f, // display '3' = segmento[3] no port e aciona o display 1 RC6=1

-na próxima passada você desliga RC6=0, coloca 0x66, // display '4' = segmento[4] e liga RC7=1

 

 

Olha que fácil pra 8 displays algo como (digito on line...)

unsigned char display[],i=0,k=1;
...
interrupt void timer(void)
{
PORTB=segmentos[[display[i]];
PORTC=k;
i++; if (i>7) {i=0;k=1;}
k<<=1;
}
...
//34
display[0]=3;
display[1]=4;

 

Postado

Obrigado mais uma vez Isadora, entendi a lógica agora é tentar colocar em pratica, agora só mais uma coisa se possível? e nem sei se pode ser aqui ou tem que abrir outro tópico? E que é continuação desse projeto.

Estou tentando fazer tipo um elevador para peças , pretendo contar o curso do mesmo  por tempo, algo bem simples, um contador de segundos de no máximo 20 segundos por delay mesmo.

A contagem será só na subida, dai eu preciso salvar essa contagem na eeprom e quando ligar novamente e apertar a tecla busca ( busca de tempo/Posição)   ele vai ligar o motor pelo tempo salvo e parar na posição que eu salvei.

Consegui salvar numeros fiz com LCD  e deu certinho, mais e para ligar o motor ?  isso eu não consegui ainda.

 

 

int cont=0;
char texto[15];

void gravaEEPROM();                     //Grava o valor atual do display da EEPROM
void tela();

#define   grava    porta.f0
#define   inc      porta.f1

#define   led1     porta.f3


//******************************************************************************
void tela ()          // mostra o valor no LCD
{
inttostr(cont,texto);
lcd_out(2,4, texto);      // lcd_out(1,2,"SP");
LCD_Out(1,1, "Contador Pulsos");
}
//******************************************************************************
void main( )
{
cmcon=0x07;
trisa=0b00000111;
porta=0;
trisb=0;
portb=0;

LCD_Config(&portb,1,0,2,7,6,5,4);
LCD_Cmd(LCD_Cursor_Off);
LCD_Cmd(Lcd_Clear);
LCD_Out(1,1, "Contador Pulsos");

cont=0;
tela();

INICIO:;

while(1)
{
if (button(&porta,2,40,1)){      //volta a zero
porta.f7=1;
goto VOLTAZERO;
}
else
{
porta.f7=0;
}


if (button(&porta,1,40,1)){      //Incrementa +++++
goto INCREMENTA;
tela();
}

else
{
porta.f6=0;
}



if (button(&porta,0,40,1)&& (button(&porta,4,40,1))) {      //Grava Pos de trabalho
delay_ms(100);
gravaEEPROM();
cont=cont2;
}

else
{
}



if (button(&porta,0,40,1)){      //Busca posição
goto BUSCA;
tela();
}


}        //end while

//******************************************************************************
VOLTAZERO:;

while(1)
{
if(cont !=0){          //cont não vai abaixo de zero
if(cont>0)
{
cont=cont-1;
tela();
if(cont == 00 )
{
cont=0;
porta.f7=0;
tela();
goto INICIO;
}
}
}
delay_ms(1000);
}


//******************************************************************************
INCREMENTA:;

while(1)
{
porta.f6=1;                      //Sobe a badeja até o máximo
if(cont<20){
cont = cont+1;
tela();
delay_ms(500);
}

goto INICIO;
}

//******************************************************************************
BUSCA:;
while(1)
{
cont = EEPROM_Read(0x00);              //vai buscar valor salvo na memória
tela();                                //Mostra o valor no display
delay_ms(1000);                        //aguarda 1 segundo                                //Zera cont                                //Mostra no display que zerou
porta.f6=1;                            //liga o rele Sobe a badeja
if(cont < cont) {    //
cont = cont+1;
tela();
}
if (cont==cont){
porta.f6=0;
goto INICIO;
}
delay_ms(1000);
}


//******************************************************************************
}     //end main

//******************************************************************************
void gravaEEPROM()
{
   EEPROM_Write(0x00, cont);
   delay_ms(10);
   led1 = 0x01;
   delay_ms(500);
   led1 = 0x00;
   delay_ms(2000);
}

 

  • Membro VIP
Postado
15 horas atrás, Jason Aspire disse:

Consegui salvar numeros fiz com LCD  e deu certinho, mais e para ligar o motor ? 

você já tem a faca e o queijo na mão. Apenas grave o valor do tempo do motor em endereço difernte uai...

 

15 horas atrás, Jason Aspire disse:

while(1) { cont = EEPROM_Read(0x00); //vai buscar valor salvo na memória

e a busca nao precisa estar dentro do loop. Coloque na inicialização antes do main()... Percebo agora vários loops.. Isso não é totalmente bom. Tenta dar uma revisada/estudada nos princípios  fundamentais do C. P.ex. crie funções dentro de um loop só.
 

for(;;) //o mesmo que while(1)
{
if (x) funcx();
func1();
i++;
func2(2,i);
delay(y);
//etc
}

Nem vai precisar do confuso goto

  • 3 semanas depois...
Postado

Dando uma posição sobre o meu programa, eu  resolvi fazer com LCD mesmo.

E consegui salvar o tempo e uma segunda variável para poder ligar o motor.

Mais uma vez eu agradeço a Isadora que me ajudou.

 

segua o código ja funcionando.

char texto[15];

int temp_motor=0;             //Variavél de contagem do tempo do motor
int cont=0;                   //Variavél de contagem de tempo auxiliar

void gravaEEPROM();           //Grava o valor atual do display da EEPROM
void tela();                  //Mostra o valor no Display LCD

#define   pos_trab   porta.f0   //Tecla posição de trabalho
#define   inc        porta.f1   //Tecla incrementa

#define   buzzer     porta.f3   //Saida do Buzzer
#define   rele_sobe  porta.f6   //Rele sobe motor
#define   rele_desce porta.f7   //Rele desce motor

//******************************************************************************
void tela ()          // mostra o valor no LCD
{
inttostr(cont,texto);
lcd_out(1,10, texto);
LCD_Out(1,1, "Cont");


inttostr(temp_motor,texto);
lcd_out(2,10, texto);
LCD_Out(2,1, "Motor");
}
//*****************************************************************************
void main( )
{
cmcon=0x07;
trisa=0b00000111;
porta=0;
trisb=0;
portb=0;

LCD_Config(&portb,1,0,2,7,6,5,4);
LCD_Cmd(LCD_Cursor_Off);
LCD_Cmd(Lcd_Clear);


temp_motor=0;
cont=0;
tela();

//*****************************************************************************
INICIO:;

while(1)
{
if (button(&porta,2,40,1)){      //Tecla retorna a zero
delay_ms(100);
porta.f7=1;
goto VOLTAZERO;
}
else
{
porta.f7=0;
}


if (button(&porta,1,40,1)){      //Incrementa +++++
delay_ms(100);
goto INCREMENTA;
}

else
{
porta.f6=0;
}



if (button(&porta,0,40,1)&& (button(&porta,4,40,1))) {  //Grava Pos de trabalho
delay_ms(100);
gravaEEPROM();
}

else
{
}

if (button(&porta,0,40,1)){      //Busca posição que foi gravada
delay_ms(100);
goto BUSCA;
tela();
}

}        //end while
//******************************************************************************
VOLTAZERO:;

while(1){
cont=0;
temp_motor=0;
tela();
cont=20;
tela();
porta.f7=1;                   //Liga desce bandeja


while(1)
{
delay_ms(1000);
if (cont > 0)            // 20 segundos
{
cont = cont-1;
tela();
if(cont == 0)
{
cont=0;
temp_motor=0;
porta.f7=0;
tela();
goto INICIO;
}
}
//delay_ms(1000);
if (button(&porta,2,40,1))   //Tecla volta zero
{
goto EMERGENCIA;
}
}
}
//******************************************************************************
INCREMENTA:;

while(1)
{
porta.f6=1;                      //liga o rele sobe bandeja
if(cont<20 && temp_motor<20) {
cont = cont+1;
temp_motor=temp_motor+1;
tela();
delay_ms(1000);
}
goto INICIO;
}

//******************************************************************************
BUSCA:;

while(1)
{
cont = EEPROM_Read(0x00);           //vai buscar valor salvo na memória  `0´

temp_motor= EEPROM_Read(0x09);     //Vai buscar valor salvo na memória `9´
tela();                             //Mostra o valor no display

delay_ms(1000);                     //Aguarda 1 segundo
cont=0;                             //Zera cont
tela();                             //Mostra no display cont zerado

while(1)
{
delay_ms(1000);
if (cont < temp_motor )
{
porta.f6=1;                         //Liga o rele sobe Bandeja
cont = cont+1;
tela();
if (cont == temp_motor)
{
porta.f6=0;
goto INICIO;
}
}
//delay_ms(1000);
}
}
//******************************************************************************
EMERGENCIA:;

cont =0;
temp_motor=0;
porta.f7=0;
delay_ms(3000);
goto INICIO;

//*****************************************************************************

}     //end main

//******************************************************************************
void gravaEEPROM()
{
   EEPROM_Write(0x00, cont);
   delay_ms(10);
   EEPROM_Write(0x09,temp_motor);
   delay_ms(10);
   buzzer = 0x01;
   delay_ms(2000);
   buzzer = 0x00;
   delay_ms(2000);
}

 Jason Aspire

 Autor do tópico

Membros Juniores

 1

3 posts

desde 01/04/2020

 

Denunciar post

 

 

#5  

Postado 3 de abril

Obrigado mais uma vez Isadora, entendi a lógica agora é tentar colocar em pratica, agora só mais uma coisa se possível? e nem sei se pode ser aqui ou tem que abrir outro tópico? E que é continuação desse projeto.

Estou tentando fazer tipo um elevador para peças , pretendo contar o curso do mesmo  por tempo, algo bem simples, um contador de segundos de no máximo 20 segundos por delay mesmo.

A contagem será só na subida, dai eu preciso salvar essa contagem na eeprom e quando ligar novamente e apertar a tecla busca ( busca de tempo/Posição)   ele vai ligar o motor pelo tempo salvo e parar na posição que eu salvei.

Consegui salvar numeros fiz com LCD  e deu certinho, mais e para ligar o motor ?  isso eu não consegui ainda.

 

 

 

  • Curtir 1

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!