|
|
View previous topic :: View next topic |
Author |
Message |
bdrmachin Guest
|
Output_Low in #asm |
Posted: Sun Jan 24, 2010 8:42 pm |
|
|
I have a small program that reads 4 DS18b20 One_Wire parts using Port E Pin 0. I call that pin DQ using the following line
Code: | #define DQ PIN_E0
output_Low(DQ);
output_float(DQ);
|
I would like to change this to a variable so I could use a second pin to address a different array of DS18b20's. Passing a variable to output_low() throws the time off too much.
I know assembly code but I don't know how to properly embed it in C.
Would someone please show me how to pass a variable to assembly and toggle the TRIS_EX bit, X being the contents of the passed Variable.
Thank Much |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 25, 2010 2:00 am |
|
|
What is your PIC ? |
|
|
Ttelmah Guest
|
|
Posted: Mon Jan 25, 2010 3:40 am |
|
|
If you are using 'fast_io', then the output_low, and output_high instructions, code as a single assembler instruction. You aren't going to do any better.....
The 'generic' allow a pin to be selected code versions, take a long time, because it is quite complex to work out what registers are needed - the basic code inside the operation, is 'assembler', so again nothing to be gained.
The 'key' normally in this situation, is to not try to be 'generic'. If (for instance), you code:
Code: |
#define PINTOUSE_A PIN_E0
#define PINTOUSE_B PIN_E2
#define PIN_A false
#define PIN_B true
void output_low_pinAB(int1 pin) {
if (pin) output_low(PINTOUSE_B);
else output_low(PINTOUSE_A);
}
|
Then you can use 'output_low_pinAB(PIN_A)' (or pin B), with a simple true/false variable, and select between two pins. When compiled, you get only three extra instruction times, which is as good as an assembler solution....
If you leave standard_io enabled, then TRIS will be toggled for you, at the cost of another instruction.
If you just want to change TRIS, and not actually output data, then you can just use output_float, instead of output_low.
Remember also, that you can define a bit of a TRIS register, using the #bit operand, and just set this tue/false, for a single instruction solution.
#ASM, in CCS, does allow you to embed assembler, but _not_ MicroChip assembler. So even if you have the code already written in 'assembler', unless it is in CCS assembler, it _will_ need to be re-written. Given that with careful instruction choice, you can matsh the assembler solution directly in C, why not just do it this way?....
Best Wishes |
|
|
Guest
|
|
Posted: Mon Jan 25, 2010 7:00 am |
|
|
Thanks Ttelmah I'll give it a try.
The part is a 18f4620.
The way I interface to the 1-Wire port is to change the port pin to input using output_float(DQ) so it floats high or execute a output_low(DQ).
I'm open to any thing at this point, though I would still like to see a #ASM example of so I can understand how variables are passed and returned. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 25, 2010 1:18 pm |
|
|
This shows how to get values in and out of an #asm block.
If you don't want to manipulate the data after the #asm block ends,
you can return a value by putting it into the special _RETURN_
variable. This is in the manual.
Code: |
#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
int8 my_func(int8 value)
{
int8 temp;
temp = 1;
#asm
movf value,W // W = value
addwf temp // temp = W + temp
#endasm
temp++;
return(temp);
}
//======================================
void main(void)
{
int8 result;
result = my_func(0x55);
printf("result = %x", result);
while(1);
} |
|
|
|
Guest
|
|
Posted: Mon Jan 25, 2010 1:59 pm |
|
|
Thanks Much "PCM programmer"
This should help a lot to clear things up. I have one last question:
How would you pass and / or return a 16bit variable? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 25, 2010 2:58 pm |
|
|
I guess you want to know how to access the msb byte in CCS ASM code.
You have to convert it to a byte pointer and then add 1 to it. Example:
Note: Instead of putting the syntax directly into the code, I made it into
a 'BYTE_PTR' macro. The MPLAB simulator gives the following result
(in Hex) for this program:
Code: |
#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define BYTE_PTR(x) &(int8 *)(x)
int16 my_func(int16 value)
{
int16 temp;
int16 retval;
temp = 0x55E0;
#asm
MOVF value, W // W = value (lsb)
ADDWF temp, W // W = W + temp (lsb)
MOVWF retval // retval (lsb) = W
MOVF BYTE_PTR(value) +1, W // W = value (msb)
ADDWFC BYTE_PTR(temp) +1, W // W = W + temp (msb) + CY
MOVWF BYTE_PTR(retval) +1 // retval (msb) = W
#endasm
retval++;
return(retval);
}
//======================================
void main(void)
{
int16 result;
result = my_func(0x1234);
printf("result = %lx", result);
while(1);
}
|
|
|
|
Guest
|
|
Posted: Mon Jan 25, 2010 4:07 pm |
|
|
You're the best!!!
Thanks |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|