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:
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:
T0CON = %11000111
With this in place, your program should work fine. Here's the whole code with corrections applied:
Code:
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