Learning to program the PIC16LF1823

Ian Rogers

Joined Dec 12, 2012
1,136
I use MPLab 8.92. It is still available for download, but does not support the very newest chips. I did try on an early version of MPLabX and found it unusable for Assembly. I understand from @Ian Rogers and others that those earlier problems have been somewhat resolved, but I have not ventured out into that realm again.
I have fallen out with MPLABX again....Not because of assembly ( that's a chore on its own ).. But because of Harmony..
I found MPLAB X very unfriendly for Assembley.
Its a really stupid assembler, Its bundled with the XC toolsuite… I have assembled several programs with it..

Its on my tutorial "todo" list... You just have to remember that the ASM file MUST be named correctly for XC assembler to kick in..

There is a really decent IDE from Proteus... It was bundled with Proteus8 but if you had downloaded it when version 7 was out, it was standalone... It is VSM studio... This detected both MPASM and MPASMWIN and would set it up for you..

BUT!! As others have said... MPASM and MPASWIN are dated and may not support newer chips..
 

jpanhalt

Joined Jan 18, 2008
11,087
I have fallen out with MPLABX again....Not because of assembly ( that's a chore on its own ).. But because of Harmony..
That very term reminds me of my antivirus (Avast). Several months ago, it offered a free trial to "clean up and optimize my computer." I agree and regretted it immediately. Cancelled the free trial period well before the due date. Anything named Harmony must have brought smiles of sarcasm to those who created it.
 

MaxHeadRoom

Joined Jul 18, 2013
30,658
The biggest Issue I have with MPLAB IDE is when using Pickit3, Picket2 I can hot swap anything on the USB port any time with no problems.
Pik3 the slightest little thing and I have to go through the whole Correct sequence of loading everything in the proper order, one step wrong, and it does't like it.
Max.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
I think I now understand what's with the whole "__CONFIG" thing ... it is not a register, but rather a physical location in the chip's structure where fuses are located that define its functionality. That's why they can't be accessed at run-time, and can only be set or cleared during programming. Most MCU's work this way. But it's the change in language that gets to me. It almost feels as if I were learning some sort of alien artifact ... I mean, why call registers "files" in the instruction set? ... geeezzz...
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
So ... I've already compiled the program and uploaded it into the PIC10LF322 chip ... the software reported no errors, and I was able to read back the code stored in the chip.

Here's the compiled program:

Code:
:020000040000FA
:020000000528D1
:040002000034003492
:0800080009008F309005033060
:1000100085000610851C0F280D2805140A280510D8
:020020000A28AC
:00000001FF
And here's the relevant portion of the code read back from the chip:

Code:
:020000040000FA
:10000000052800340034FF3F09008F30900503308D
:1000100085000610851C0F280D2805140A280510D8
:100020000A28FF3FFF3FFF3FFF3FFF3FFF3FFF3FEC
I'm familiar with the .HEX file syntax and structure, and as far as I can see, things look alright to me... thing is, the chip is not responding as it should ... when I press the button, nothing happens on the other pin ... :(
 

JohnInTX

Joined Jun 26, 2012
4,787
Howdy! You need to clear ANSELA to make it a digital port.
Also, Microchip discourages using r-m-w (bsf,bcf etc.) on the TRIS registers .. for good reasons. Write the whole register using MOVWF.
Finally, be sure to do all rmw (bcf/bsf) to LATA instead of PORTA. I have found on these little chips that they can be sensitive to r-m-w issues. Other than that, it runs on the sim.
EDIT: using code in post #30
Having fun yet? :)
 
Last edited:

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
Having fun yet? :)
:rolleyes: rub it in man ... after this is over, I'll challenge you to a full-blown grills-galore smoked ribs cookout ... see who comes out a winner ... :p

In the meantime, I need all the help that I can get ... so I'm just gonna have to soak it up, eat humble pie, and follow my (very much) elder's advice ... :p:D

Thanks for the tip!
 

JohnInTX

Joined Jun 26, 2012
4,787
Nah, not rubbing it in, just sympathizing. And since I had to sell my smoker, I am at your mercy in the BBQ dept - I've seen your stuff!
y sí, soy el más viejo con PIC.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
Nah, not rubbing it in, just sympathizing. And since I had to sell my smoker, I am at your mercy in the BBQ dept - I've seen your stuff!
y sí, soy el más viejo con PIC.
I've tweaked the code as you've suggested ... how's this?

