I'm working with Hi-Tech C on a 16C73 project where I have to do some
arithmetic on a 16-bit value - specifically the hi and lo bytes of the
capture register CCPR1(H and L).
How can I smash, concatenate, whatever the two 8-bit hi and low bytes into a
16-bit one? I'm guessing I need to shift them in. Or would it be more
efficient to work with the hi and low bytes separately. Specifically, I'm
trying to figure out the delta of two samples and I thought it would be
easier to work with it as a single int value.
Now capture has the value I want to play with. If capture is a local (auto)
variable, you need to change the _capture to something in a slightly different
format
_routine$capture (for 7.85)
_routine_captuer (for 7.84 and earlier)
I'm working with Hi-Tech C on a 16C73 project where I have to do some
arithmetic on a 16-bit value - specifically the hi and lo bytes of the
capture register CCPR1(H and L).
How can I smash, concatenate, whatever the two 8-bit hi and low bytes into a
16-bit one? I'm guessing I need to shift them in. Or would it be more
efficient to work with the hi and low bytes separately. Specifically, I'm
trying to figure out the delta of two samples and I thought it would be
easier to work with it as a single int value.
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Your 16 bit total will then reside in myvar.total</FONT>
</P>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">I try and use these constructs to stay away from inline asm wherever possible, but sometimes it really is needed. You can use this method to access bits in a char or int as well. Have a look on HiTechs FAQ page at<U> <A HREF="http://www.htsoft.com/" TARGET="_blank">http://www.htsoft.com/</A></U> for more details.</FONT></P>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Hope that helps</FONT>
</P>
union intchar /* define the union variable type */
{
struct
{
unsigned char lo;
unsigned char hi;
}byte;
unsigned int total;
}
union intchar myvar; /* declare the variable */
To use this you would load the two halves as follows:
myvar.byte.lo = CCPR1L;
myvar.byte.hi = CCPR1H;
Your 16 bit total will then reside in myvar.total
I try and use these constructs to stay away from inline asm wherever
possible, but sometimes it really is needed. You can use this method to
access bits in a char or int as well. Have a look on HiTechs FAQ page at http://www.htsoft.com/ for more details.
> union intchar /* define the union variable type */
I thought about a union too. It, for some late night reason, seemed clunky.
But now that I see it after some rest, it doesn't look too bad. I may try a
few options and see what I get out when it compiles.
> I try and use these constructs to stay away from inline asm wherever
possible, but sometimes it really is
> needed. You can use this method to access bits in a char or int as well.
Have a look on HiTechs FAQ page at
> http://www.htsoft.com/ for more details.
Forgot to go to the FAQ - perused the PIC archives and Hi-Tech's on-line
discussions.
> At one time I believe I checked and found the HTC generated comparable
code to
> what I proposed in assembly.
>
> I think it does this correctly:
>
> int counter;
> counter = (CCPR1H << 8) | (CCPR1L);
>
This is what I thought could be done. While the union gives me access to all
the entities, I'll have to further look to see I need the hi and low order
bytes when I'm done. Chances are, no.
Question for Andy - is the above example what you found to be comparable to
the assembly routine you posted? Unfortunately I'm not at my dev machine
right now to try it out.
> union intchar /* define the union variable type */
I thought about a union too. It, for some late night reason, seemed clunky.
But now that I see it after some rest, it doesn't look too bad. I may try a
few options and see what I get out when it compiles.
> I try and use these constructs to stay away from inline asm wherever
possible, but sometimes it really is
> needed. You can use this method to access bits in a char or int as well.
Have a look on HiTechs FAQ page at
> http://www.htsoft.com/ for more details.
Forgot to go to the FAQ - perused the PIC archives and Hi-Tech's on-line
discussions.
> At one time I believe I checked and found the HTC generated comparable
code to
> what I proposed in assembly.
>
> I think it does this correctly:
>
> int counter;
> counter = (CCPR1H << 8) | (CCPR1L);
>
This is what I thought could be done. While the union gives me access to all
the entities, I'll have to further look to see I need the hi and low order
bytes when I'm done. Chances are, no.
Question for Andy - is the above example what you found to be comparable to
the assembly routine you posted? Unfortunately I'm not at my dev machine
right now to try it out.
part 0 2198 bytes <P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Ok, been doing a bit of fiddling.</FONT>
</P>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">I found an include that I downloaded while back, but never really looked at. Amongst other stuff, the file defines the following:</FONT></P>
part 0 5383 bytes <P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Andy Kunz proposed:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial">> At one time I believe I checked and found the HTC generated comparable</FONT>
<BR><FONT SIZE=2 FACE="Arial">code to</FONT>
<BR><FONT SIZE=2 FACE="Arial">> what I proposed in assembly.</FONT>
<BR><FONT SIZE=2 FACE="Arial">></FONT>
<BR><FONT SIZE=2 FACE="Arial">> I think it does this correctly:</FONT>
<BR><FONT SIZE=2 FACE="Arial">></FONT>
<BR><FONT SIZE=2 FACE="Arial">> int counter;</FONT>
<BR><FONT SIZE=2 FACE="Arial">> counter = (CCPR1H << 8) | (CCPR1L);</FONT>
<BR><FONT SIZE=2 FACE="Arial">></FONT>
</P>
</UL>
<P><FONT SIZE=2 FACE="Arial">David E. Olson replied:</FONT>
</P>
<UL>
<P><FONT SIZE=2 FACE="Arial">This is what I thought could be done. While the union gives me access to all</FONT>
<BR><FONT SIZE=2 FACE="Arial">the entities, I'll have to further look to see I need the hi and low order</FONT>
<BR><FONT SIZE=2 FACE="Arial">bytes when I'm done. Chances are, no.</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">Question for Andy - is the above example what you found to be comparable to</FONT>
<BR><FONT SIZE=2 FACE="Arial">the assembly routine you posted? Unfortunately I'm not at my dev machine</FONT>
<BR><FONT SIZE=2 FACE="Arial">right now to try it out.</FONT>
</P>
</UL>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Andy Kunz came back with:</FONT>
<UL>
<P><FONT SIZE=2 FACE="Arial">Yes, this is the C that I believe generated the good code. I can't test now</FONT>
<BR><FONT SIZE=2 FACE="Arial">myself either :-(</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">Boating season is here!</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">Andy</FONT>
</P>
</UL>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">It certainly would make a neat macro if it worked. However, I've just tried it on V7.85, compiling for a 16F877 with maximum optimisation and it got it's knickers in a twist:</FONT></P>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">This is moving the CCPR1H and CCPR1L registers in a global unsigned int called "count"</FONT>
</P>
<P> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">movf 21,w ;volatile</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">movwf btemp+1</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">clrf btemp</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">movf 22,w ;volatile</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">iorwf btemp,w</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">movwf _count</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">movf btemp+1,w</FONT>
<BR> <FONT COLOR="#0000FF" SIZE=2 FACE="Arial">movwf _count+1</FONT>
<BR><FONT COLOR="#0000FF" SIZE=2 FACE="Arial"> </FONT>
<BR><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">As all registers are in bank 0, this should boil down to 4 instructions, with no temps being needed. Any comments Clive if you're listening?</FONT></P>
On Wed, Mar 22, 2000 at 09:51:16AM -0000, Michael Rigby-Jones wrote:
> It certainly would make a neat macro if it worked. However, I've just tried
> it on V7.85, compiling for a 16F877 with maximum optimisation and it got
> it's knickers in a twist:
You didn't show your C code, but here's what I tried:
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">I was sure I must be doing something screwy here, so I have re-installed V8.75 just to make sure I had the right version and the results are the same.</FONT></P>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Your idea of using it directly is superb, I just wouldn't have thought of that. However it obviously only works in the minority of cases, a more general solution is needed for most jobs.</FONT></P>
I was going to reply to Michael's comment that his compiler barfed over this
statement - when I did it worked fine. Had me worried until I read the other
posts.
However...
> static unsigned int CCPR1 @ 0x15;
This looks even cooler. Got to love it when folks want to try to optimize a
seemingly innocuous function.
>Your idea of using it directly is superb, I just wouldn't have thought of
that. However it obviously
> only works in the minority of cases, a more general solution is needed for
most jobs
Michael - are you saying that either CCPR1 is not adjacent in all pics or
it's not at 0x15?
<P><FONT SIZE=2 FACE="Arial">I was going to reply to Michael's comment that his compiler barfed over this</FONT>
<BR><FONT SIZE=2 FACE="Arial">statement - when I did it worked fine. Had me worried until I read the other</FONT>
<BR><FONT SIZE=2 FACE="Arial">posts.</FONT>
</P>
</UL>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">Well, it's got me well and truly worried. I just can not get this to work no matter what I do. Are you using the compiler through MPLAB or are you using the HPDPIC IDE? I have to admitt, I have been seeing some odd things recently...</FONT></P>
<UL>
<P><FONT SIZE=2 FACE="Arial">However...</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">This looks even cooler. Got to love it when folks want to try to optimize a</FONT>
<BR><FONT SIZE=2 FACE="Arial">seemingly innocuous function.</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">>Your idea of using it directly is superb, I just wouldn't have thought of</FONT>
<BR><FONT SIZE=2 FACE="Arial">that. However it obviously</FONT>
<BR><FONT SIZE=2 FACE="Arial">> only works in the minority of cases, a more general solution is needed for</FONT>
<BR><FONT SIZE=2 FACE="Arial">most jobs</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">Michael - are you saying that either CCPR1 is not adjacent in all pics or</FONT>
<BR><FONT SIZE=2 FACE="Arial">it's not at 0x15?</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">-DO</FONT>
</P>
</UL>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">No, I'm saying that using this method is great for the case of grabbing a 16 bit result from a peripheral that happens to have the hi-lo bytes adjacent and in the right sequence. There are other times when you may want to construct an 16 bit integer from two bytes where this just is not applicable, for instance building a 16 bit value from the two 8 bit SPI transfers of an ADC.</FONT></P>
<P><FONT COLOR="#0000FF" SIZE=2 FACE="Arial">AFAIK CCPR1 will have it's registers in the same place on any particular PIC family.</FONT>
</P>
> Well, it's got me well and truly worried. I just can not get this to work
no matter what I do.
> Are you using the compiler through MPLAB or are you using the HPDPIC IDE?
I have to admitt,
> I have been seeing some odd things recently...
Nope. Using it standalone and through a Mathias. I'm up to 7.85. I got it to
work through TDE from Tech-Tools. No extra optimization flags either. Just
plain build and emulate. Could it be PIC dependent? I'm specifically using
the 16C73A emulation (even though the target chip will be a 73B - wish Tech
Tools supported the 73B!).
> No, I'm saying that using this method is great for the case of grabbing a
16 bit result from a peripheral that
> happens to have the hi-lo bytes adjacent and in the right sequence. There
are other times when you may
> want to construct an 16 bit integer from two bytes where this just is not
applicable, for instance building a
> 16 bit value from the two 8 bit SPI transfers of an ADC.
> AFAIK CCPR1 will have it's registers in the same place on any particular
PIC family.
<start rant>
Please turn off the switch that makes HTML code when posting to the
Piclist. Especially when you include code to
try. While blue text is nice, it's really a hassle to cut out the HTML
stuff when your recipient want to try your code.
It also expands the size of your message by at least a factor of 2.
<end rant>
Regards,
Jim Ham
At 11:15 AM 3/22/2000 -0000, you wrote:
> How embarrasing. OK, I've just tried this code:
><> unsigned int count; void main( )
<snip>
Jim Ham, Porcine Associates
(650)326-2669 fax(650)326-1071
"http://www.porcine.com"
I just tried Michael Rigby-Jones' code and confirmed his results - 10
instructions. (V7.85 with a code generator only a couple of weeks old). I
know I have seen the four instruction sequence in the past, but the test
code certainly doesn't generate it.
Regards,
Jim Ham
At 08:55 PM 3/22/2000 +1000, you wrote:
>On Wed, Mar 22, 2000 at 09:51:16AM -0000, Michael Rigby-Jones wrote:
>> It certainly would make a neat macro if it worked. However, I've just
tried {Quote hidden}
>> it on V7.85, compiling for a 16F877 with maximum optimisation and it got
>> it's knickers in a twist:
>
>You didn't show your C code, but here's what I tried:
>
>;x.c: 7: count = (CCPR1H << 8) + CCPR1L;
> movf 22,w ;volatile
> movwf _count+1
> movf 21,w ;volatile
> movwf _count
>
>Looks fine to me.
>
>
> I just tried Michael Rigby-Jones' code and confirmed his results - 10
> instructions. (V7.85 with a code generator only a couple of weeks old). I
> know I have seen the four instruction sequence in the past, but the test
> code certainly doesn't generate it.
> Jim Ham
>
> >You didn't show your C code, but here's what I tried:
> >;x.c: 7: count = (CCPR1H << 8) + CCPR1L;
> > movf 22,w ;volatile
> > movwf _count+1
> > movf 21,w ;volatile
> > movwf _count
> >
> >Looks fine to me.