Also shown is how to use the 16F1934 IOCBF interrupt flags to recognize button presses in the background. I.E. you don't need to poll port pins to detect a change, and no interrupts required.
Code:
' Name : T246_1934X.pbp
' Compiler : PICBASIC PRO Compiler 2.6
' Assembler : MPASM
' Target PIC : 40-pin 16F1934 or similar
' Hardware : LAB-X1 Experimenter Board
' Oscillator : 4MHz external crystal
' Keywords : LCDOUT
' Description : PICBASIC PRO program to demonstrate using Timer2 for a
' 24 hour format clock. Time is shown on the LCD as Time = 11:14 with
' hours : minutes. The keypad is used to increment hours, minutes, reset
' the time to 12:00, and reset the Timer2 tick counter.
'
' Note: Open the 16F1934.INC file in your PBP directory, and comment out the default
' __config settings.
ASM
__config _CONFIG1, _FOSC_XT & _WDTE_SWDTEN & _PWRTE_ON & _MCLRE_ON & _BOREN_ON & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF & _VCAPEN_OFF & _STVREN_ON & _BORV_25
ENDASM
' Define LCD pins
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
' setup vars for clock
Time Var Word ' accumulates TMR2 to PR2 match counts
Minutes Var Byte ' minutes
Hours Var Byte ' hours
Match Var PIR1.1 ' TMR2 to PR2 match interrupt flag bit
IocFlag Var INTCON.0 ' portb int-on-change flag bit
Gosub Init ' jump to hardware initialization routine
Lcdout $fe,1,"Time = ", #Hours DIG 1,#Hours DIG 0,":",#Minutes DIG 1,#Minutes DIG 0
' setup & start TMR2 after Lcdout
T2CON = %01110110 ' set 1:16 prescale, 1:15 postscale, TMR2 on
Main:
' every 60mS the TMR2IF flag is set, and this routine is entered.
' Plenty of time to do other stuff.
If Match = 1 Then ' has TMR2 matched PR2? (should happen every 60mS)
Match = 0 ' yes. clear TMR2 to PR2 match flag bit PIR1.1
Time = Time + 1 ' increment 60mS count
If Time = 1000 Then ' has 60 seconds (1000*60mS) passed?
Time = 0 ' yes. clear count
Minutes = Minutes + 1 ' increment Minutes
If Minutes = 60 Then ' roll-over from 59 to 0
Minutes = 0 ' zero Minutes count
Hours = Hours + 1 ' and increment Hours count
If Hours = 24 Then ' roll-over from 23 to 0
Hours = 0 ' zero Hours count
Endif
Endif
' Update time on LCD every 60 seconds
Lcdout $fe,$87,#Hours DIG 1,#Hours DIG 0,":",#Minutes DIG 1,#Minutes DIG 0
Endif
Endif
' test for key press
If IocFlag Then ' if keys SW13, 14, 15 or 16 were pressed,
Gosub GetKeys ' get the button/buttons pressed
Endif
Goto Main
' ===========\ Get Keypad Switch Presses /=========== '
GetKeys:
Pause 500 ' crude debounce for key press
' SW13 increments Hours
If IOCBF.4 Then ' IOCBF.4 = 1 when low edge detected on RB4
While PORTB.4 = 0 ' wait for key release
Wend '
Hours = Hours + 1 : Time = 0
If Hours = 24 Then Hours = 0
Endif
' SW14 increments Minutes
If IOCBF.5 Then ' IOCBF.5 = 1 when low edge detected on RB5
While PORTB.5 = 0 ' wait for key release
Wend '
Minutes = Minutes + 1 : Time = 0
If Minutes = 60 Then Minutes = 0
Endif
' SW15 zeros Time "tick" counter
If IOCBF.6 Then ' IOCBF.6 = 1 when low edge detected on RB6
While PORTB.6 = 0 ' wait for key release
Wend '
Time = 0
Endif
' SW16 resets clock to 12:00
If IOCBF.7 Then ' IOCBF.7 = 1 when low edge detected on RB7
While PORTB.7 = 0 ' wait for key release
Wend '
Hours = 12 : Minutes = 0 : Time = 0
Endif
IOCBF = 0 ' reset all int-on-change bits on exit
IocFlag = 0
' Update LCD on each change
Lcdout $fe,$87,#Hours DIG 1,#Hours DIG 0,":",#Minutes DIG 1,#Minutes DIG 0
Return
Init:
ANSELA = 0 ' porta all digital
ANSELB = 0 ' portb all digital
ANSELD = 0 ' portd all digital
ANSELE = 0 ' porte all digital
OPTION_REG.7 = 0 ' enable PORTB pullups
PORTB = 0 ' RB3 low
TRISB = %11110111 ' RB3 = 0 for output to keys 13, 14, 15, 16
WPUB = %11110000 ' weak pull-ups on for ----> RB4, 5, 6, 7
IOCBP = 0 ' positive edge disabled
IOCBN = %11110000 ' negative edge int-on-change enabled for keys
TRISD = 0 ' PORTD all outputs
INTCON = 0 ' not using interupts. Just monitoring int flag bits
Time = 0 ' clear TMR2 to PR2 match counter
Hours = 10 ' set clock starting hour to 10 here
Minutes = 16 ' set clock starting minutes to 16 here
' TMR2 increments from 0 until it matches the value in the PR2 register.
' The match automatically resets Timer2 and sets the Timer2 interrupt flag
' bit PIR1.1.
PR2 = 249 ' 0 to 249 = 250. 250*16*15*1uS=60mS
Match = 0 ' clear PIR1.1 match flag bit
Pause 100 ' Wait for LCD to start
Return ' Return to caller
End


Menu

Re: FSK demodulator in firmware
could work good, input coupling cap, output would swing about 0, then ZCD could work...
amgen Yesterday, 20:3510000