and I'm guessing the operative word of that last statement is "hard" ...My reasoning is pure and my strident insistence on same is derived from hard experience.
I think I know what the difference is ... PORTA reads the physical state of the pins, while LATA reads what the user is telling the pin to do. For instance, if I write a 1 to the pin but then short it to ground, PORTA will read a 0, while LATA will read a 1 ... right?The assembler knows how to resolve the differences between LATA and PORTA as long as you, the programmer, know the differences. For now, it is sufficient to use PORT only for actual inputs (switches etc.) and LAT for everything else. Trust me on this one.
Hard and expensive. And yup, been there with stupid mistakes. I actually have a billing code called 'dummy time' which is how I track stupid stuff that I can't in good conscience bill to clients. AAC has a lot of good PIC guys here so don't worry. PIC hardware can be *ahem* thorny but a lot of that is because they pack a lot of stuff into the chip. Once you get past that, the same programming skills from 8051 will apply.and I'm guessing the operative word of that last statement is "hard" ...
dude ... I've been there and done that ... I've gone through countless migraines and spent endless hours trying to bug-out stupid mistakes and overlooked details while learning this sort of stuff ... you have no idea of how much I'm appreciating your help at this moment ... "thanks" doesn't quite say it ...
please ... don't leave me until I get through this ...
Right!I think I know what the difference is ... PORTA reads the physical state of the pins, while LATA reads what the user is telling the pin to do. For instance, if I write a 1 to the pin but then short it to ground, PORTA will read a 0, while LATA will read a 1 ... right?
You wrote:Because, the LATA register (or "file", in this stupid thing) does NOT have an RA0 bit, but rather a LATA0 bit ... the compiler should've reported that as an error ...
I didn't pay a lot of attention to how you identified the bits on that port, they typically are like RA0, RA1, etc.Edit: On further review, you need to disable ANSELA for your digital inputs and outputs (RA0, RA1). As for setting a "pre" state, Since the input pin has a weak pullup, it is already high. I don't believe setting it to 1 will affect it. Output drivers are disabled on it. Finally, you will probably get by with reading and writing to the port, but since that chip has output latches, it is preferred to write to the latch (i.e, LATA) and read the port.
;*****************************************************************************************
; 10 JUL 2018, 10:23:51 AM:
; Generator controller for the PIC10LF322
; The following program reads the state of the R1 pin and outputs it at the R0 pin
;*****************************************************************************************
list p=PIC10LF322 ;list directive to define processor
#include p10lf322.inc ;processor specific variable definitions
radix dec
; - Flash memory self-write protection off (default state)
; - Brown-out reset low trip point is selected (default state)
; - Low-power Brown-out Reset is enabled (default state)
; - High Voltage on MCLR pin must be used for programming
; - Program memory code protection disabled (default state)
; - MCLR pin set as digital input
; - Power-up Timer disabled (default state)
; - Watchdog timer disabled
; - Brown-out reset is enabled (default state)
; - Internal oscillator is activated
__CONFIG _LVP_OFF & _MCLRE_OFF & _WDTE_OFF & _FOSC_INTOSC
;*****************************************************************************************
; Reset and Interrupt program memory locations
;*****************************************************************************************
RESET_VECTOR ORG 0x000 ;processor reset vector
goto Init ;go to beginning of program
INT_VECTOR ORG 0x004 ;interrupt vector location
retfie ;return from interrupt
;*****************************************************************************************
; Main program start
;*****************************************************************************************
Init
;the reference Clock output bit CLKROE is disabled by default, we'll leave it that way
;set the internal oscillator frequency to 31 KHz (the lowest possible), this is done
;by clearing the IRCF bits, which belong in bit locations 4, 5 and 6, respecively
movlw b'10001111' ;the W register has been loaded with the IRCF bits as zeroes
andwf OSCCON, f ;AND the W register with OSCCON, storing the result in OSCCON
clrf INTCON ;make sure that all interrupts are disabled
;************************************* I/O definitions ***********************************
CLRF ANSELA ;clear the analog select register, which for some stupid reason
;is enabled by default ... otherwise the digital i/o function
;won't work
; - set RA1 as an input, active low ... this means that we also have to enable its
; internal weak pull-up
; - set RA0 as an output, active high ... leave RA2 as an input ... RA3 can ONLY be
; an input
;BANKSEL PORTA ;this instruction is not necessary with the 10LF322, since it only
;has one bank of SFRs
movlw b'00000011' ;set appropriate pin states BEFORE enabling their i/o functions
movwf LATA ;R0, will be set as an output, with its startup state as one, R1
;will be set as an active-low input with an internal pull-up
;enabled, therefore it must be latched as one ... all other bits
;are inconsequential
;10 JUL 2018, 5:57:17 PM: By the advice of JohnInTx, the following function has been
;cancelled, and a complete movwf to TRISA will be used instead
;bcf TRISA, TRISA0 ;clear bit TRISA0 located at the TRISA register, effectively setting
;R0 as an output, all other bits remain in their defualt (1) state
movlw b'00001110'
movwf TRISA
;the following instruction is unnecessary, since all internal weak pull ups are enabled
;by default when a pin is configured as an input
;bsf WPUA, WPUA1 ;activate the internal weak pull-up of the RA1 pin
ProgramLoop
;RA1 is an input, active low, which will go low when the button is pressed and connects
;it to ground ... therefore under the next logic, RA0 will remain high until the button
;is pressed
btfss PORTA, RA1 ;skip next instruction if the button is unpressed
goto Clr_Ra0
goto Set_Ra0
;yeah, I know that this logic structure can be imporved substantially, but hey, I'm
;learning here!
;10 JUL 2018, 6:01:16 PM: again, the very sympathetic JohnInTx recommended using LATA
;instead of PORTA for all rmw (such as bsf and bcf) for some obscure and obnoxious
;reason. BUT the datasheet says that writing to PORTA and writing to LATA are the same
;thing ... the difference lies when *reading* from those registers ... the read
;instruction does not result in the same thing
Set_Ra0
bsf LATA, LATA0
goto ProgramLoop ;loop endlessly through this logic
Clr_Ra0
bcf LATA, LATA0
goto ProgramLoop ;loop endlessly through this logic
END
That's an extremely important observation Max, that behavior is not the same with the 8051, which I'm familiar with. Thanks for sharing.When servicing an interupt it prevents any other interupt from happening until the retfie.
Yes it is ... because it's apparently unnecessary, according to the datasheet ... I'm gonna un-comment it, and see what happens...Line 76, the weak pullup config is commented out? Plus you have to enable the whole shebang in OPTION_REG:WPUEN
John, you're the man ... you've just saved me from one of the most horrible headaches and annoyances in recent times ...See my edit re: OPTION_REG? Global weak pullups are disabled by default.
... and I assume that humility is just another one of your vastly magnificent virtues?De hecho, soy el hombre en lo que respecta a PIC.
Vastly magnificent? I like that. Humility.. of course!... and I assume that humility is just another one of your vastly magnificent virtues?
Your comment in the code says 'Why return and not retfie?' To answer, it's because with no interrupt service routines, there should be no interrupts at all. If there are, it is an error. The solution I posted was to disable all interrupts then just return. RETFIE returns and reenables interrupts so the problem would be restored. Note that to get to the interrupt vector at all you have to have made a mistake in your coding. You want to tamp it out right there.If using Interrupts the Retfie is return and interrupt enable.
When servicing an interupt it prevents any other interupt from happening until the retfie.
Max.
Main:
bsf ADCON0,GO_DONE ; start an A-to-D conversion
call InitLCD ; Initialize LCD Special Function Registers
clrf Counter
clrf TMR1L
clrf TMR1H
Loop:
btfss INTCON,T0IF ; TMR0 is preloaded so than this loop is exited every 23.4ms
goto Loop
That was Senor Martinez comment, not mine.Your comment in the code says 'Why return and not retfie?' .
by Robert Keim
by Jake Hertz
by Duane Benson
by Aaron Carman