Tag: PIC18F4550

Palavra-chave
Destaque/Sem destaque
Resolvida/Não Resolvida
Aberta/Encerrada
0 votos
930 visualizações

Ola Pessoal eu gostaria de vossa ajuda.
Eu sou iniciante a programar micro-controladores, e estou programando o micro de 8bits da familia 18f no Mplab x, e estou tendo dificuldades nisso.
EU fiz o código para a livraria do C18, compilou sem erro, mas não está simulando no Proteus.
Por isso tentei mudar para livraria XC8, mas essa livraria n encontrei a biblioteca para LCD e nem Biblioteca pra Delays, passei pela google, dei varias pesquisadas, e nada parece tar resolvendo o meu problema, gostaria que pudessem me ajudar a solucionar esse problema:
Ai tem o código abaixo para o C18.

#include <p18f4550.h>
#define _XTAL_FREQ = 20000000
#pragma config MCLRE = OFF, LVP = OFF, WDT = OFF, PLLDIV = 5, CPUDIV = OSC1_PLL2
#pragma config FOSC = HS, PBADEN = OFF, XINST = OFF
#include <delays.h>
#include <xlcd.h>

void DelayFor18TCY( void )
{
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
  Nop();
}
void DelayPORXLCD (void)
{
  Delay1KTCYx(75); // Delay of 15ms
                   // Cycles = (TimeDelay * Fosc) / 4
                   // Cycles = (15ms * 20MHz) / 4
                   // Cycles = 75,000
  return;
}
void DelayXLCD (void)
{
  Delay1KTCYx(25); // Delay of 5ms
                   // Cycles = (TimeDelay * Fosc) / 4
                   // Cycles = (5ms * 20MHz) / 4
                   // Cycles = 25,000
  return;
}
void Init_lcd(void){
    OpenXLCD( EIGHT_BIT & LINES_5X7 );
    while( BusyXLCD() );
    WriteCmdXLCD( EIGHT_BIT & LINES_5X7 );
    WriteCmdXLCD( BLINK_ON );
    WriteCmdXLCD( SHIFT_DISP_LEFT );
}

void main(void) {
    TRISD = 0x00;
    OSCCONbits.IRCF=0b1110;
    OSCCONbits.SCS=0b00;
    ADCON1bits.PCFG0=0b0000;

    Init_lcd();
    putrsXLCD( "Hello World" );
    SetDDRamAddr(0x40);
    while(1){
    LATDbits.LATD0 = 0xff;
    Delay10KTCYx(75);
    LATDbits.LATD0 = 0x00;
    Delay10KTCYx(75);
    }

}

Poderiam me ajudar por favor!

0 votos
0 respostas
3k visualizações

Opa!

estou enfrentando um problema que é, como posso dizer, esquisito.

Tenho uma aplicação que faz uso do Timer 0 para algumas operações de timming (dã) através de interrupções.

Abaixo segue o código da ISR do timer:


interrupt high_priority void isrTIMER0(void)
{
    if ( INTCONbits.TMR0IF )
    {
        TMR0H = wReloadTimer[TIMER0] >> 8;
        TMR0L = (uint8_t)wReloadTimer[TIMER0];
        PORTAbits.RA2 ^= 1;

        (tcb[TIMER0])(); // call the timer0 callback function

        INTCONbits.TMR0IF = 0;
    }
}

E a seguir temos a configuração do timer 0:


    INTCONbits.GIE = 0;

    //! configure the timer 0 for 16 bit mode and preescaler of 1/256
    T0CONbits.TMR0ON    = TMR0ON_OFF;           //! turn off
    T0CONbits.T08BIT    = T08BIT_LEN_16;        //! select the 8 bit mode
    T0CONbits.T0CS      = T0CS_INT;             //! internal clock 
    T0CONbits.PSA       = PSA_PREESC_ASSIGN;    //! use the preescaler
    T0CONbits.T0PS      = T0PS_PREESC_1_2;      //! 1/2 preescaler

    INTCON2bits.TMR0IP = 1;                     //! high priority for TMR0 interruption

    INTCONbits.TMR0IF   = 0;                    //! clear the interrupt flag
    INTCONbits.TMR0IE   = 1;

    TMR0        = 0;

    wReloadTimer[TIMER0] = (WORD)(-100);

    TMR0        = wReloadTimer[TIMER0];

    T0CONbits.TMR0ON = TMR0ON_ON;            //! turn on

Enfim… com isso eu sei que o timer 0 está configurado como 16 bits, com clock interno, preescaler de 1:2 e recarga de -100, gerando interrupções a cada 100 us.

