Learning to program the PIC16LF1823

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
I think you misunderstood. Timer 2 runs continuously and resets itself when it reaches the value in PR2 so it generates a uniform system interrupt, no stopping, no reloading just tik tik tik. All you have to do is be able to service the interrupt within the timer period. Clear the TMR2IF when you enter the service routine, process the tik then retfie.
Nice ... then it means it works very similar to the 8051 in that respect, which as you know, is more familiar territory to me.
 

JohnInTX

Joined Jun 26, 2012
4,787
Nice ... then it means it works very similar to the 8051 in that respect, which as you know, is more familiar territory to me.
Pretty much like MODE 2 in the 8051. If I read it right though, the reload in the 8051 is from a register so the timer counts up from there to rollover. That means that the setting is 256-n counts. TMR2 in the PIC counts up from 0 to PR2 then resets to 0 so the number of counts is just PR2
 

OBW0549

Joined Mar 2, 2015
3,566
Ok, this chip has two timers: Timer0 and Timer2 (what happened to Timer1? :confused:).
One thing to note about PIC timers: TMR0, TMR1, TMR2, etc. do not merely enumerate a PIC's timers; they designate the type of timer. A TMR0 on any particular PIC operates the same as a TMR0 on any other PIC; the same goes for TMR1, TMR2 and all the rest. They are different types of timers.

So it's not that Microchip "skipped over" TMR1 when enumerating the timers on the PIC10F322; rather, it's that the PIC10F322 doesn't have a TMR1-type timer.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
One thing to note about PIC timers: TMR0, TMR1, TMR2, etc. do not merely enumerate a PIC's timers; they designate the type of timer. A TMR0 on any particular PIC operates the same as a TMR0 on any other PIC; the same goes for TMR1, TMR2 and all the rest. They are different types of timers.

So it's not that Microchip "skipped over" TMR1 when enumerating the timers on the PIC10F322; rather, it's that the PIC10F322 doesn't have a TMR1-type timer.
Ah! ... I understand now, I think ... in the 8051 one changes the timer's type by changing its MODE of operation ... so I see that the PIC has different timers operating at different modes that cannot be changed.
 

OBW0549

Joined Mar 2, 2015
3,566
Ah! ... I understand now, I think ... in the 8051 one changes the timer's type by changing its MODE of operation ... so I see that the PIC has different timers operating at different modes that cannot be changed.
Exactly. However, in some PICs with multiple timers there is an option to concatenate two of them to make one timer with longer length; my recollection of which timers those are, is a bit hazy. TMR1 and TMR3? I hate getting old and not being able to remember stuff...
 

jpanhalt

Joined Jan 18, 2008
11,087
Exactly. However, in some PICs with multiple timers there is an option to concatenate two of them to make one timer with longer length; my recollection of which timers those are, is a bit hazy. TMR1 and TMR3? I hate getting old and not being able to remember stuff...
You can use TMR0 overflow as a gate source for TMR1 to get some pretty long intervals without using a 32 KHz clock.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
Say I have two registers representing a 16-bit number. They are counter_lb and counter_hb, respectively. And a couple of constants (value_lb and value_hb) also representing a 16-bit number.

What's the easiest way of performing the following conditional?:

if counter_xx >= value_xx then
call subroutine​
end if​

by counter_xx I mean to represent both bytes as a single 16-bit number. Same goes for value_xx
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
May I pass along one of the resources I found when I started programming PICs many years ago?

PICLIST Code Repository
Here's a little snippet of code extracted from the link you posted. At this point, I'm thoroughly running it in my head, to get more acquainted with the PIC's internal logic ... this little project is certainly pulling me out of my comfort zone ... but what can I say? the sense of progress I'm getting is also very satisfactory ... plus, I'm having loads of fun :)

Code:
; signed and unsigned 16 bit comparison routine:
; by David Cary 2001-03-30
; returns the correct flags (Z and C)
; to indicate the X=Y, Y<X, or X<Y.
; Does not modify X or Y.

compare_signed16: ; 7
; uses a "temp" register.
    movf Yhi,w
    xorlw 0x80
    movwf temp
    movf Xhi,w
    xorlw 0x80
    subwf temp,w ; subtract Y-X
    goto Are_they_equal

compare_unsigned_16: ; 7
    movf Xhi,w
    subwf Yhi,w ; subtract Y-X

Are_they_equal:
  ; Are they equal ?
   skpz     ;<- this instruction doesn't exist in the 10LF322, I assume it's equivalent to "btfsc STATUS, Z"
    goto results16

  ; yes, they are equal -- compare lo
   movf Xlo,w
   subwf Ylo,w ; subtract Y-X

  results16:
; if X=Y then now Z=1.
; if Y<X then now C=0.
; if X<=Y then now C=1.
  return
 
Last edited:

MMcLaren

Joined Feb 14, 2010
861
Cool! Just for fun, type that function into an XC8 program, compile it, and look at the generated code in the LST file... Look familiar?
Code:
   void function_test()             //
   { int a = 14555;                 //
     int b = 27000;                 //
     if(a >= b) {                   //
       a++;                         //
     }                              //
   }                                //
