Learning to program the PIC16LF1823

jpanhalt

Joined Jan 18, 2008
11,087
The datasheet states that:

"A write operation to the LATx register has the same affect as a write to the corresponding PORTx register."

NOTE: I hate it when people confuse the word "affect" with the word "effect" ... :confused:
I had never noticed that error and feel the same way about it. I guess chips must have a personality.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,218
And here's a question about how to minimize current consumption. From the datasheet:

1575419690268.png
Question, if I do leave unconnected I/O pins in my circuit, wouldn't it be enough just to configure them as inputs, and then enable their internal weak pull-ups? ... that way they technically won't be left floating, right?.
 

jpanhalt

Joined Jan 18, 2008
11,087
I am not sure I understand that either. I usually set unconnected pins as outputs.

The WPU current is listed as 100 uA nominal (200 uA max) and 140 uA nominal (300 uA max) for VCC = 3.3 V and 5 V, respectively, and pin connected to VSS. Maybe what it is means is connecting to VCC, if WPU is enabled, or disable WPU and connect to VSS.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,218
I'm getting the following error when MPLAB X tries to compile the following lines:

Code:
       banksel OSCCON     ;select memory bank 1
       movlw b'00000111'  ;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
Message[302] C:\A\GEN03\GEN03.ASM 129 : Register in operand not in bank 0. Ensure that bank bits are correct.

Of course OSCCON does not reside in bank 0, but rather in bank 1 ... and yet the compiler seems to be ignoring the preceding banksel instruction. It doesn't work when I use movlb 1 instead either. :mad:

What's going on?
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,218
Message[302] isn't an error. It isn't even really a warning, either; it's just a "friendly reminder."

It's all explained in this thread over in the Microchip forums. Also in this thread from the PicList.
Many thanks for bringing that to my attention ... as suggested in one of the links you posted, I added the instruction errorlevel -302 at the top of my program, and that suppressed those annoying messages.

I don't understand why the compiler doesn't simply evaluate the active memory bank when that instruction is compiled, though. Perhaps it's not possible for the compiler to know all possible active memory banks under every conceivable circumstance?
 

OBW0549

Joined Mar 2, 2015
3,566
I don't understand why the compiler doesn't simply evaluate the active memory bank when that instruction is compiled, though. Perhaps it's not possible for the compiler to know all possible active memory banks under every conceivable circumstance?
Correct.
 

djsfantasi

Joined Apr 11, 2010
9,156
The arduino IDE is easy because it doesn't do much.
MPLABX includes a simulator which allows you to single step through your program (C or assembler), view or change RAM or SFRs, and you can set up a file to simulate external hardware. You don't need the actual hardware to do some quite detailed debugging. Natuarlly all this takes some learning.
It doesn’t do much if you don’t ask it to. It will install a boot loader on a naked chip, turn a chip into a programmer, manage all of your libraries (standard and add-ons), automatically create a project from your Main sketch (automatically attaching all external code, external header files just by adding a command that includes them).

Note that I never mentioned Arduino systems, as the IDE can be used on many chips and microprocessor systems

It’s easy to use not because it doesn’t do anything but rather because of all that it does.

It doesn’t have a debugger. Darn! But you can download one...
 

jpanhalt

Joined Jan 18, 2008
11,087
There's another error code that can help, but can also be a nuisance. Code 305 will occur when you leave the destination off. With older PIC's, it was maybe not such a big deal. With enhanced midrange, you operate directly on WREG, such as this:
Code:
     decfsz    WREG           ;delay                                       |B2
and that will give this "message":
Message[305] D:\EPROJECT\MPLAB\MPLAB PROJECTS\GLCD_ST7567 BOB\GLCD_ST7567 BOB V10 MOD120119.ASM 317 : Using default destination of 1 (file).
Maybe 1 or 2 of those is not bothersome, but the code with that instructions gives 12 of the 305 warnings.

Here is my standard beginning, unless I have a reason not to use it:
Code:
;*******************************************************************************
    list        p=16f1829      ; list directive to define processor
    #include    <p16f1829.inc> ; processor specific variable definitions
    errorlevel -302, -305
         list st=off
    RADIX dec
;*******************************************************************************
 

joeyd999

Joined Jun 6, 2011
5,234
and yet the compiler...
What compiler?

You're using assembly. Assembly is assembled by an assembler, not a compiler.

An assembler is not as smart as a compiler, and it has no knowledge of your code and what bank bits you think you have set up. BANKSEL is just a macro to assist you with setting the proper bits in the BSR. There's no context for the assembler to know that you've used it properly.

Consider it a friendly warning to pay attention.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,218
What compiler?

You're using assembly. Assembly is assembled by an assembler, not a compiler.

An assembler is not as smart as a compiler, and it has no knowledge of your code and what bank bits you think you have set up. BANKSEL is just a macro to assist you with setting the proper bits in the BSR. There's no context for the assembler to know that you've used it properly.

Consider it a friendly warning to pay attention.
thanks for the lesson in semantics, Joey ... and yes, a few hours ago I figured that banksel is not really an instruction but rather a macro that generates a movlb instruction accordingly.

As for my attention, rest assured it's being exercised to the best of my abilities... I still have lots to learn about this architecture.
 

jpanhalt

Joined Jan 18, 2008
11,087
I mentioned before that I use mainly movlb rather than banksel. Here's an example I learned from one of the experts a long time ago:
Code:
;*******************************************************************************
PutCMD
     movlb     2              ;                                            |B2
     bcf       CSn            ;                                            |B2
     bcf       A0             ;CMD/DAT bit, L=CMD                          |B2
     movlb     4              ;PutCMD+3                                    |B4
     movwf     SSP1BUF        ;PutCMD+4                                    |B4
     btfss     SSP1STAT,BF    ;                                            |B4
     bra       $-1            ;                                            |B4
     return                   ;                                            |B4
