Microchip Technology
Welcome to www.microchip.com
Search: Click here to Search Microchip.com
Forums Home Register LoginLog Out Inbox Address Book My Subscription Member List Search My Profile FAQ
Clever and Useful tricks

Clever and Useful tricks

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [Microcontroller Discussion Group] >> Tips and Tricks >> Clever and Useful tricks Page: [1] 2 3 4 5   next >   >>
Login
Message << Older Topic   Newer Topic >>
Clever and Useful tricks - May 26, 2006 9:23:21 AM   
jbroadwell
5+ years with MCHP products


Posts: 1419
Joined: Nov. 2, 2005
From: Indianapolis, Indiana
Status: offline
As a parallel to the thread started by Prince, how about a clever and useful tricks thread?

I'll start...

Tip 1:
The ability to output the CV ref voltage on a pin on the 18F4620 can be awesome for debugging.  It gives you the ability to output 16 different analog voltages.  I (like most embedded developers) often write state machines to get my work done.  I sometimes use the CV ref pin to output a voltage indicating which state  I'm in.  That way I can track state transitions in real time using an oscilloscope.

Tip 2:

If you're maintaining a legacy product using a chip such as the 18F458, consider modifying one of your engineering samples to use the 18F4580.  Porting the code isn't hard (use #ifdefs for the differences).  Use the additional breakpoints available on the 18F4580 to find your problem, then fix it on the production boards using the 18F458's.  The difference between having 3 breakpoints and one is huge.  Those who have the bling to buy an ICE can safely ignore this tip.

_____________________________

http://www.serialwombat.com
When someone asks you "Can't you just...", watch out.
Post #: 1
RE: Clever and Useful tricks - May 26, 2006 10:23:56 AM   
Guest
A ultrafast 8bit*8bit -> 16bit operation in C18:

   char a,b;
   int i;
   
   a = b = 100;

   i = (a*b,PROD);

(in reply to jbroadwell)
  Post #: 2
RE: Clever and Useful tricks - May 26, 2006 10:27:01 AM   
Guest
In C18, always declare local loop control variables as the first local var in the function, as unsigned char. The compiler will access the variable using INDF2, that is the fastest ACCESS mode that you have in the PIC18, faster even than a global var. All other local vars will require PLUSW2 addressing, much slower.

(in reply to Guest)
  Post #: 3
RE: Clever and Useful tricks - May 27, 2006 12:00:07 PM   
Polyene

 

Posts: 813
Joined: Jan. 8, 2006
From: Sweden
Status: online
In many architectures, multiplication by a power of 2 can be optimized to a bit shift operation.

In the PIC18 though, multiple bit shifts can be optimized into a single multiplication instruction (MULLW). It's mostly useful for 8-bit variables, but in some cases it can be used for 16-bits as well. Implemention is compiler-specific, but here's a couple of examples in assembly:

Shift the value in W 3 bits to the left:
  MULLW   8
  MOVF    PRODL,W


Shift the value in W 3 bits to the right:
  MULLW   32
  MOVF    PRODH,W

(in reply to Guest)
Post #: 4
RE: Clever and Useful tricks - May 27, 2006 12:47:36 PM   
Guest
I can't claim originality on this one, but is a useful trick.

Exchange 2 RAM addresses value without a temp register:

   movf        var_A,w
   xorwf       var_B,w
   xorwf       var_A,f
   xorwf       var_B,f


(in reply to Polyene)
  Post #: 5
RE: Clever and Useful tricks - May 27, 2006 1:05:22 PM   
danish.ali
5+ years with MCHP products

 

Posts: 1354
Joined: Nov. 16, 2004
From: Surrey, UK
Status: offline
And something I don't claim originality for:
Replace only the <mask> bits in <reg> by those in W leaving the rest of <reg> untouched.
    xorwf  <reg>,W
    andlw  <mask>
    xorwf  <reg>,F
(I got this from disassembling the ZX-Spectrum ROM)
- Danish

(in reply to Guest)
Post #: 6
RE: Clever and Useful tricks - May 27, 2006 1:15:35 PM   
Prince
Experienced Hobbyist

 

Posts: 364
Joined: Nov. 21, 2005
Status: offline
Aha. Nice thread. Glad I could start something.  Hah. Wow these are cool tricks. I guess i named my thread a bit wrong, nice catch. These might be a bit more useful than mine. Though the posts on the other... hah... started intresting and puzzling discussion. These will be good for people looking for optimization(sp).

_____________________________

ETA - Certified Student Electronics Technician
Experience In 12F, 16F, 18F, and 30F
while (alive > 0)
{
  HandleLife();
  Intelligence++;
}

(in reply to danish.ali)
Post #: 7
RE: Clever and Useful tricks - May 27, 2006 3:29:20 PM   
Guest
This one I can claim originality:

Multiply 16x16->32 in C18 (similar to the 8x8->16):


  int y,z;
  long x;
  
   // trick: get 16*16->32
   y = z = 1000;
   x = (y*z,*(long *)&AARGB3);     // 63 cycles


This works very well in C18 v3.00. It is compiler-version specific, though: for higher versions, you need to use __AARGB3 or the MATHDATA variable used by the 16x16 lib multiply routine. This is almost twice as fast as doing the operation cast to long.


(in reply to Prince)
  Post #: 8
RE: Clever and Useful tricks - May 27, 2006 4:00:25 PM   
K8LH
Experienced Hobbyist

 

Posts: 1545
Joined: Mar. 26, 2004
From: Michigan, USA
Status: offline
I stumbled upon a collection of snippets from Myke Predko long ago here; http://www.myke.com/basic.htm

Building on one of his examples, here's a reasonably efficient PutHex subroutine using one level of recursion (2 stack levels total);
;
;  Print byte in W as two ASCII nybbles
;
PutHex  movwf   TEMP            ; save byte 
        swapf   TEMP,W          ; swap nybbles in W
        call    Hex2Asc         ; process left nybble
        movf    TEMP,W          ; process right nybble
Hex2Asc andlw   b'00001111'     ; mask off left nybble
        addlw   h'36'           ;
        btfsc   STATUS,DC       ;
        addlw   h'07'           ;
        addlw   0-6             ; ($FA)
        goto    Put232          ; print ASCII nybble

Have fun.  Regards, Mike

< Message edited by K8LH -- Jul. 16, 2006 8:33:41 AM >

(in reply to Guest)
Post #: 9
RE: Clever and Useful tricks - May 27, 2006 5:01:26 PM   
K8LH
Experienced Hobbyist

 

Posts: 1545
Joined: Mar. 26, 2004
From: Michigan, USA
Status: offline
I've always been amazed at the creative solutions for processing the quadrature A and B outputs from a Rotary Encoder (grin).  One simple method for determining encoder direction is to exclusive-or the previous encoder A or B bit reading with the opposite bit of the current encoder reading. 

Here's a simple 10 word (PIC16) polling routine that uses a single variable along with a few extra instructions for dealing with encoder detents;
;
;  check the Rotary Encoder A and B switches (bits 0 and 1 in
;  the debounced SWDAT2 variable) for a change
;
ISR_Encoder
       movf    SWDAT2,W        ; load switch data                |B0
       andlw   b'00000011'     ; mask encoder B and A switches   |B0
       xorwf   ENCOLD,W        ; same as last reading?           |B0
       bz      ISR_NextColumn  ; yes, branch (no change), else   |B0
       xorwf   ENCOLD,W        ; restore encoder bits in W       |B0
       rrf     ENCOLD,f        ; prep for B-old ^ A-new          |B0
       xorwf   ENCOLD,f        ; ENCOLD bit 0 = direction        |B0
       rrf     ENCOLD,f        ; now Carry bit = direction       |B0
       movwf   ENCOLD          ; update ENCOLD (new BA bits)     |B0
;
;  encoder position has changed but we only act on a change
;  that occurs when the encoder falls into one of the detent
;  positions (we ignore the changes between detents)
;
       xorlw   b'00000011'     ; detent position (BA = 11)?      |B0
       bnz     ISR_NextColumn  ; no, branch, else                |B0
;
;  set encoder pseudo 'DEC' or 'INC' switch bits in the SWITCH2
;  variable based on the Carry bit for Main program processing
;

Have fun.  Regards, Mike

(in reply to K8LH)
Post #: 10
RE: Clever and Useful tricks - May 29, 2006 6:11:18 AM   
Guest
quote:

ORIGINAL: K8LH

I stumbled upon a collection of snippets from Myke Predko long ago here; http://www.myke.com/basic.htm

Building on one of his examples, here's a reasonably efficient PutHex subroutine using one level of recursion (2 stack levels total);


Quite nice Mike. Although I have never seen Predko's snippets, this is from my lib:
SERIAL.print_hex:
  
      movwf       temp
      swapf       temp,w
      call        SERIAL.print_hex_digit
      movf        temp,w
  
SERIAL.print_hex_digit:
  
      andlw       0x0f
      addlw       0x06
      btfsc       DCARRY
      addlw       "A"-"9"-1
      addlw       "0"-0x06
      goto        SERIAL.print_char


It is essentially the same code as yours :-)

