tweak 16f877a code for 18f452 ?

General discussion on mikroBasic PRO for PIC.
Post Reply
Author
Message
HyperUniverse
Posts: 282
Joined: 17 Jun 2009 10:42

tweak 16f877a code for 18f452 ?

#1 Post by HyperUniverse » 01 Oct 2009 16:05

Hi,

After having problems with memory banks using PIC16F877A, I have followed mE advise, and upgrade to PIC18F452 (which is pin for pin compatible with 16F877A).

Now the code needs a bit of tweaking.
Next is a frequency meter, which works perfect with 16f877a.
After reading both datasheets, I have changed the OPTION_REG to T0CON (I kept same values).
PIC18F452 has no OPTION_REG, so I thought the T0CON will replace it.
But the program is not working.

Can anybody point me to what I'm doing wrong here?

Thanks.

Code: Select all

program FREQ_COUNTER
'===============================================================================
'| *****  0Hz to 65.5KHz  Frequency Counter  *****                             |
'| *****  PIC16F877A @ 8MHz  Default Configs *****                             |
'| *****  By Warren Schroeder Apr 02, 2009   *****                             |
'| *****                                                                       |
'| *****  Counts pulses on T1CKI pin for 1 Second Sampling Period *****        |
'| *****                                                                       |
'===============================================================================
CONST FILLER as Byte = 256-132    ' = 132 * 128us = 16896us
Dim TIMER1 as Word  Absolute 14   '  TMR1L:TMR1H pair
Dim FREQ as Word
Dim TALLY as Byte
DIM HertzStr as String[5]    'Hertz to output to LCD

dim LCD_RS as sbit  at RB1_bit
    LCD_EN as sbit  at RB2_bit
    LCD_D4 as sbit  at RB4_bit
    LCD_D5 as sbit  at RB5_bit
    LCD_D6 as sbit  at RB6_bit
    LCD_D7 as sbit  at RB7_bit

    LCD_RS_Direction as sbit at TRISB1_bit
    LCD_RW_Direction as sbit at TRISB1_bit
    LCD_EN_Direction as sbit at TRISB2_bit
    LCD_D4_Direction as sbit at TRISB4_bit
    LCD_D5_Direction as sbit at TRISB5_bit
    LCD_D6_Direction as sbit at TRISB6_bit
    LCD_D7_Direction as sbit at TRISB7_bit
' End Lcd module connections
'===============================================================================


Sub Procedure Interrupt()
    dec(TALLY)
    If TALLY = 0 Then          ' 30 int's x 32768us = 983040us
       TMR0 = TMR0 + FILLER    ' add 16896us = 999,936us  ~1sec.
       TALLY = 31
    End If
    If TALLY = 30 Then         ' finished 1 second
        T1CON.TMR1ON = 0       ' stop  timer1
        FREQ = TIMER1          ' save  timer1
        TIMER1 = 0             ' clear timer1
        T1CON.TMR1ON  = 1      ' start timer1
        TMR0   = 0             ' clear timer0 ; fresh start for next 1sec.
     End If
    INTCON.TMR0IF = 0     ' clear int flag
End Sub

Sub Procedure SetupT1asCounter()
    T1CON = %00000110      ' ext clock, no sync, no prescale
    TMR1H = 0              ' clear timer1
    TMR1L = 0
    T1CON.TMR1ON = 1       ' start timer1
    TALLY = 30             ' 30 interrupts, each 256*128us= 32768us
End Sub

Sub Procedure SetupT0asTimer()

     OPTION_REG = %00000111 ' prescale=256  = 128us each tick
     ' T0CON = %00000111 ' prescale=256  = 128us each tick (for PIC18F452)

      TMR0 = 0               ' timer cleared and rolling
      INTCON = %10100000     'GIE enabled,TMR0IE enabled,TMR0IF cleared
End Sub
'===============================================================================

Sub Procedure GENERAL_INIT()

       TRISA  = 0
       PORTA  = 0
     TRISB  = 0
     PORTB  = 0
       TRISC  = 1
       PORTC  = 0
     TRISD  = 0
     PORTD  = 0

      ADCON1 = 6             ' disable analog inputs
    '  CMCON  = $06             ' Comparators off
      CMCON = 7
     FREQ  = 0
    
      LCD_Init()
      LCD_Cmd(_LCD_CLEAR)                    ' Clear display
      LCD_Cmd(_LCD_CURSOR_OFF)               ' Turn cursor off

     SetupT1asCounter()
     SetupT0asTimer()
     
end sub
'===============================================================================

 main:
     General_Init()

     While 1=1              ' Loop from here
          Delay_ms(50)                              'update LCD every 50ms
          wordToStr(FREQ, HertzStr)                 'convert FREQ for LCD
          
          LCD_Out(1,1,"HERTZ")
          LCD_Out(2,1,HertzStr)
     Wend                   'Loop to here

