CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Output_Low in #asm

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bdrmachin
Guest







Output_Low in #asm
PostPosted: Sun Jan 24, 2010 8:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 25, 2010 2:00 am     Reply with quote

What is your PIC ?
Ttelmah
Guest







PostPosted: Mon Jan 25, 2010 3:40 am     Reply with quote

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








PostPosted: Mon Jan 25, 2010 7:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 25, 2010 1:18 pm     Reply with quote

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








PostPosted: Mon Jan 25, 2010 1:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 25, 2010 2:58 pm     Reply with quote

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:
Quote:
result = 6815

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








PostPosted: Mon Jan 25, 2010 4:07 pm     Reply with quote

You're the best!!!


Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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