How to set or clear individual bit of a register of PIC in asm code?

Status
Not open for further replies.
Code:
# define LDE PORTB,0

BSF  LED

BCF LED
OR

Code:
led   equ   0x01

BSF  PORTB,led
 
Last edited:

'bsf <file register>,<bit number>'. bsf = Bit Set in File register
'bcf <file register>,<bit number>'. bcf = Bit Clear in File register

You can #define the register names and bit names just as in 'C' but they are all included in the standard MPLAB header file for the processor, so if you #include it you can simply use register and bit names. For example:
bsf INTCON,GIE means set the GIE bit in the INTCON register. If you want to make life difficult for yourself you can use the register and bit number instead 'bsf 0x0B,7'.

Brian.
 

Thanks PA3040 and betwixt

I tried this but it gives error in MPLAB X + XC8


Code C - [expand]
1
2
3
4
5
6
7
8
#define LED LATAbits.LATA0
 
void led_toggle(){
 
      asm("bsf LED");
      asm("bcf LED");
 
}

 

I think it's because MPLAB uses different names for the pins. The one you used is specific to Mikroe products. Try "'#define LED LATA,0" instead.
If you look in the listing file (.lst) you should see the instructions convered to "bsf LATA,0" and "bcf LATA,0" respectively.


Brian.
 

betwixt LATAbits.LATA0 is specfic to XC8, C18, Hi-Tech C Compilers. For mikroC it is LATA0_bit. I tried all methods but still XC8 tells Syntax error.

This works in XC8


Code C - [expand]
1
2
asm("movlw 0x00");
asm("movwf PORTA");


but this gives syntax error

Code C - [expand]
1
2
3
#define LED LATAbits.LATA0
 
asm("bsf LED");



This also gives syntax error in XC8


Code C - [expand]
1
2
3
#define LED LATD,0
 