(in reply to K8LH)
  Post #: 11
RE: Clever and Useful tricks - May 29, 2006 6:27:21 AM   
markul

 

Posts: 352
Joined: Aug. 26, 2005
Status: offline
Programmable adjusting loop delay time by one cycle:
loop_delay - holds counts of additional nop cycles (by inverse order)

loop
    movlw   nop_table
    addwf   loop_delay, w
    movwf  PCL
nop_table
     nop
     nop
     .
     .
     .
     nop
     decfsz  loop_counter, f
     goto loop
end_of_loop




< Message edited by markul -- May 29, 2006 6:28:28 AM >

(in reply to Guest)
Post #: 12
RE: Clever and Useful tricks - May 29, 2006 10:44:25 AM   
K8LH
Experienced Hobbyist

 

Posts: 1545
Joined: Mar. 26, 2004
From: Michigan, USA
Status: offline
quote:

ORIGINAL: j_doin

Quite nice Mike. Although I have never seen Predko's snippets, this is from my lib:
SERIAL.print_hex:
 
     movwf       temp
     swapf       temp,w
     call        SERIAL.print_hex_digit
     movf        temp,w
 
SERIAL.print_hex_digit:
 
     andlw       0x0f
     addlw       0x06
     btfsc       DCARRY
     addlw       "A"-"9"-1
     addlw       "0"-0x06
     goto        SERIAL.print_char