ExitCMD
     movlb     2              ;                                            |B2
     bsf       A0             ;                                            |B2
     bsf       CSn            ;                                            |B2
     movlb     0              ;                                            |B0
     return                   ;                                            |B0
I am not fanatical about tracking the bank, but there are two occasions when I am pretty religious about doing it:
1) Processor set up, because there will be a lot of bank changes that I may not just know off hand.
2) When writing often-used subroutines (as in the above example). It can save considerable instructions when doing graphics, for example, to know what bank you are in and going to.

Of course, there are other occasions, and when working in Bank0, I often neglect doing it.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,218
I mentioned before that I use mainly movlb rather than banksel. Here's an example I learned from one of the experts a long time ago:
Code:
;*******************************************************************************
PutCMD
     movlb     2              ;                                            |B2
     bcf       CSn            ;                                            |B2
     bcf       A0             ;CMD/DAT bit, L=CMD                          |B2
     movlb     4              ;PutCMD+3                                    |B4
     movwf     SSP1BUF        ;PutCMD+4                                    |B4
     btfss     SSP1STAT,BF    ;                                            |B4
     bra       $-1            ;                                            |B4
     return                   ;                                            |B4
ExitCMD
     movlb     2              ;                                            |B2
     bsf       A0             ;                                            |B2
     bsf       CSn            ;                                            |B2
     movlb     0              ;                                            |B0
     return                   ;                                            |B0
I am not fanatical about tracking the bank, but there are two occasions when I am pretty religious about doing it:
1) Processor set up, because there will be a lot of bank changes that I may not just know off hand.
2) When writing often-used subroutines (as in the above example). It can save considerable instructions when doing graphics, for example, to know what bank you are in and going to.

Of course, there are other occasions, and when working in Bank0, I often neglect doing it.
Have you actually memorized the contents of each bank? Or do you still have to look at the tables to make sure you're using the correct one?
 

joeyd999

Joined Jun 6, 2011
5,234
I mentioned before that I use mainly movlb rather than banksel. Here's an example I learned from one of the experts a long time ago:
Code:
;*******************************************************************************
PutCMD
     movlb     2              ;                                            |B2
     bcf       CSn            ;                                            |B2
     bcf       A0             ;CMD/DAT bit, L=CMD                          |B2
     movlb     4              ;PutCMD+3                                    |B4
     movwf     SSP1BUF        ;PutCMD+4                                    |B4
     btfss     SSP1STAT,BF    ;                                            |B4
     bra       $-1            ;                                            |B4
     return                   ;                                            |B4
ExitCMD
     movlb     2              ;                                            |B2
     bsf       A0             ;                                            |B2
     bsf       CSn            ;                                            |B2
     movlb     0              ;                                            |B0
     return                   ;                                            |B0
I am not fanatical about tracking the bank, but there are two occasions when I am pretty religious about doing it:
1) Processor set up, because there will be a lot of bank changes that I may not just know off hand.
2) When writing often-used subroutines (as in the above example). It can save considerable instructions when doing graphics, for example, to know what bank you are in and going to.

Of course, there are other occasions, and when working in Bank0, I often neglect doing it.

You can also substitute:

movlb HIGH filereg

This way, if you change filereg's location, the code will auto adjust.

I usually define a label for the main working bank (generally not bank 0 -- there are fewer GP registers there). Routines that require banking can then switch back easily, and I don't have to edit my code substantially if I choose a different main bank.
 

jpanhalt

Joined Jan 18, 2008
11,087
You can also substitute:

movlb HIGH filereg

This way, if you change filereg's location, the code will auto adjust.

I usually define a label for the main working bank (generally not bank 0 -- there are fewer GP registers there). Routines that require banking can then switch back easily, and I don't have to edit my code substantially if I choose a different main bank.
That is still an unnecessary instruction, if everything is in the same Bank.

As for registers, I usually get by with Common RAM. I may use GP RAM, but I don't find Bank0 restrictive in that regard. For something big, like a FIFO Buffer, I use linear RAM.
 

joeyd999

Joined Jun 6, 2011
5,234
That is still an unnecessary instruction, if everything is in the same Bank.

As for registers, I usually get by with Common RAM. I may use GP RAM, but I don't find Bank0 restrictive in that regard. For something big, like a FIFO Buffer, I use linear RAM.
I use 18F parts. Always need more than one bank of working registers (usually many -- my projects are usually fairly large). For queues and tables, I use indirect addressing with the FSRs.
 

jpanhalt

Joined Jan 18, 2008
11,087
Frankly, I view the 18F's as advanced over the 16F's but see no reason to go to that platform with 24F's being available. I would compare 18F's in a literary manner to early steamboats with sails.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,218
Here's a dumb question. Register banks 0 through 7 have clear differences between them, but what's the purpose then of having banks 8 through 31 if they look exactly the same, with the first 12 registers of every bank pointing to exactly the same registers in every other bank, and the rest of those registers are unusable?
 

jpanhalt

Joined Jan 18, 2008
11,087
Here's a dumb question. Register banks 0 through 7 have clear differences between them, but what's the purpose then of having banks 8 through 31 if they look exactly the same, with the first 12 registers of every bank pointing to exactly the same registers in every other bank, and the rest of those registers are unusable?
It has to do with the 14-bit core that can only accommodate so much addressing in an instruction. There are 31 banks (2^5-1). Many of the higher numbered banks are virtually vacant, but as peripherals get added, those banks get filled with SPF registers. Look at the 16F18856 and similar newer chips. Bank19 or maybe even higher have SPF registers.
 
Top