Adding ASM code to C program

Status
Not open for further replies.

Andy_123

Member
Please excuse my stupidity, but I never used C for PIC programming and all my projects are in ASM

Here is what I need:

I have simple code in asm that I am using with my device.

This code is interrupt driven and works just fine for a long time.
I want to add USB connection so I can change some parameters from PC without recompling the code plus have some visualization.

I took Microchip USB host sample and got it working with VB6 application.
This code is in "C" . I stripped it down enough and I know how to pass values from PIC to PC .

Now difficult part - I need to merge two programs, particulary Interrupt section.
I am trying to insert asm code into MAIN.C using _asm _endasm, but I can't fugure out how to declare variables to the same memory area so I can access them from the main loop and interrupt routine.

So if anyone can show me a quick example I really appreciate this.
Thanks
 

Attachments

  • main.zip
    2.2 KB · Views: 132
Last edited:
Not sure if you are talking C18 or C30, but I looked. Try page 166 at the below link for details.

**broken link removed**
 
Thanks for link, I think this will move forward!
I am using C18, I should find the same manual for C18 I guess...
 
Hi Andy,

Have you considered just doin' the interrupt code in C? Please note I didn't spend any time on the INT_MARKER line. Sorry. But hopefully you've got enough info' to determine if you want to try to code it in C.

Good luck. Have fun. Regards, Mike

Code:
unsigned char DIRECTION = 0;
unsigned char FINAL_REG = 0;
unsigned int  COUNTER = 0;
unsigned int  MAX_COUNT = 0;

/*****************************************************************
 *  setup interrupt vectors                                      *
 *****************************************************************/
#pragma code high_interrupt = 0x08
void high_interrupt (void)
{ _asm goto isr_hi _endasm
}

#pragma code

/*****************************************************************
 *  ISR (high)                                                   *
 *****************************************************************/
#pragma interrupt isr_hi

void isr_hi ()
{ if (INTCONbits.TMR0IF = 1)
  { DIRECTION = PORTB;                  //
    if ( DIRECTION && 0b00000100 )      // if enabled
    { if ( DIRECTION && 0b00000010 )    // if increment
      { if (!(FINAL_REG >>= 1))         //   "rrncf FINAL_REG,F"
          FINAL_REG = 0b10000000;       //
        while ( COUNTER++ == MAX_COUNT) //
          COUNTER = 0;                  //
      }
      else                              // else decrement
      { if (!(FINAL_REG <<= 1))         //   "rlncf FINAL_REG,F"
          FINAL_REG = 0b00000001;       //
        while ( COUNTER-- == 0)         //
          COUNTER = MAX_COUNT;          //
      }
      if ( COUNTER && 0b11111110 )      // INT_MARKER ???  Huh?
      { FINAL_REG |= 0b00010000;        //   "bsf FINAL_REG,4"
        FINAL_REG &= 0b11011111;        //   "bcf FINAL_REG,5"
      }
      else
      { FINAL_REG &= 0b11101111;        //   "bcf FINAL_REG,4"
        FINAL_REG |= 0b00001000;        //   "bsf FINAL_REG,5"
      }
      LATA = FINAL_REG;                 //
    }
    INTCONbits.TMR0IF = 0;              //
  }
}
 
Last edited:
Thanks for ideas Mike,

Yes, I considered this, but I was not sure if C compiler can make interrupt code fast.

In my code interrupt coming from input and signal frequency can reach 200KHz.
So I need to have interrupt code as short (and fast) as possible so I have time to serve USB requests.

I guess I should try.
 
Mike
I will try your code, here is one place I am not sure about, like I said, I did not use "C" so sorry do stupid questions...


INT_MARKER:
movlw b11111110
andwf COUNTER+0,w
iorwf COUNTER+1,w

Actually checks value 0<=COUNTER<=X

if this case x=1, but it can be 0,1,3,7 to increase marker with to 1,2,4 or 8 pulses - this is one parameter I want to change with USB

If within limits, then set marker, if not reset.

So what will be best C code for this check?
 
I was confused by that bit of code. Sorry.

If you're simply testing a value and setting a flag of some sort then why not simply do that (grin);

Code:
  if ( COUNTER = TESTVALUE )
    MARKER = 1;
  else
    MARKER = 0;
 
No I am testing for COUNTER to be within a range between 0 and TESTVALUE

MARKER is actualy 2 bits (01 or 10) within a FINAL_REG.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…