It is essentially the same code as yours :-)


Very nice Jonny, much cleaner and more intuitive.

(in reply to Guest)
Post #: 13
RE: Clever and Useful tricks - Jun. 1, 2006 3:35:32 AM   
gloin

 

Posts: 175
Joined: Jun. 13, 2005
Status: offline
quote:

ORIGINAL: K8LH

I've always been amazed at the creative solutions for processing the quadrature A and B outputs from a Rotary Encoder (grin).  One simple method for determining encoder direction is to exclusive-or the previous encoder A or B bit reading with the opposite bit of the current encoder reading. 


[/code]
Have fun.  Regards, Mike


Hello Mike,

I m working on an encoder project, I want to count the pulses for cw and ccw direction, I wrote a code but still counting wrong with this code, could you give me a short example in C language, I couldnt understand the logic of your assembly code.

regards,  

Attachment (1)

_____________________________

Gloin

(in reply to K8LH)
Post #: 14
RE: Clever and Useful tricks - Jun. 1, 2006 3:47:40 AM   
Guest
quote:

ORIGINAL: K8LH

One simple method for determining encoder direction is to exclusive-or the previous encoder A or B bit reading with the opposite bit of the current encoder reading. 

As always your code is clean and direct Mike. You seem to think in terms of digital logic circuitry.

(in reply to K8LH)
  Post #: 15
RE: Clever and Useful tricks - Jun. 1, 2006 3:49:19 AM   
Guest
quote:

ORIGINAL: gloin

I m working on an encoder project, I want to count the pulses for cw and ccw direction, I wrote a code but still counting wrong with this code, could you give me a short example in C language, I couldnt understand the logic of your assembly code.

Hello gloin. May I suggest you to create a thread to discuss your problem?

(in reply to gloin)
  Post #: 16
RE: Clever and Useful tricks - Jun. 22, 2006 8:55:06 PM   
K8LH
Experienced Hobbyist

 