asm("bsf LED);

 
Last edited:

There IS a syntax error in the last code. You missed the closing quote mark in the brackets.

Here is an example taken from working code. The processor is a 16F628A:
Code:
	list      p=16f628A           ; list directive to define processor
	#include <p16F628A.inc>       ; processor specific variable definitions

	errorlevel  -302              ; suppress message 302 from list file

	__CONFIG   _CP_OFF & _CPD_OFF & _LVP_OFF & _BOREN_ON & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC

;***** PIN DEFINITIONS
#define BEEP		PORTA,0		;Output
#define HITAG_GREEN	PORTA,1		;Input, low when tag present
#define HITAG_CTS	PORTA,2		;Input, low when Hitag accepting commands
#define DATA_TO_HITAG	PORTA,3		;Output, 9600 bauds data to Hitag module
#define DEBUGPIN	PORTA,4		;note OD output!
#define DATA_FROM_HITAG	PORTB,0		;Input, 9600 bauds data from Hitag module
#define RX		PORTB,1		;Input, 38,400 bauds data from host
#define TX		PORTB,2		;Output, 38,400 bauds data to host
#define BUS_EN		PORTB,3		;Output, high to enable bus transmitter
#define MBX		PORTB,4		;Input, low when mailbox lid lifted
#define DOORBELL	PORTB,5		;Input, low when doorbell button is pressed
#define GATE_LED	PORTB,6		;Output, high to enable gate LED
#define UNLOCK		PORTB,7		;Output, high to open the gate lock

You can see some of the pins being used in this extract from the program:
Code:
main
	clrf	Events
	clrf	HWStatus
	bcf	UNLOCK			;must be locked at power up.
	clrf	RelockTimer
	clrf	BeepTimer		;silent at power up
	clrf	BellLockoutTimer
	bcf	GATE_LED		;light off at power up
	call	BusTxPrepare
	movlw	BusRxBuffer
	movwf	BusRxPtr		;point to start of buffer
	call	HitagSetup

You can see the pins defined as 'UNLOCK' and 'GATE_LED' being directly driven. The program is part of a contactless key entry system.

Brian.
 

betwixt is it for XC8 Compiler?

betwixt I am attaching my project. It is not working. Can you fix it, just the asm thing.
 

Attachments

  • XC8_LCD_4bit_PIC18F458_4MHz.rar
    125 KB · Views: 80
Last edited:

I want to replace all c doe inside the functions with asm code.
But why? Code size will be just the same for well considered C code.

Personally I'm using assembler code mainly in two situations:
- for special operations that aren't effectively coded by a compiler.
- to fix compiler bugs

Needless to say that I use to review the manuals for the required assembler syntax of the respective tool before.
 

@FVM Likewise, I use both. Timing critical applications or when space is really tight is for assembly, complex math is for compilers! I do occasionally write assembly routines inside C programs or even call C routines from within an assembly language routine but that's rare.

@Jayanth, it's written for MPLAB in pure assembly language, no compiler is used at all. If you want to replace only C functions with equvalent asm code, you will have to learn how stack calls are made and how parameter passing works if you want to make any progress. I warn you it can be quite complicated and there is no standard between different compilers.

I tried the code but my XC8 configuration threw so many errors I didn't go any further. The change I suggested is this though (at the end of the program):
Code:
	LCD_Out(4,1,"Working?");

	asm("bsf LED");
       
	while(1)
	{
		asm("clrwdt");
	}
	
	return (0);

so instead of the while(1) statement just looping on itself it clears the WDT each time.

Brian.
 

I'm not sure but it seems to be valid syntax for XC8 so it has to be something to do with the way LED is defined. I note you have commented out the definition and the usage in the program, is that to make it compile without errors? I'm still not sure why you are doing all this, it makes more sense to stay with either assembly language or with C. XC8 is designed to be a 'C' compiler and has a built in facility to add short sections of asm code but it isn't intended to be a full featured assembler. MPLAB and MPLABX handle assembly without even having XC8 on the computer.

All I can do is show you examples of working code. The following is the top of a program I wrote a while ago and below it a section showing an SPI interface to a video controller IC which uses some of the pin names:
Code:
#include <xc.h>
#include "eeprom_routines.h"
#include <string.h>
#include <stdio.h>



#pragma config FOSC=HS, WDTE=ON, PWRTE = ON, MCLRE_ON, CP=OFF, CPD=OFF, BOREN=ON, CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF
#pragma config WRT=OFF, PLLEN=OFF, STVREN=ON, BORV=HI, LVP=OFF

//***** SYSTEM CONSTANTS
#define _XTAL_FREQ 19660800
#define    BaudRate 38400
#define BRGVALUE (_XTAL_FREQ / (BaudRate * 64)) -1  //for BRGH = 0


//***** PIN DEFINITIONS
#define CLK5730        PORTAbits,RA0        //Output, clock to STV5730
#define CSN5730        PORTAbits,RA1        //Output, active low select to STV5730
#define DATA5730    PORTAbits,RA2        //Output, data to STV5730
#define SPARE0        PORTAbits,RA3        //Output, 
#define SPARE1        PORTAbits,RA4        //Output, 
#define NC1            PORTAbits,RA5        //Unavailable - used for -MCLR
#define    NC2            PORTAbits,RA6        //Unavailable - used for XTAL 
#define    NC3            PORTAbits,RA7        //Unavailable - used for XTAL
#define SPARE2        PORTBbits,RB0        //Output,
#define RX            PORTBbits,RB1        //Input, 38,400 bauds data from host
#define TX            PORTBbits,RB2        //Output, 38,400 bauds data to host
#define SPARE3        PORTBbits,RB3        //Output, 
#define SPARE4        PORTBbits,RB4        //Output,
#define CLK459        PORTBbits,RB5        //Output, SPI clock to MAX459
#define CSN459        PORTBbits,RB6        //Output, active low select to MAX459
#define DATA459        PORTBbits,RB7        //Output, data to MAX459

Code:
//***** 8-bit transfers to SPI devices
void SPI_OSD8(char SPIDataL)
{
    char Clocks = 7;
    unsigned char BitMask = 0x80;
    
    CSN5730 = 0;
        
    do
    {
        CLK5730 = 0;                            //SPI clock low while data changes
        if(BitMask & SPIDataL) DATA5730 = 1; //set or reset SPI data line
        else DATA5730 = 0;
        BitMask /= 2;
        CLK5730 = 1;                            //SPI clock high to latch data bit
    }while(Clocks-- != 0);

    CSN5730 = 1;                            //ensure devices are deselected
}

Brian.
 

What about asm("bsf LED"); ??
Why is it not working?
The question can be rephrased:
- What's the required syntax for symbolic C variables in XC8 inline assember expressions?
- Does it support bit structures in SFR access?

Personally, I'm motivated to dive into the assembly syntax details if the whole thing serves a reasonable purpose. I don't see it in the present case.
 

I think the answer is here: https://www.microchip.com/forums/m723144.aspx
(and I suspect I know who "internetuser2k11" might be :wink

XC8 does not allow defined names to be used in string literals so the "asm("bsf LED");" is not valid because it can't turn the "LED" into part of the string.

Brian.
 
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
I saw those answers at microchip but that #asm and #endasm thing gives error in my XC8 Compiler. I don't know why.
The post in microchip forum gives a plausible explanation why asm("bsf LED"); doesn't work.
It claims that preprocessor macros should work with #asm #endasm. But it does not confirm that the C syntax for bit structures is supported in assembler expressions.

The point is left to be found out by you.

By the way, I appreciate Dave's statement at microchip forum:
Knowing how to "do it in ASM" is one thing (Read the XC8 User's Guide). Knowing whether it is worthwhile making your program less portable and less maintainer-friendly by (interspersing the C code with Assembler instructions) is another.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…