And here's the generated code from the program LST file;
Code:
   909  0520  30DB                  movlw    219
   910  0521  00F4                  movwf    function_test@a
   911  0522  3038                  movlw    56
   912  0523  00F5                  movwf    function_test@a+1
   913             
   914                           ;16F1823_I2C_v1.c: 138: int b = 27000;
   915  0524  3078                  movlw    120
   916  0525  00F2                  movwf    function_test@b
   917  0526  3069                  movlw    105
   918  0527  00F3                  movwf    function_test@b+1
   919             
   920                           ;16F1823_I2C_v1.c: 139: if(a >= b) {
   921  0528  0875                  movf    function_test@a+1,w
   922  0529  3A80                  xorlw    128
   923  052A  00F1                  movwf    ??_function_test
   924  052B  0873                  movf    function_test@b+1,w
   925  052C  3A80                  xorlw    128
   926  052D  0271                  subwf    ??_function_test,w
   927  052E  1D03                  skipz
   928  052F  2D32                  goto    u215
   929  0530  0872                  movf    function_test@b,w
   930  0531  0274                  subwf    function_test@a,w
   931  0532                     u215:
   932  0532  1C03                  skipc
   933  0533  0008                  return
   934             
   935                           ;16F1823_I2C_v1.c: 140: a++;
   936  0534  3001                  movlw    1
   937  0535  07F4                  addwf    function_test@a,f
   938  0536  3000                  movlw    0
   939  0537  3DF5                  addwfc    function_test@a+1,f
   940  0538  0008                  return
   941  0539                     __end_of_function_test:
Here's code generated for an "unsigned" integer version;
Code:
   872                           ;16F1823_I2C_v1.c: 394: if(a >= b)
   873  0514  0872                  movf    test@b+1,w
   874  0515  0274                  subwf    test@a+1,w
   875  0516  1D03                  skipz
   876  0517  2D1A                  goto    u245
   877  0518  0871                  movf    test@b,w
   878  0519  0273                  subwf    test@a,w
   879  051A                     u245:
   880  051A  1C03                  skipc
   881  051B  0008                  return
   882                   
   883                           ;16F1823_I2C_v1.c: 395: a++;
   884  051C  3001                  movlw    1
   885  051D  07F3                  addwf    test@a,f
   886  051E  3000                  movlw    0
   887  051F  3DF4                  addwfc    test@a+1,f
   888  0520  0008                  return
   889  0521                     __end_of_test:
Another invaluable tool is the MPLAB simulator. Use the "watch" window to view and/or modify your variables and the simulator to single step through your code to verify that it's doing what you expect.

Have fun... Cheerful regards, Mike, K8LH
 

Attachments

Last edited:

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
YES! ... the firmware needed to control my device is now complete! ... and it's working beautifully! ...:)

Of course, I've still got many, many things to learn about the PIC architecture. But I think I've finally understood the basic stuff. It's not a bad family of chips, at all. And it's worth considering as a migration option from the 8051.

Many, many thanks to all who helped me out through this thread. It would've easily taken me ten times the effort had it not been for your invaluable help... I owe each and every one of you a nice dinner and a few beers ... all you have to do is come down here and collect ... :D
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
Question, I'm no sure I understand what the "Complimentary Waveform Generator (CWG)" feature in this chip is, or what it's for. Would someone care to explain it to me in simple and clear English?
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
I'm at the end of my wits here ...

I've built the very same circuit I've been working on, but this time using entirely SMT components, including the PIC MCU. Specifically, I traded the DIP PIC10LF322-I/P for the PIC10LF322T-I/OT, which are exactly the same, but with different pinout.

Well, I've gone through the pinout a 1,000 times and compared it to what I did on my first circuit, and everything is a perfect match. I've also checked the PCB traces multiple times and everything's nice and steady. At no moment has the device's voltage been exceeded (3.3V) and I have not connected a single periferial to it it yet.

The first time I tried to program it using the MPLAB X IDE software, I got an error message telling me that the device ID was not a valid one. That's when I began to check and re-check things ... then I concluded that I must've burnt or zapped the thing at some moment during assembly or while I was handling it, so I removed the device, and installed a completely fresh one out of its package and was double-extra-careful while I handled it and while I soldered it. I used low-temp SMT solder at 430°F, and applied the iron as briefly as possible. And then I checked and re-checked all the traces for proper conductivity and short circuits and everything was fine.

Then I connected the PCB to the PickIt 3 programmer, and tried to read the device's contents.

This is the message I got:
Connecting to MPLAB PICkit 3...

Currently loaded firmware on PICkit 3
Firmware Suite Version.....01.51.12
Firmware type..............Midrange

Target voltage detected
Target Device ID (0x2180) is an Invalid Device ID. Please check your connections to the Target Device.
So I tried it a second time, and the message I got was this:
Target Device ID (0x180) is an Invalid Device ID. Please check your connections to the Target Device.
And the third time and all the rest of the times that I've tried to read or program it, the message has always been:
Target Device ID (0x0) is an Invalid Device ID. Please check your connections to the Target Device.
It appears that the device was damaged somehow... maybe a higher (5V) voltage was applied to it by the programmer? But I also checked for that, and MPLAB clearly shows that that's the device being worked on on the Dashboard:

upload_2019-8-7_13-16-48.png

What gives? I'm pulling what little hair I have left on my scalp here...
 
Last edited:

OBW0549

Joined Mar 2, 2015
3,566
Beats me; I've never encountered that before, except when I've neglected to turn on power as supplied from the PICKit. All I can suggest is mount a PIC on some sort of header board or breakout board, and connect it to the PK3 with nothing else involved and see if the PK3 recognizes it. That's about all I can think of.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,762
Beats me; I've never encountered that before, except when I've neglected to turn on power as supplied from the PICKit. All I can suggest is mount a PIC on some sort of header board or breakout board, and connect it to the PK3 with nothing else involved and see if the PK3 recognizes it. That's about all I can think of.
Yeah... that's going to be my last resort ... fortunately, I have quite a few of them suckers available to pop as I please before things become critical.
 
Top