Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

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

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 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 às perguntas 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.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Entre para seguir isso  
Joao Fabri

Varredua de botões por Interrupção PIC16F883

Recommended Posts

Bom dia, estou desenvolvendo um código para incrementar a contagem em um display de 7 segmentos a cada vez que o botão B1 for pressionado, para otimizar meu código eu decidi fazer a varredura dos botões através das interrupções, então em um tempo de aproximadamente 20ms eu testo meu botão B1 através do estouro do TMR0... porém como nunca é do jeito que a gente quer meu código não esta rodando perfeitamente no protheus, alguém sugeri o motivo ? Segue código comentado...

 

unsigned char catodo, cont = 0x00;       // variaveis auxiliares
 unsigned char segmento[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};   // vetor para display 7seg

 void interrupt ()
 {
 if (T0IF_bit)                                      // testa flag de estouro tmr0
 {
  T0IF_bit = 0;                                     // limpa flag
  TMR0 = 0xA0;                                      // inicia tmr0 em   160

 if (B1 == 0)                                       // se b1 pressionado...
  {
  cont ++;                                          // cont ++
  Delay_ms(150);
  }
  }
  }


 

void main ()
{
OPTION_REG =   0b10000110;      // Desabilitando resistores de puldow, oscilador interno, prescaller 1:256
TMR0  = 0xA0;                   // inicia tmr0 160
INTCON.GIE = 1;                 // habilita interrupçao global
INTCON.PEIE = 1;                // habilita interrupçao por perifericos internos
INTCON.T0IE = 1;                // habilita interrupçao por estouro timer 0


TRISE = 0b00001000;
TRISC = 0b00000000;
TRISB = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00100000;
PORTE = 0b00001000;

   while (1)
{

    catodo = segmento [cont];         // atribui o vetor segmento com o parametro cont há variavel catodo
    PORTB = catodo;
     if (cont > 9)                    // limite de contagem ate 9
    {
    cont = 0;
    }

}
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tá não entendi muito bem o seu código. Tem um erro ai no mínimo:

TRISB = 0b00000000; isso define todas as portas como saída e você disse que B1 é uma das portas. se B1 é entrada* então ficaria TRISB = 0b00000010;

 

Se você olhar no datasheet do teu mic e olhar no PORTB registradores você vai ver que terá que alterar ANSELH = 0; ou os bits que você que sejam apenas entra e saída (você coloca isso no void principal). Isso se deve novamente ao fato do PORTB poder ser configurado como entrada e saída ou analógico.

 

Se ainda tiver mais problema no teu código avisa que posso dar uma outra olhada.

Editado por Bommu Perneta

Compartilhar este post


Link para o post
Compartilhar em outros sites

Além disso....

Do jeito que você fez pode ocorrer que não leia o botao no momento da interrupt. Faça interrupt por mudança de estado de pino ou simplesmente while(B1);cont++;while(!B1);

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • Autor do tópico
  • @Bommu Perneta  na verdade eu não copiei a parte das diretivas ''B1'' é na verdade RB3_bit, e eu não entendi muito bem o lance sobre ANSELH, este registrador não configura apenas os pinos do PORTA se eles sarão analógicos ou digitais ?

    adicionado 1 minuto depois

    @Isadora Ferraz poderia ser mais especifica como eu deveria mudar minha logica ??

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Que vê dá procura na net pelo datasheet do mesmo, dá um ctrl+F no pdf e procurar por PORTB vai indo até encontrar a parte de dos registradores, e procura por essa palavra por lá ^^ você pode fazer um exemplo simples no proteus

     

    Pagina 49 do PDF do datasheet


     

    Citação

     

    "

    3.4.1

    ANSELH REGISTER

    The ANSELH register (Register 3-4) is used to

    configure the Input mode of an I/O pin to analog.

    Setting the appropriate ANSELH bit high will cause all

    digital reads on the pin to be read as ‘

    0

    ’ and allow

    analog functions on the pin to operate correctly.

    The state of the ANSELH bits has no affect on digital

    output functions. A pin with TRIS clear and ANSELH

    set will still operate as a digital output, but the Input

    mode will be analog. This can cause unexpected

    behavior when executing read-modify-write

    instructions on the affected port."

     

     

    Página 50 do datasheet


     

    Citação

     

    "ANSELH: ANALOG SELECT HIGH REGISTER

    bit 7-6

    Unimplemented:

    Read as ‘

    0

    bit 5-0

    ANS<13:8>

    : Analog Select bits

    Analog select between analog or digital function on pins AN<13:8>, respectively.

    1

    = Analog input. Pin is assigned as analog input

    (1)

    .

    0

    = Digital I/O. Pin is assigned to port or special function.

    Note 1:

    Setting a pin to an analog input automatically disables the digital input circuitry, weak pull-ups, and

    interrupt-on-change if available. The corresponding TRIS bit must be set to Input mode in order to allow

    external control of the voltage on the pin.

    "

     

     

    Abaixo Eu só comentei teu código

    //// unsigned char catodo, cont = 0x00;       // variaveis auxiliares
    ///unsigned char segmento[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};   // vetor para display 7seg
    /*
     void interrupt ()
     {
     if (T0IF_bit)                                      // testa flag de estouro tmr0
     {
      T0IF_bit = 0;                                     // limpa flag
      TMR0 = 0xA0;                                      // inicia tmr0 em   160
    
     if (B1 == 0)                                       // se b1 pressionado...
      {
    //  cont ++;                                          // cont ++
      Delay_ms(150);
      }
      }
      }
    
      */
    
    
    void main ()
    {
    /*
    OPTION_REG =   0b10000110;      // Desabilitando resistores de puldow, oscilador interno, prescaller 1:256
    TMR0  = 0xA0;                   // inicia tmr0 160
    INTCON.GIE = 1;                 // habilita interrupçao global
    INTCON.PEIE = 1;                // habilita interrupçao por perifericos internos
    INTCON.T0IE = 1;                // habilita interrupçao por estouro timer 0
      */
    
    TRISE = 0b00001000;
    TRISC = 0b00000000;
    TRISB = 0b00000010;
    PORTB = 0b00000000;
    PORTC = 0b00100000;
    PORTE = 0b00001000;
    
    ANSELH = 0;       // retirar do analog.
    
       while (1)
    {
    
      if (PORTB.B1==1){PORTB.B2=1; delay_ms(500);}
       PORTB.B2=0;
    /*  PORTB.B0=0;
       delay_ms(500);
      PORTB.B0=1;
       delay_ms(500);
       PORTB.B2=1;
      */
    
    }
    }

    Se você você retirar esse comando o programa que lé o botão no Proteus não vai funcionar, a lógica pelo menos.

     

    Capturar.PNG.faace9f1ea5c54b26e5e21f20f66108d.PNG

     

    adicionado 1 minuto depois

    Ta uma ***** a passagem do texto, melhor ler no datasheet uhahuauhahu

    adicionado 5 minutos depois

    http://ww1.microchip.com/downloads/en/DeviceDoc/41291B.pdf

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • meu codigo esta assim agora, esta funcionando normalmente no protheus a cada pressionada do botão e incrementa um valor no display, porém o led que esta ligado ao pino RB7 nunca acende, este pino independente do de qualquer coisa so esta ficando em nivel baixo... Segue o codigo 

     

     

    #define B1 RE3_bit


     unsigned char catodo, cont = 0x00;       // variaveis auxiliares
     unsigned char segmento[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};   // vetor para display 7seg

     void interrupt ()
     {
     if (T0IF_bit)                                      // testa flag de estouro tmr0
     {
      T0IF_bit = 0;                                     // limpa flag
      TMR0 = 0x00;
      if (B1 == 0)
     {
       cont ++;
       Delay_ms(250);


     }                                    // inicia tmr0 em   160
     }
     }


     

    void main ()
    {
    OPTION_REG =   0b10000111;      // Desabilitando resistores de puldow, oscilador interno, prescaller 1:256
    TMR0  = 0x00;                   // inicia tmr0 em 0
    INTCON.GIE = 1;                 // habilita interrupçao global
    INTCON.PEIE = 1;                // habilita interrupçao por perifericos internos
    INTCON.T0IE = 1;                // habilita interrupçao por estouro timer 0


    TRISE = 0b00001000;
    TRISB = 0b00000000;
    PORTB = 0b00000000;
    PORTE = 0b00001000;
    ANSELH = 0;
     while (1)
    {

        catodo = segmento [cont];         // atribui o vetor segmento com o parametro cont há variavel catodo
        PORTB = catodo;
         if (cont > 9)                    // limite de contagem ate 9
        {
        cont = 0;
        }

    }
    }

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    É esse linha aqui

    PORTB = catodo;

    Ele tá modificando essa porta para 0 . Ele está no while, fora do botão e repetindo toda hora... ou seja vai ficar zero todo o tempo..

    adicionado 14 minutos depois

    unsigned char segmento[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};

     

    de hexadecimal binário

    0xF3 = 00111111

    0x06= 00000110

    0x5b= 01011011

    0x4f= 01001111

    0x66=01100110

    0x6d=01101101

    0x7d=01111101

    0x07=00000111

    0x7f=01111111

    0x67=01100111

     

    Sendo que da esquerda para direita cada digito do binário que são 8 nesse caso são as porta do PORTB segundo o código, onde ficamos respectivamente B7,B6,B5,B4,B3,B2,B1,B0 e note que todo tempo o primeiro que seria o B7 fica todo tempo em 0, logo desligado. Está ai uma explicação.

     

    @Joao Fabri

     

     

    Editado por Bommu Perneta

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • @Bommu Perneta nossa é verdade, e no meu hardware sem querer eu estava usando o pino G do display no pino RB7 invés de RB6 por isso não ascendia... Cara agora eu tenho uma outra duvida sobre esse meu mic, eu acompanho wr kits no youtube e la ele sempre desliga os comparadores qundo não vai usar através do comando CMCON = 0x07 mas quando vou tentar colocr isso no meu codigo ele da erro, sera que meu mic em questão usa um registrador diferente para tratar os compardores ?? Obrigado

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Depende da versão que você usa do teu mikroC Pro...por exemplo, a versão que ele usa parece bem diferente da minha, muitos registradores parecem diferentes do que uso, se você for desativar um "com nome semelhante" teu proteus ou mic não funciona... então tem que ser o nome exato que ele fala, se não tiver o mesmo nome exato você pode tentar adaptar e trocar um, desligar outro e vai vendo o que funciona no seu caso.

    adicionado 0 minutos depois

    ah... pelo que vejo o curso dele é bom.

    adicionado 4 minutos depois

    Ah não se esqueça que precisa alimentar o pic, dependendo pode colocar cristal e tal. ^^ deixar em alto com um resistor de 10k o reset e por ai vai... tudo pode dar erro ^^

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    13 horas atrás, Joao Fabri disse:

    como eu deveria mudar minha logica ??

    Tentemos...

     

    Pelo que entendi você lê o status do botão a cada 20mS usando o timer só pra isso. Isso não é necessário. Use o timer pra algo mais nobre e coerente com seu nome. Se você programar uma interrupção por mudança de estado da entrada, já lhe é suficiente. Hás de ler o datasheet pra ver como programar o pino pra isso.

     

    Eis o modo que "simula" uma interrupção por sw por mudança de estado. É auto explicativo pra um programador mediano em c
     

    while (1)
    {
        catodo = segmento [cont];         // atribui o vetor segmento com o parametro cont há variavel catodo
        PORTB = catodo;
    while(B1);while(!B1); //<<===
    cont++;
         if (cont > 9)                    // limite de contagem ate 9
        {
        cont = 0;
        }
    }

    No proteus deve funcionar. Na prática, hás de ser apresentado ao termo debouncing

    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    Em 24/07/2017 às 07:36, Isadora Ferraz disse:

    No proteus deve funcionar. Na prática, hás de ser apresentado ao termo debouncing

     

    Pior que é verdade !

     

    Paulo

    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

    Entre para seguir isso  





    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

    ×