Ir ao conteúdo
  • Cadastre-se

Comportamento estranho da função delay!


Posts recomendados

Boa tarde amigos!

 

Recentemente eu comecei a usar a linguagem C para programar microcontroladores PIC. Estou utilizando o mplabX 3.40 junto com o compilador xc8 v1.38, ambos são as versões mais atualizadas desses programas! O código abaixo é para fazer um led blinking.

 

O problema é que a função "__delay_ms()" deveria fazer o uC esperar por "x" milissegundos, tal que 0 <= x <= 192, e no meu caso ela está fazendo o uC ficar um tempo muito superior a isso.

Repare que passando o valor 5 como argumento da função o meu led oscila aproximadamente em 1 segundo. Eu quero entender esse "bug" ,mas está difícil...

Eu já li o manual do compilador e vi que esse calculo é feito com base no #define do _XTAL_FREQ.

Eu já testei outras formas de delay como o "_delay()" que é equivalente ao NOP(); e em todos esses casos o delay é muito maior que o tempo que deveria ser

 

obs: Estou utilizando o pic18f1220, oscilador interno. 

 

#include <xc.h>
#define _XTAL_FREQ 4000000

void main(void) {
    TRISBbits.RB7 = 0x00;
    PORTBbits.RB7 = 0x00;
    while(1){
        
       PORTBbits.RB7 = !PORTBbits.RB7; // inverte rb7
       __delay_ms(5); 
    }
}

 

Link para o comentário
Compartilhar em outros sites

Olá amigo!

Segue o código completo! Implicitamente o mplabx ja faz o "include" de pic utilizado. Estou utilizando o oscilador interno de 4mhz do pic

 

// PIC18F1220 Configuration Bit Settings

// CONFIG1H
#pragma config OSC = INTIO2     // Oscillator Selection bits (Internal RC oscillator, port function on RA6 and port function on RA7)
#pragma config FSCM = ON        // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal External Switchover mode enabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON         // Brown-out Reset Enable bit (Brown-out Reset enabled)
// BORV = No Setting

// CONFIG2H
#pragma config WDT = ON         // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled, RA5 input pin disabled)

// CONFIG4L
#pragma config STVR = ON        // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Low-Voltage ICSP Enable bit (Low-Voltage ICSP enabled)

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (00200-0007FFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (000800-000FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (00200-0007FFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (000800-000FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (00200-0007FFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (000800-000FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from table reads executed in other blocks)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#define _XTAL_FREQ 4000000

void main(void) {
    TRISBbits.RB7 = 0x00;
    PORTBbits.RB7 = 0x00;
    while(1){
        
       PORTBbits.RB7 = !PORTBbits.RB7; // inverte rb7
       __delay_ms(5); 
    }
}

Eu estou baixando um versão mais antiga do compilador para ver se resolver meu problema

 

Edit: Acabei de testar com a versão 1.35 do compilador xc8 e o problema persiste :(

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

ok

 

-mplab

-rode passo a passo inicialmente pra você sentir algo das entranhas do pic

-ache a função _delay e coloque um break point no começo e final dela com 5 ms como argumento

-mande rodar

-verifique quantos ciclos de máquina ocorreram e calcule se o tempo foi 5ms

-Também pode usar o logic analizer (ou algo assim) e verificar os pulsos do seu port

 

Mais opções:

 

-Crie seu próprio delay algo como

void delay(unsigned int d) //coloque um valor qualquer...

{

while (d--); //e verifique o tempo desta iteração com a técnica citada acima

}

-Use os timer´s

 

de nada...

adicionado 12 minutos depois

Ah sim, se for problema no hw, como pino de reset aberto, falha na alimentação, etc, receba um cascudo virtual.

Também observe o watch dog

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

Olá amigo. Eu uso o mplabx também e eu sempre declaro qual o pic que estou usando no código.

Uso os fuses que ele gera só pra ter uma referência, mas geralmente eu que escrevo tudo.

Experimente fazer dessa rdem:

 

#include <pic18f1220.h>

#include <xc.h>

 

#pragma config

#pragma config  // aqui você coloca os fuses

#pragma config

 

#define _XTAL_FREQ 4000000

 

Já passei por esse tipo de problema e era essa ordem que me atrapalhava.

 

Outra coisa: Se não funcionar, tenta substituir a linha #define _XTAL_FREQ 4000000 por: 

 

OSCCONbits.IRCF2 = 1;

OSCCONbits.IRCF1 = 1;

OSCCONbits.IRCF0 = 0;

 

Isso faz tu configurar direto no registrador do oscilador interno para 4MHZ. 

Dá uma olhada no diagrama em blocos desse pic: Temq ue fazer configuração de postscaler do oscilador interno.

Diagrama-blocos-oscilador-696x761.jpg

Tu tem que configurar o postscaler. 

Não consegui ver a fundo porque estou na correria. Mas tente fazer com oscilador externo e ver se funciona, é uma opção.

 

 

 Abraço

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

funcionou pourra!!!!!!!!!!!!!

 

eu realmente esqueci do configurar o OSCCON.

 

eu configurei o byte inteiro  para "OSCCON = 0b01100000"

 

agora deu certo :)

 

O lado bom é que eu aprendi que sempre devemos ler atentamente o datasheet o integrado que vamos utilizar.

 

Obrigado a todos que quiseram me ajudar!

 

 

@Rafael Del Pino te amo  (sem veadagi)

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

Visitante
Este tópico está impedido de receber 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...