Posts: 1545
Joined: Mar. 26, 2004
From: Michigan, USA
Status: offline
A quick-n-dirty method for adding a serial port to that "one off" prototype board test circuit you're workin' on (the 3.5mm stereo jacks I use fit nicely in the prototype board 0.1" spaced holes).




Thumbnail Image


Attachment (1)

< Message edited by K8LH -- Jun. 22, 2006 9:08:59 PM >

(in reply to Guest)
Post #: 17
RE: Clever and Useful tricks - Jul. 16, 2006 11:15:01 AM   
K8LH
Experienced Hobbyist

 

Posts: 1545
Joined: Mar. 26, 2004
From: Michigan, USA
Status: offline
Software version of Xtal Oscillator Trimmer Capacitor

A 20-MHz crystal oscillator doesn't necessarily oscillate at exactly 20-MHz which can be a 'bummer' in RTC applications (grin).  Normally I would use a ceramic trimmer capacitor to 'tune' the oscillator circuit but last year I tried a "software" trimmer capacitor in a couple projects.  So far it's proven very reliable and accurate.

The "software" trimmer code consists of 8 instruction words in two locations within the ISR;
;
;  ISR_Trim routine is used to adjust the RTC 1-second period to
;  within plus or minus 200-nsecs to make up for a crystal which
;  may be slightly off frequency.  The routine adds or subtracts
;  one 200-nsec count (1 Tcyc) from Timer 2 for the first 'CCTR'
;  number of 1-msec interrupts each second. Theoretical accuracy
;  to within 6.3 secs/year, not including temperature drift and
;  crystal aging.
;
;   variables:  CCNT, correction count from EEPROM [00 to FF]
;               CVAL, correction value from EEPROM [FF or 01]
;               CCTR, correction counter reloaded from 'CCNT'
;                     variable each 1-second period
;
;       range:  ±255 200-nsec counts/second (±51.0 usecs/sec)
;
ISR_Trim
       movf    CCTR,W          ; correction counter 0?           |B0
       bz      ISR_Sw_Input    ; yes, branch, else               |B0
       decf    CCTR,f          ; decrement counter               |B0
       movf    CVAL,W          ; get correction value FF or 01   |B0
       addwf   TMR2,f          ; apply 1 Tcyc timer correction   |B0
;

I reset the CCTR 'correction counter' var with the CCNT 'correction count' value after each 1-second RTC period a little further down in my ISR;
;
;  the Real Time Clock 1-second 'heartbeat' timer/counter code
;  counts 1,000 1-msec interrupts before performing all of the
;  once-per-second procedures and functions
;
ISR_RTC    
       decfsz  RTCL,f          ; RTC counter lo = 0?             |B0
       goto    ISR_Calibrate   ; no, branch, else                |B0
       movlw   d'250'          ;                                 |B0
       movwf   RTCL            ; reset RTCL for 250-msecs        |B0
       decfsz  RTCH,f          ; all four 250-msec periods?      |B0
       goto    ISR_Calibrate   ; no, branch, else                |B0
       bsf     RTCH,2          ; reset RTCH for 4 (x 250)        |B0
;
;  reload timer Trim correction counter
;
       movf    CCNT,W          ; reload correction counter var   |B0
       movwf   CCTR            ;                                 |B0
;

A couple caveats apply when using the code; (1) writing to TMR2 clears the prescaler and postscaler but I don't use the prescaler and the postscaler hasn't yet incremented when I write TMR2, (2) You can apply the correction to shorter overall periods (100-msecs, 200-msecs, etc.) as long as the correction to your particular crystal can be accomplished within the shorter period.

Adjusting the CVAL 'correction value' and CCNT 'correction count' values and saving them to EEPROM is entirely up to you.  In one of my projects I use a PCB jumper to display the values, a rotary encoder to edit them, and then remove the PCB jumper to save the edited values back to EEPROM.

Have fun.  Kind regards, Mike

(in reply to K8LH)
Post #: 18
RE: Clever and Useful tricks - Jul. 18, 2006 1:34:07 AM   
Stokes

 

Posts: 733
Joined: Jul. 26, 2005
From: Australia, Sydney,N.S.W
Status: offline
Very nice.

(in reply to K8LH)
Post #: 19
RE: Clever and Useful tricks - Jul. 18, 2006 4:00:37 PM   
paulbergsman
5+ years with MCHP products

 

Posts: 1504
Joined: May 25, 2006
From: Merion Station, Penna.
Status: offline
I HAVE ATTACHED A SHORT NOTE TO AID YOU IN
MAKING A GOOD ENCODER


Attachment (1)

(in reply to K8LH)
Post #: 20
Page:   [1] 2 3 4 5   next >   >>
All Forums >> [Microcontroller Discussion Group] >> Tips and Tricks >> Clever and Useful tricks Page: [1] 2 3 4 5   next >   >>
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts


  Site Index  |  Legal Information  |  microchipDIRECT  |  Samples  |  Technical Support  |  Investor Information  |  Careers at Microchip  |  Contact Us  |  RSS Feeds ©2009 Microchip Technology Inc.  
  Shanghai ICP Recordal No.09049794  
Forum Software © ASPPlayground.NET Advanced Edition 2.5.5 Unicode

0.406