O timer está gerando a interrupção e aqui que ocorre a coisa estranha: o PIC não realiza a escrita dos valores de recarga no registro TMR0, conforme é intuido pelas instruções abaixo:

        TMR0H = wReloadTimer[TIMER0] >> 8;
        TMR0L = (uint8_t)wReloadTimer[TIMER0];

Fiquei aqui pensando, pensando, pensando e não cheguei a conclusão nenhuma.
Olhe o que ocorre observando com o debuger:

Entrada na ISR do Timer 0

Aqui podemos ver que o registro TMR0 possui o valor 0x0012 e a posição 0 do vetor wReloadTimer está com o valor de recarga 0xFF9D (-100).

O esperado é que, ao executar as próximas duas linhas, o registro TMR0 tenha o valor 0xFF9D. Observe o que ocorre na próxima figura:

Após "escrever" TMR0

Reparou que o valor de TMR0 é 0x009D?
Isso quer dizer que somente TMR0L foi alterado. Porque?
Não sei…

é isso que eu gostaria de saber. Alguém aqui já passou por isso?
Sempre que utilizei o timer 0 foi com 8 bits, nunca precisei ou me atentei a esta configuração de 16 bits…

muito obrigado!

  • Rafael Dias perguntada 3 anos atrás
  • última atividade 3 anos atrás
0 votos
0 respostas
2k visualizações

Olá!

Estou fazendo alguns testes com interrupções com o XC8 e acabei observando um fenômeno interessante relaionado ao salvamento de contexto em ISRs.

Na aplicação que estou realizando de um PIC18F4550 tenho que realizar o tratamento da interrupção do TIMER 0. A interrupção do timer 0 é tão simples quanto isso:


interrupt high_priority void isrTIMER0(void)
{
    if ( INTCONbits.TMR0IF )
    {
        TMR0H = wReloadTimer[TIMER0] >> 8;
        TMR0L = (uint8_t)wReloadTimer[TIMER0];
        PORTAbits.RA2 ^= 1;

        (tcb[TIMER0])(); // call the timer0 callback function

        INTCONbits.TMR0IF = 0;
    }
}

O código assembly gerado para esta ISR ficou assim:

opt stack 21 pop ; remove dummy address from shadow register refresh
movff fsr0l,??_isrTIMER0+2
movff fsr0h,??_isrTIMER0+3
movff fsr1l,??_isrTIMER0+4
movff fsr1h,??_isrTIMER0+5
movff fsr2l,??_isrTIMER0+6
movff fsr2h,??_isrTIMER0+7
movff prodl,??_isrTIMER0+8
movff prodh,??_isrTIMER0+9
movff tblptrl,??_isrTIMER0+10
movff tblptrh,??_isrTIMER0+11
movff tblptru,??_isrTIMER0+12
movff tablat,??_isrTIMER0+13

;p18f_timer.c: 124: if ( INTCONbits.TMR0IF )
btfss intcon,2,c ;volatile
goto i2l578

