Code:
'****************************************************************************************************
'* Name : RE test WJS.pbp *
'* Author : WJ Sherwood *
'* Notice : Copyright (c) 2021 *
'* : All Rights Reserved *
'* Date : 07/02/21 *
'* Device : 16F1788 [tests using 16F886 (and appropriate Reg changes) works correctly.] *
'* Version : 1 (PBP 3.0.10.4) *
'* Notes : Spurious "I'm Alive" serial traffic following RE action (still) and corrupt chars if *
'* : Pause at line 75 (following MaxLimit = 60) removed - what am I missing? *
'* : *
'* : REa portb.6, REb portb.5, REsw portb.4 all pulled up, active low. *
'* : *
'****************************************************************************************************
'=========================================================================================================
' CONFIGURE DEVICE
'=========================================================================================================
#CONFIG ; 16F1788.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _LVP_OFF & _BORV_HI & _LPBOR_OFF ;& _STVREN_OFF
#ENDCONFIG
'' What happens with a different PIC?
'#CONFIG ; F886
' __config _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_ON & _LVP_OFF & _CP_OFF
'#ENDCONFIG
' -----[ Initialization F1788]---------------------------------------------------------------------------------
TRISA = %00000000 ' Set I/O.
' TRISB = %01111111 ' Set I/O.
TRISB = %01110000 ' Set I/O. Only RE bits set as inputs.
TRISC = %00000000 ' Set I/O.
define OSC 4
OSCCON = %01101010 ' 4Mhz (F1788).
'define OSC 32
' OSCCON = %11110000 ; 32 MHz,
ANSELA = 0 ; all digital
ANSELB = 0 ; all digital
' --------------------------------------------------------------------------------------------------------------
'' -----[ Initialization F866]-----------------------------------------------------------------------------------------------
' CM1CON0 = 0 ' Comparators off.
' ANSEL = %00000000 ' Make PortA AN0-AN7 digital.
'' ANSEL = %00000011 ' All digital except An0 and An1.
' TRISA = %00000000 ' Set I/O.
' CM2CON0 = 0 ' Comparators off.
' ANSELH = 0 ' Make PortB AN8-AN13 digital.
'' PortB Int-On-Change: 1 = Int enabled. 0 = Int disabled.
' IOCB.0 = 0 ' No.
' IOCB.4 = 1 ' Yes, encoder pushbutton.
' IOCB.5 = 1 ' Yes, encoder Channel A.
' IOCB.6 = 1 ' Yes, encoder Channel B.
' IOCB.7 = 0 ' No.
' TRISB = %01110000 ' 4-6 encoder inputs.
' CCP1CON = %00000000 '
' TRISC = %00000000 ' Set I/O.
'' ADCON0 = %11001000 ' Set A/D to Frc, Channel 3, On (F88).
' ADCON0 = 0 ' Disable A/D.
' ADCON1 = %00000110 ' All digital.
'' ADCON1 = %10000000 ' R justify (where the 6 MSB of ADRESH read as 0 i.e. 10 bit), Vdd for Vref.
' Define OSC 4 ' Set Operating Frequency
' OSCCON = %01100000 ' 4Mhz (F886).
'' Define OSC 8 '
'' OSCCON = %01110000 ' 8Mhz (F886).
' INTCON = %10001000 ' Port B int on change and global interrupt enable.
' clear ' ****** Clear statement must be before the INC file.******
'wsave VAR BYTE $70 SYSTEM ' alternate save location for W
'' --------------------------------------------------------------------------------------------------------------
' Define LCD connections
DEFINE LCD_DREG PORTA ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTA ' Register Select Port
DEFINE LCD_RSBIT 4 ' Register Select Bit
DEFINE LCD_EREG PORTA ' Enable Port
DEFINE LCD_EBIT 7 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD
'=========================================================================================================
' PIN ASSIGNMENTS, SYSTEM CONSTANTS, TEMPORARY VARIABLES
'=========================================================================================================
' Rotary Encoder stuff
Old_Bits VAR BYTE bank0 ' Encoder port bits before change.
New_Bits VAR BYTE bank0 ' Encoder port bits after change.
RotEnc1_val VAR word bank0 ' Connected to PORTB<6:5>.
MaxLimit var word bank0 ' Used for setting upper limit for encoder counts.
RotEncDir VAR BIT bank0 ' Direction of rotation bit.
ButtPush var bit bank0 ' Flag shows button was pushed, allows quick exit from Int handler.
REdec var bit bank0 ' Flag shows RE decrement, allows quick exit from Int handler.
REinc var bit bank0 ' Flag shows RE increment, allows quick exit from Int handler.
'Temp var byte ' Used for Int clearing by reading PortB. F886
Include "MODEDEFS.BAS" ' Include Shiftin/out modes.
INCLUDE "DT_INTS-14.bas" ' Needs to be assembled with MPASM **********
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
OPTION_REG.6 = 0 ' INTEDG set to interrupt on falling edge.
' OPTION_REG.6 = 1 ' INTEDG set to interrupt on rising edge.
' ----- F1788 --------------------------------------------------------------------------------------------------
' IOCBP = %01110000 ; REa portb.6, REb portb.5 pos edge trigger
IOCBN = %01110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
IOCBF = 0 ; Reset the PortB flag.
INTCON = %11001000 ; GIE, PEIE, IOCIE.
' --------------------------------------------------------------------------------------------------------------
clear ' Clear all vars.
MaxLimit = 60 ' Menu value limit.
' pause 100 ' Let everything settle...
serout2 PORTC.6, 16468, ["Power-on: ",BIN8 STATUS, " - ",BIN8 PCON,10,13] ' thanks to Henrik.
PCON = %00011111
serout2 PORTC.6,16468,["Priming PCON: ",BIN8 STATUS," - ",BIN8 PCON,10,13]
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]
' ----- F1788 --------------------------------------------------------------------------------------------------
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes ; Newer PICs.
endm
INT_CREATE ; Creates the interrupt processor .
ENDASM
@ INT_ENABLE IOC_INT ; Newer PICs.
' --------------------------------------------------------------------------------------------------------------
'' ----- F886 ---------------------------------------------------------------------------------------------------
'ASM
'INT_LIST macro ; IntSource, Label, Type, ResetFlag?
' INT_Handler RBC_INT, _Rot_Encoder, PBP, yes
' endm
' INT_CREATE ; Creates the interrupt processor
'ENDASM
'@ INT_ENABLE RBC_INT ; RB Port Change Interrupt
'' --------------------------------------------------------------------------------------------------------------
Old_Bits = PORTB & (%01100000) ; RE uses B.6,B.5 - REa and REb.
Main:
if PortB.4 = 0 then ' Check if Encoder pushbutton was pushed.
while PortB.4 = 0:wend ' Wait for release.
pause 50 ' Debounce delay.
serout2 PORTC.6,16468,[13,10,"ButtPush = 1, RE ",dec5 RotEnc1_val]
'serout2 PORTC.6,16468,[13,10,BIN8 STATUS," - ",BIN8 PCON,10,13] ' thanks to Henrik.
endif
if REdec or REinc = 1 then
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
REdec = 0:REinc = 0 ' Reset the flags.
endif
goto main ' endless loop waiting for INT.
'---[IOC - interrupt handler]---------------------------------------------------
' Don't forget 4 counts per detent (Quadrature).
Rot_Encoder:
New_Bits = PORTB & (%01100000) ' Set port bits for Encoder's chosen A and B channels.
IF (New_Bits & %01100000) = (Old_Bits & %01100000) then DoneRotEnc ' No change.
RotEncDir = New_Bits.6 ^ Old_Bits.5 ' Bit XOR compare to get direction of rotation.
if RotEncDir = 0 then ' CCW so decrement.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val - 1 ' Decrement the count.
if RotEnc1_val => 65530 then RotEnc1_val = 0 ' Limit the max.
if RotEnc1_val <= 4 then RotEnc1_val = 0 ' Limit the min.
REdec = 1 ' Flag the event.
endif
ELSE ' RotEncDir = 1, CW so increment.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val + 1 ' Increment the count.
if RotEnc1_val >= MaxLimit then RotEnc1_val = MaxLimit ' Limit the count.
REinc = 1 ' Flag the event.
endif
ENDIF
DoneRotEnc:
Old_Bits = New_Bits
INTCON.0 = 0 ; Clean up and exit - clear IOCIF. F1788
IOCBF = 0 ; Reset the flag. F1788
' Temp = PORTB ' Read PortB to clear the Int (F886).
@ INT_RETURN
end
Next up I'm going to try a 16F1938 (and maybe some 18F's) but out of time now and it will have to wait for the weekend. While I can use the F886 for this project it gives me no confidence to use F1788's for Int duties in future until sorted.
Bookmarks