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.
' 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
Re: SERIN2 Receiving Wrong Data
The sending device has the typical 18F4550 USB setup and it is set to "Define OSC 48". The receiving device is set to "DEFINE OSC 16".
rsocor01 Yesterday, 19:56