I believe that Port A is all Schmitt Trigger. The microchip switching levels are 0.2 and 0.8 x VDD .
Have you considered putting a relatively high value resistor (10 k to 50 k) in parallel with the diode or diode/resistor. That will ensure a positive pull-down without the diode drop without greatly affecting the on current available..
John
;******************************************************************
;
; /*
; * Lighted Push Button Switches (emulated toggle switches)
; *
; * swnew ____---____-----___ sample active lo switches
; * swold _____---____-----__ switch state latch
; * swnew ____-__-___-____-__ changes, press or release
; * swnew ____-______-_______ filter out 'release' bits
; * flags _____-------_____-- toggle flag bits for main
; * trisa -----_______-----__ toggle tris bits for LEDs
; */
;
; while(1)
; { delay_ms(25); // sample at 25-ms intervals
; trisa |= 0b00000111; // set RA2-RA0 pins to input
; swnew = ~porta; // sample active lo switches
; swnew &= 0b00000111; // only RA2-RA0 switch pins
; swnew ^= swold; // changes, press or release
; swold ^= swnew; // update switch state latch
; swnew &= swold; // filter out 'release' bits
; flags ^= swnew; // toggle flag bits for main
; porta &= 0b11111000; // set output latches to '0'
; trisa ^= flags; // light only active sw LEDs
;
; if(swnew) // on any "new press"
; beep(); // task a "new press" beep
;
; if(swnew.0) // if sw RA0 'new press'
; { //
; } //
; if(swnew.1) // if sw RA1 'new press'
; { //
; } //
; if(swnew.2) // if sw RA2 'new press'
; { //
; } //
; }
;
loop
DelayCy(25*msecs) ; sample at 25 msec intervals |B0
movlw TRISA ; |B0
movwf FSR ; FSR = &TRISA |B0
movlw 0x07 ; wreg = 1<<RA2|1<<RA1|1<<RA0 |B0
iorwf INDF,F ; TRISA |= 0x07 (RA0-RA2 inputs) |B0
comf PORTA,W ; sample active lo switches |B0
andlw 0x07 ; on the RA2..RA0 pins only |B0
xorwf swold,W ; changes, press or release |B0
xorwf swold,F ; update switch state latch |B0
andwf swold,W ; filter out 'release' bits |B0
movwf swnew ; save 'new press' bits |B0
xorwf flags,F ; toggle flag bits for main |B0
movlw b'11111000' ; mask off RA0-RA2 bits |B0
andwf PORTA,F ; keep switch latch bits '0' |B0
movf flags,W ; trisa ^= flags |B0
xorwf INDF,F ; light only active LEDs |B0
; movf swnew,W ; any 'new press' bits? |B0
; skpnz ; yes, skip, else |B0
goto loop ; loop |B0
Wow thank you for the responses. I try to answer them one by one. I could do low side switching (not a problem). But does PORTA have pull-up resistors internally? If not, I would have the same problem. How about using the comparator function to force the pin low?How about low side switching? Connect the LED's from Vcc to the switch and the switch to ground. You'd have to invert the logic in the PIC.
Hi PommieIf you use port B and invert the logic then you can use the internal weak pullups of the chip. Some of the newer pin compatible pics have WPUs on port A too.
Mike.
Hello MikeWhat does your code look like, ROM? I've done something similar before but I was using active low push button switches and active high LEDs (to emulate lighted toggle switches). I believe I used something like the code below;
Cheerful regards, Mike
[/code]
I could since all use a 1k series resistor.I wonder if the LEDs & current limiting resistor would work as a pull-up?
Also, if only one LED is lighted at a time, couldn't you use a single current limiting resistor?
So you don't think LED and resistor will provide logic "1" with all switches open?That will work but not without pullups. Either the internal ones or something like 50k resistors across the LEDs.
Mike.
;******************************************************************
; *
; Filename: 12F1822_Test.asm *
; Author: Mike McLaren, K8LH *
; Date: 13-Aug-2017 *
; *
; 12F1822 experiment *
; *
; *
; MPLab: 8.92 (tabs=8) *
; MPAsm: 5.51 *
; *
;******************************************************************
include "P12F1822.INC"
errorlevel -302
list st=off
radix dec
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _BORV_19 & _LVP_OFF & _PLLEN_OFF
;
; _MCLRE_ON default
; _PWRTE_OFF default
; _CP_OFF default
; _CPD_OFF default
; _BOREN_ON default
; _CLKOUTEN_OFF default
;
; _WRT_OFF default
; _STVREN_ON default
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; variables ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cblock 0x20 ; 0x20..0x6F, bank 0
swold ;
swnew ;
flags ;
delayhi ; DelayCy() function variable
endc
cblock 0x70 ; 0x70..0x7F common all banks
endc
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; constants ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; K8LH DelayCy() subsystem macro generates four instructions ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
radix dec
clock equ 16 ; 4, 8, 12, 16, 20 (MHz), etc.
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ usecs*1000 ; cycles/millisecond multiplier
dloop equ 5 ; loop size, 5 to 8 cycles
;
; -- loop -- -- delay range -- -- memory overhead ----------
; 5-cyc loop, 11..327690 cycles, 9 words (+4 each macro call)
; 6-cyc loop, 11..393226 cycles, 10 words (+4 each macro call)
; 7-cyc loop, 11..458762 cycles, 11 words (+4 each macro call)
; 8-cyc loop, 11..524298 cycles, 12 words (+4 each macro call)
;
DelayCy macro cycles ; range, see above
if (cycles<11)|(cycles>(dloop*65536+10))
error " DelayCy range error "
else
movlw high((cycles-11)/dloop)+1
movwf delayhi
movlw low ((cycles-11)/dloop)
call uLoop-((cycles-11)%dloop)
endif
endm
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; reset vector ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
org 0x0000
v_reset
goto setup ;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; interrupt vector ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
org 0x004
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; main setup ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
setup
banksel ANSELA ; bank 3 |03
clrf ANSELA ; set digital I/O |03
banksel TRISA ; bank 01 |01
movlw b'00000111' ; |01
movwf TRISA ; |01
;
; setup INTOSC
;
banksel OSCCON ; bank 1 |01
movlw b'01111010' ; |01
movwf OSCCON ; setup 16-MHz INTOSC |01
waitfs btfss OSCSTAT,HFIOFS ; stable? yes, skip, else |01
bra waitfs ; branch and wait |01
banksel PORTA ; bank 0 |00
clrf swold ; |00
clrf flags ; |00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; main loop ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; /*
; * Lighted Push Button Switches (emulated toggle switches)
; *
; * swnew ____---____-----___ sample active lo switches
; * swold _____---____-----__ switch state latch
; * swnew ____-__-___-____-__ changes, press or release
; * swnew ____-______-_______ filter out 'release' bits
; * flags _____-------_______ toggle flag bits for main
; * trisa -----_______------- toggle tris bits for LEDs
; */
;
; while(1)
; { delay_ms(25); // sample at 25-ms intervals
; trisa |= 0b00000111; // set RA2-RA0 pins to input
; swnew = ~porta; // sample active lo switches
; swnew &= 0b00000111; // only RA2-RA0 switch pins
; swnew ^= swold; // changes, press or release
; swold ^= swnew; // update switch state latch
; swnew &= swold; // filter out 'release' bits
; flags ^= swnew; // toggle flag bits for main
; porta &= 0b11111000; // set output latches to '0'
; trisa ^= flags; // light only active sw LEDs
;
; if(swnew) // on any "new press"
; beep(); // task a "new press" beep
;
; if(swnew.0) // if sw RA0 'new press'
; { //
; } //
; if(swnew.1) // if sw RA1 'new press'
; { //
; } //
; if(swnew.2) // if sw RA2 'new press'
; { //
; } //
; }
;
loop
DelayCy(25*msecs) ; sample at 25 msec intervals |00
;
; K8LH parallel switch state logic and "new press" filter
;
; wreg ____---____-----_____ inverted active lo sample
; swold _____---____-----____ switch state latch
; wreg ____-__-___-____-____ changes, press or release
; wreg ____-______-_________ filter out 'release' bits
; flags _____-------_________ toggle flag bits for main
;
banksel TRISA ; bank 1 |01
movlw b'00000111' ; |01
iorwf TRISA,F ; set RA2..RA0 pins to inputs |01
banksel PORTA ; bank 0 |00
comf PORTA,W ; sample active lo switches |00
xorwf swold,W ; changes, press or release |00
xorwf swold,F ; update switch state latch |00
andwf swold,W ; filter out 'release' bits |00
movwf swnew ; save 'new press' bits |00
skpz ; new switch? no, skip, else |00
movwf flags ; update 'on' flags (1 of n) |00
; xorwf flags,F ; toggle 'on' flags (n of n) |00
;
; light LEDs for switches with an 'on' flag
;
movlw b'11111000' ; mask off RA2-RA0 bits |00
andwf PORTA,F ; set output latches to '0' |00
movf flags,W ; pickup sw2..sw0 states |00
banksel TRISA ; bank 1 |01
xorwf TRISA,F ; trisa ^= flags (light LEDs) |01
banksel PORTA ; bank 0 |00
;
; check for "new" switch position change
;
btfsc swnew,0 ; RA0 on? no, skip, else |00
call off_mode ; |00
btfsc swnew,1 ; RA1 on? no, skip, else |00
call man_mode ; |00
btfsc swnew,2 ; RA2 on? no, skip, else |00
call auto_mode ; |00
goto loop ; |00
off_mode
man_mode
auto_mode
return ; |00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; K8LH DelayCy() subsystem 16-bit uDelay subroutine ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a = dloop-1
while a > 0
nop ; (cycles-11)%dloop entry points |00
a -= 1
endw
uLoop addlw -1 ; subtract 'dloop' loop time |00
skpc ; borrow? no, skip, else |00
decfsz delayhi,F ; done? yes, skip, else |00
goto uLoop-dloop+5 ; do another loop |00
return ; |00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?