end.

User avatar
anikolic
mikroElektronika team
Posts: 1775
Joined: 17 Aug 2009 16:51
Location: Belgrade
Contact:

#2 Post by anikolic » 06 Oct 2009 09:36

Hi,
Your code needed a little adjustments to meet the features of PIC18F452 that are different from PIC16F877A.
1. First of all, your TIMER1 variable pointed to wrong address. In PIC16F877A, the address of TMR0 is 14, but in PIC18F452 is 0xFCE. You should see the datasheet for addresses of special function registers. They are different for every PIC.

Code: Select all

Dim TIMER1 as Word  Absolute 0xFCE   '  TMR1L:TMR1H pair
2. Your TIMER0 was turned off in your SetupT0asTimer() initialization procedure, so it never caused the interrupt overflow. You should set TMR0ON bit, as well as T08BIT to enable Timer0 and set it to 8-bit mode:

Code: Select all

T0CON = %11000111
With this in place, your program should work fine. Here's the whole code with corrections applied:

Code: Select all

program FreqCounter
'===============================================================================
'| *****  0Hz to 65.5KHz  Frequency Counter  *****                             |
'| *****  PIC16F877A @ 8MHz  Default Configs *****                             |
'| *****  By Warren Schroeder Apr 02, 2009   *****                             |
'| *****                                                                       |
'| *****  Counts pulses on T1CKI pin for 1 Second Sampling Period *****        |
'| *****                                                                       |
'===============================================================================
CONST FILLER as Byte = 256-132    ' = 132 * 128us = 16896us
Dim TIMER1 as Word  Absolute 0xFCE   '  TMR1L:TMR1H pair
Dim FREQ as Word
Dim TALLY as Byte
DIM HertzStr as String[5]    'Hertz to output to LCD

dim LCD_RS as sbit  at RB4_bit
    LCD_EN as sbit  at RB5_bit
    LCD_D4 as sbit  at RB0_bit
    LCD_D5 as sbit  at RB1_bit
    LCD_D6 as sbit  at RB2_bit
    LCD_D7 as sbit  at RB3_bit

    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit
' End Lcd module connections
'===============================================================================


Sub Procedure Interrupt()
    dec(TALLY)
    If TALLY = 0 Then          ' 30 int's x 32768us = 983040us
       TMR0L = TMR0L + FILLER    ' add 16896us = 999,936us  ~1sec.
       TALLY = 31
    End If
    If TALLY = 30 Then         ' finished 1 second
        T1CON.TMR1ON = 0       ' stop  timer1
        FREQ = TIMER1          ' save  timer1
        TIMER1 = 0             ' clear TIMER1
        T1CON.TMR1ON  = 1      ' start timer1
        TMR0L  = 0             ' clear timer0 ; fresh start for next 1sec.
     End If
    INTCON.TMR0IF = 0     ' clear int flag
End Sub

Sub Procedure SetupT1asCounter()
    T1CON = %00000110      ' ext clock, no sync, no prescale
    TMR1H = 0              ' clear timer1
    TMR1L = 0
    T1CON.TMR1ON = 1       ' start timer1
    TALLY = 30             ' 30 interrupts, each 256*128us= 32768us
End Sub

Sub Procedure SetupT0asTimer()
      TMR0H = 0
      TMR0L = 0               ' timer cleared and rolling
      T0CON = %11000111 ' prescale=256  = 128us each tick (for PIC18F452)
      INTCON = %10100000     'GIE enabled,TMR0IE enabled,TMR0IF cleared
End Sub
'===============================================================================

Sub Procedure GENERAL_INIT()

     TRISA  = 0
     PORTA  = 0
     TRISB  = 0
     PORTB  = 0
     TRISC  = 1
     PORTC  = 0
     TRISD  = 0
     PORTD  = 0

     ADCON0 = 0
     ADCON1 = 6             ' disable analog inputs
     CCP1CON = 0
     FREQ  = 0

     LCD_Init()
     LCD_Cmd(_LCD_CLEAR)                    ' Clear display
     LCD_Cmd(_LCD_CURSOR_OFF)               ' Turn cursor off

     SetupT1asCounter()
     SetupT0asTimer()

end sub
'===============================================================================

 main:
     GENERAL_INIT()

     While True              ' Loop from here
          Delay_ms(50)                              'update LCD every 50ms
          WordToStr(FREQ, HertzStr)                 'convert FREQ for LCD

          LCD_Out(1,1,"HERTZ")
          LCD_Out(2,1,HertzStr)
     wend                   'Loop to here

end.
Best regards,
Aleksandar
Web Department Manager

Post Reply

Return to “mikroBasic PRO for PIC General”