Code:
;*****************************************************************************************
;                                   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

;************************************* 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 PORTA       ;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
Set_Ra0
       bsf LATA, RA0
      goto ProgramLoop ;loop endlessly through this logic
     
Clr_Ra0
       bcf LATA, RA0
      goto ProgramLoop ;loop endlessly through this logic
     
     END
 

JohnInTX

Joined Jun 26, 2012
4,787
Sim's happy, I'm happy. Does the chip work?
If you're not using interrupts, you should never get to 0x004. If you do, it's an error. Kill interrupts and return to resume processing. A better way eventually is to trap that error so that you know that you have a problem.
Code:
INT_VECTOR    ORG    0x004                       ;interrupt vector location
    clrf    INTCON        ; should never be here, disable interrupts  
    return              ;return without re-enabling interrupt
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
Sim's happy, I'm happy. Does the chip work?
Code:
INT_VECTOR    ORG    0x004                       ;interrupt vector location
    clrf    INTCON        ; should never be here, disable interrupts  
    return              ;return without re-enabling interrupt
Not yet ... I'm going to include that snippet of code you've posted ... see what happens...
 

JohnInTX

Joined Jun 26, 2012
4,787
I don't think that will fix it, just a precaution.
What oscillator config are you wanting? Your CONFIG line is commented out. I think you don't have an oscillator based on the default CONFIG bits.
Are you using MPLABX?
 

JohnInTX

Joined Jun 26, 2012
4,787
Paste this into the code:

; CONFIG
; __config 0xFC80
__CONFIG _FOSC_INTOSC & _BOREN_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _LVP_OFF & _LPBOR_OFF & _BORV_LO & _WRT_OFF

And don't get discouraged. These are not trivial to get started with, despite those "35 easy to learn instructions"

EDIT: Since you are using MPLABX, config bits get easy.
Click Window->PIC Memory Views -> Configuration Bits
You get a nice window with drop-down boxes in the OPTION column. Select what you want then..
Click Generate Source Code To Output.
You'll get lines like I posted.
Copy and paste into your source.
Done. Nice. While I admire and agree with your wanting to understand CONFIG, do this first then do it by hand and see if you agree. Once you get it, use the tool.

EDIT2: I would write OSCCON directly instead of relying on default bits and ANDing. Just bang 'em in there.
 
Last edited:

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
It works!!! ... here's the code (I didn't change the CONFIG line 'cause I just saw your post):

Code:
;*****************************************************************************************
;                                   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
              clrf   INTCON
              return                             ;why return and not retfie?
             ;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

;************************************* 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
Set_Ra0
       bsf LATA, RA0
      goto ProgramLoop ;loop endlessly through this logic
    
Clr_Ra0
       bcf LATA, RA0
      goto ProgramLoop ;loop endlessly through this logic
    
     END
Bu-uh-ha-ha-ha-ha!!!! (evil laughter) ... the first step of my plan towards total world domination is now complete! ... the foundations of the Martínez dynasty of Supreme Leaders for the next millennia have been laid! ...

***

My next step will be to tweak the code a little, the datasheet says that writing to PORTA is the same as writing to LATA (but it's not the same as reading) ... so I'm gonna test that ...

As you can see the bsf LATA, RA0 instruction is NOT supposed to work ... and yet it does
 
Last edited:

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
Yup ... I changed "bsf LATA, RA0" to "bsf PORTA, RA0" and it worked just as well ...

Another mistake I was making is that I was not unplugging the programmer's cable from the PCB
 

jpanhalt

Joined Jan 18, 2008
11,087
As you can see the bsf LATA, RA0 instruction is NOT supposed to work ... and yet it does
RA0 is an output. Why do you think it shouldn't work? "Write to LATA, read PORTA."

Yes, you can write to a post too, but writing to a port has "read-modify-write" vulnerability. In your case that should not make a difference.

It may be the ANSELA change.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,760
RA0 is an output. Why do you think it shouldn't work? "Write to LATA, read PORTA."
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 ...
 

JohnInTX

Joined Jun 26, 2012
4,787
  • ;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
My reasoning is pure and my strident insistence on same is derived from hard experience. No sense in getting smacked yourself.
 
Top