;p18f_timer.c: 125: { ;p18f_timer.c: 131: TMR0L = (uint8_t)-10;
movlw 246
movwf 4054,c ;volatile

;p18f_timer.c: 132: PORTAbits.RA2 ^= 1;
btg 3968,2,c ;volatile

;p18f_timer.c: 134: (tcb[TIMER0])();
call i2u231_48
goto i2l3697
i2u231_48: push
movwf pclath,c
movf _tcb,w,c
movwf tosl,c
movf _tcb+1,w,c
movwf tosh,c
movf tblptru,w,c
movwf tosu,c
movf pclath,w,c
return ;indir i2l3697:

;p18f_timer.c: 136: INTCONbits.TMR0IF = 0;
bcf intcon,2,c ;volatile
i2l578: movff ??_isrTIMER0+13,tablat
movff ??_isrTIMER0+12,tblptru
movff ??_isrTIMER0+11,tblptrh
movff ??_isrTIMER0+10,tblptrl
movff ??_isrTIMER0+9,prodh
movff ??_isrTIMER0+8,prodl
movff ??_isrTIMER0+7,fsr2h
movff ??_isrTIMER0+6,fsr2l
movff ??_isrTIMER0+5,fsr1h
movff ??_isrTIMER0+4,fsr1l
movff ??_isrTIMER0+3,fsr0h
movff ??_isrTIMER0+2,fsr0l
movff ??_isrTIMER0+1,pclatu
movff ??_isrTIMER0,pclath
bcf btemp,1,c ;clear compiler interruptflag (level 2)
retfie f

Observe que na entrada e na saída da ISR o compilador salva e depois recupera algumas variáveis internas:

movff fsr0l,??_isrTIMER0+2
movff fsr0h,??_isrTIMER0+3
movff fsr1l,??_isrTIMER0+4
movff fsr1h,??_isrTIMER0+5
movff fsr2l,??_isrTIMER0+6
movff fsr2h,??_isrTIMER0+7
movff prodl,??_isrTIMER0+8
movff prodh,??_isrTIMER0+9
movff tblptrl,??_isrTIMER0+10
movff tblptrh,??_isrTIMER0+11
movff tblptru,??_isrTIMER0+12
movff tablat,??_isrTIMER0+13




i2l578: movff ??_isrTIMER0+13,tablat
movff ??_isrTIMER0+12,tblptru
movff ??_isrTIMER0+11,tblptrh
movff ??_isrTIMER0+10,tblptrl
movff ??_isrTIMER0+9,prodh
movff ??_isrTIMER0+8,prodl
movff ??_isrTIMER0+7,fsr2h
movff ??_isrTIMER0+6,fsr2l
movff ??_isrTIMER0+5,fsr1h
movff ??_isrTIMER0+4,fsr1l
movff ??_isrTIMER0+3,fsr0h
movff ??_isrTIMER0+2,fsr0l
movff ??_isrTIMER0+1,pclatu
movff ??_isrTIMER0,pclath
bcf btemp,1,c ;clear compiler

São 12 instruções na entrada da ISR e 12 na saída. 24 instruções por ISR!!!!

Quando trabalhei com o C18 havia um #pragma especial para este tipo de situação. Com este pragma era possível escolher o que o compilador iria salvar ou não.

Realizei a leitura do user guide do xc8 e não encontrei nada referente a isso.

Agora vem a pergunta: Qual é a necessidade disso?
Para timers pode não ser tão crítico (porém já é), mas imagina uma situação de comunicação serial de alta velocidade. Se o microcontrolador perder 15 ciclos de clock com cada interrupção gerada, teremos um baudrate máximo que poderá ser alcançada pela a comunicação, sendo que esse gargalo é somente por overhead de tratamento de interrupção.

Alguém sabe como posso instruir o compilador o que salvar na interrupção?

grato!

  • Rafael Dias perguntada 3 anos atrás
  • última atividade 3 anos atrás
0 votos
3k visualizações

Colegas.
Estou desenvolvendo um projeto com o PIC18F26J50.

É um projeto legado onde estou implementando o firmware e não tenho que trabalhar com o hardware que me foi dado.

Basicamente é um sistema que realiza a leitura de dois sensores analógicos, aplica um filtro e disponibiliza esses dados através de um protocolo proprietário sobre RS-485.

Como estou sem o hardware em mãos (mais essa), estou realizando os testes de algoritmos em uma uStart (do nosso amigo Marcos Ribeiro), mesmo que seja um processador diferente, mas estou fazendo…

A minha pergunta é relacionada ao clock. O hardware que será construído não utiliza cristal. Estou utilizando o oscilador interno. Ontem fui medir indiretamente a frequência de operação do PIC, utilizando um interrupção de timer e um gpio, e notei uma discrepância de mais ou menos 20% na frequência de geração da interrupção do Timer0. Conferi toda a configuração do mesmo e está correto.

Gostaria de saber de vocês qual é a precisão do oscilador interno e se este tipo de configuração é adequada a um ambiente com um considerável spam de temperatura e que tenha necessidade de comunicação via interface serial, que pode ser bem sensível à variações de clock.

Cheguei a ler sobre isso no datasheet e a impressão que tive é de que não teria muitos problemas.

Ontem ao medir os tempos e perceber o desvio da frequência observada através da interrupção em relação ao esperado, fiquei ressabiado.

Muito obrigado pela ajuda!

  • Rafael Dias perguntada 3 anos atrás
  • última atividade 3 anos atrás
2 votos
4k visualizações

O μstart for PIC é uma plataforma de desenvolvimento com o microcontrolador PIC18F4550 da Microchip® ideal para seus protótipos ou projetos pois não precisa de gravador externo já que o bootloader pré-gravado resolve esta questão carregando o programa diretamente via USB.

uStart for PIC

Pode ser adquirido pelo ML neste link, ou entre em contato [email protected]

  • Marcos Ribeiro perguntada 4 anos atrás
  • última atividade 2 anos atrás
Mostrando 5 resultados