PIC16f877a ASM ADDITION

Status
Not open for further replies.

jovin555

Advanced Member level 4
Joined
May 20, 2012
Messages
115
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Visit site
Activity points
2,036
I am new to pic asm coding.i am trying to do a simple addition in asm.but its not working.can anyone tell me the reason
Code:
        list       F=inhx8m, P=16F877a, R=hex, N=0
	#include P16F877a.INC ; PIC definitions
	 __config _HS_OSC & _WDT_OFF & _LVP_OFF;
	; __config _config2,_IESO_OFF & _FCMEN_OFF 
	;Errorlevel -302      ; switches off Message [302]: Register in operand not in bank 0.
	org		0x00
	goto	start    
; Interrupt Service Routine -----------------------------------------------
;	org     0x04               ; ISR beginning
; -------------------------------------------------------------------------
; Microcontroller initialization       
	org 	0x30
start:
	clrw
	clrf 	0x01
	clrf 	0x02
	clrf 	0x03
	movlw 	0x04
	movwf 	0x01
	movlw 	0x05
	movwf 	0x02
	addwf 	0x01,0x03
	NOP
	NOP
        end             ; end of program
 


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
start:
        clrw
        clrf    0x01
        clrf    0x02
        clrf    0x03
        movlw   0x04
        addlw   0x05
        movwf   0x02
        NOP
        NOP
        end

 



Hi,

Think Jayanth, although technically correct, he really is too quick off the mark.

Coding as you have done with all those numbers 0x01, 0x03 etc will just lead to utter confusion.


When you are using RAM to store data in, do not address them literally, but step up labels for them, as you can see from my code it is easy to follow provided you add comments as well.

You can see from the screenshot that MPLAB has a SIMulator function so you can run or step though your code and watch your registers being updated.

Also look at these tutorial for help with assembly code.

http://www.winpicprog.co.uk/pic_tutorial.htm

http://www.amqrp.org/elmer160/lessons/

**broken link removed**

Code:
       list       F=inhx8m, P=16F877a, R=hex, N=0
		#include P16F877a.INC ; PIC definitions
    	 __config _HS_OSC & _WDT_OFF & _LVP_OFF;
	; __config _config2,_IESO_OFF & _FCMEN_OFF 
	;Errorlevel -302      ; switches off Message [302]: Register in operand not in bank 0.

	org		0x00
	goto	start 
   
; Interrupt Service Routine -----------------------------------------------
;	org     0x04               ; ISR beginning
; -------------------------------------------------------------------------
; Microcontroller initialization       

	cblock	0x20		; set up user registers 
	numb1
	work1
	total
	endc

start:
	clrw
	clrf 	numb1
	clrf 	work1
	clrf 	total
	movlw 	0x04
	movwf 	numb1
	movlw 	0x05
	addwf 	numb1,F     ; add numb1 and value and  store result in register numb1
	movwf	total		; move result in 'total'
	NOP
	NOP
loop	
	goto	loop	   ; loop forever
    end                ; end of program CODE
 

Attachments

  • 000065.jpg
    92.5 KB · Views: 97
I am now trying to do eeprom write in pic asm .but not getting any output.can anyone check this code
Code:
	list       F=inhx8m, P=16F877a, R=hex, N=0
	#include P16F877a.INC ; PIC definitions
	 __config _HS_OSC & _WDT_OFF & _LVP_OFF;
	Errorlevel -302      ; switches off Message [302]:like Register in operand not in bank 0.
	org		0x00
	goto	start    
; Interrupt Service Routine -----------------------------------------------
;	org     0x04               ; ISR beginning
; -------------------------------------------------------------------------
; Microcontroller initialization       
	org 	0x0A
start:
	CLRW
	BSF		STATUS,RP1
	BSF		STATUS,RP0
	BTFSC	EECON1,WR
	GOTO	$-1
	BCF		STATUS,RP0
	MOVLW	0X01
	MOVWF	EEADR
	MOVLW	0XBB
	MOVWF	EEDATA
	BSF		STATUS,RP0
	BCF		EECON1,EEPGD
	BSF		EECON1,WREN
	BCF		STATUS,RP0
	BCF		INTCON,GIE
	BSF		STATUS,RP0
	MOVLW	55H
	MOVWF	EECON2
	MOVLW	0AAH
	MOVWF	EECON2
	BSF		EECON1,WR
	BSF		INTCON,GIE
	BTFSS	PIE2,EEIE
	GOTO	$-1
	BCF		EECON1,WREN
; Main Program ------------------------------------------------------------
    end             ; end of program
 

Hi,

Your code just shows the basic routine to write out data to location 01, you have not given it any data to store and you have not read any data back out of eeprom.

Though the datasheet does show some code examples they are not very clear or easy to understand.


Here is a simple code example of how to write one byte of data to eeprom location 0x00 and then read the data back for displaying on a port or similar.

You can use SIM to watch it happening.

Understanding every line of the eeprom Write code is not easy, so just try and see how the data goes in to the Write routine and how it comes out of the Read routine and the use of the eeprom Address, so that you can Increment it to store more data.

Its also possible to preload EEprom with data at programming time as shown in the third screenshot


Code:
       list       F=inhx8m, P=16F877a, R=hex, N=0
		#include P16F877a.INC ; PIC definitions
    	 __config _HS_OSC & _WDT_OFF & _LVP_OFF;
	; __config _config2,_IESO_OFF & _FCMEN_OFF 
	;Errorlevel -302      ; switches off Message [302]: Register in operand not in bank 0.

	org		0x00
	goto	start 
   
; Interrupt Service Routine -----------------------------------------------
;	org     0x04               ; ISR beginning
; -------------------------------------------------------------------------
; Microcontroller initialization       

	cblock	0x20		; set up user registers 
	numb1
	work1
	total
	endc

start:


	movlw	0x22			; load 0x22 into numb1 for storing in EEprom address 00
	movwf	numb1

	call	eeprom_write 	; wrtite data to eeprom

	call	eeprom_read		; read data from eeprom  datra is returned in W
	movwf	total			; store in total	
;	movwf	PORTD			; output data to portd leds , if used

loop	
	goto	loop	   ; loop forver
; ***************************************************************************
;	EEPROM Data restore

eeprom_read
	movlw	0x00			; load eeaddress 
	banksel	EEADR			; select bank2
	movwf	EEADR			; store address
	banksel	EECON1			; select bank3
	bcf		EECON1,EEPGD	; point to data memory
	bsf		EECON1,RD		; read
	banksel	EEDATA			; select bank2
	movfw	EEDATA			; read data to W
	banksel 0				; return to bank0

	return



; ****************************************************************************
;  	EEPROM	Data Write
eeprom_write						
	banksel 0
	movfw	numb1			; load data
	banksel	EEDATA
	movwf	EEDATA			; load numb1 to EEdata
	movlw	0x00			; load eeaddresss 00
	movwf	EEADR			;
	banksel	EECON1
	bcf		EECON1,EEPGD	; points to data memory
	bsf		EECON1,WREN		; enable write
	bcf		INTCON,GIE		; disable all ints
	movlw	0x55			;
    movwf	EECON2			; init write sequence
	movlw	0xAA			; using 2 instructions	
	movwf	EECON2			;
	bsf		EECON1,WR		; write data
	bsf		INTCON,GIE		; turn ints back on
	banksel 0				; select bank0	
wd01 btfss	PIR2,EEIF		; is int bit on ie WRTDONE
	goto	wd01			; if done continue
	bcf		PIR2,EEIF		; reset interupt
 	banksel	EECON1
	bcf		EECON1,WREN		; disables write
	banksel	0				; select bank0

	return


	
    end                ; end of program CODE
 

Attachments

  • ScreenShot001.jpg
    103.9 KB · Views: 102
  • ScreenShot002.jpg
    112 KB · Views: 101
  • ScreenShot003.jpg
    85.2 KB · Views: 106

the code is working.its working only when i do run in mplab. but if try to do step by step excecution its not working.My code also had the same problem.i tried to do it by step by step execution.but when i run it its working.can you tell me the reason for that?
 

Hi,

So it works ok in SIM if you RUN F9 the code.

You do not say what is happening when you SINGLE STEP F7, but I think you may find it appear to just go round this little loop as shown in the screen shot.
This is where the system is waiting to the data to be actually written into eeprom , which is in Micro terms a slow process.

If you move your cursor to the lines show and Right Click, you get a menu, then click SET BREAKPOINT on each line.

You can then single step or run until it reraches the first breakpoint, Sim will then stop, so you can then RUN and it will complete that section of code at full speed and then stop at the second brealpoint so you can continue in Step mode.

If its not that then say exactly whats happening and include a screenshot if needed.
 

Attachments

  • 000076.jpg
    20.7 KB · Views: 106

What you mentioned was right.i get it looping around these statements
bcf PIR2,EEIF ; reset interrupt
banksel EECON1
so it will take lot of time to complete this writing process.and that's why its looping around.Am i right?
 

Hi,

Its the wd01 btfss PIR2.EEIF that is the loop.

After the Write to Eeeprom is started by the EECON1,WR, it takes, micro wise, a longish time to actually write the data.

When the Write has completed it turns the EEIF bit of the PIR2 register on, so the simplest way is to sit there testing the EEIF bit until it goes high.
Once it does, the next instruction Clears the EEIF bit back to zero ready for the next write.


Code:
        bsf		EECON1,WR		; write data
	bsf		INTCON,GIE		; turn ints back on
	banksel 0				; select bank0	
[U]wd01 btfss	PIR2,EEIF		; is int bit on ie WRTDONE
	goto	wd01			; if done continue[/U]]
	bcf		PIR2,EEIF		; reset interupt
 

ok.i understood that.Next after eeprom comes writing and reading to flash memory in pic16f877a datasheet.Is there any use with that.since what we are writing in asm is already saved in flash memory.then why we should write it separately? And also how to write configuration register in asm?how to define its bits in asm coding?

also i want to store data(eg 0xaa) at ram locations 120h to 127h.so how to do it using indirect addressing?Can u give me the code?
Code:
	list       F=inhx8m, P=16F877a, R=hex, N=0
	#include P16F877a.INC ; PIC definitions
	 __config _HS_OSC & _WDT_OFF & _LVP_OFF;
	Errorlevel -302      ; switches off Message [302]:like Register in operand not in bank 0.
	org		0x00
	goto	start    
; Interrupt Service Routine -----------------------------------------------
;	org     0x04               ; ISR beginning
; -------------------------------------------------------------------------
; Microcontroller initialization       
	org 	0x30
start:
    movlw   0x120	;to store the starting address into fsr
    movwf   FSR		;FSR stores the address like a pointer and indf moves the
    movlw	0xAA    ; data to that address
NEXT:
    MOVWF	INDF	;to store the data in the address stored in FSR
    INCF	FSR,F 	;increment FSR to next address
    BTFSS	FSR,3	;to check if address has reached 0x127
    GOTO	NEXT
    MOVLW	0x20
    MOVWF	FSR
    NOP
; Main Program ------------------------------------------------------------
    end             ; end of program

i have tried this code.but its writing at location 20h to 27h.so how can i change it?
 
Last edited:


Hi, Jovin...

What we are doing is writing the program to the flash memory. If we want to write any data in flash memory we can do it...

Configuration word is having an Address 2007H which is not accessible. It can only be written while programming. For that we can use _config directive
 

    V

    Points: 2
    Helpful Answer Positive Rating


Hi,


You can write to flash ( program) memory but its not something I have done and its not often you see programs with that.

Think for now you should skip that function.

For addressing ram menory 120 -7 It goes back to what I originally said, you should, typically, use names/labels for your registers, not direct addresses.

( though you can use the FSR it does not really apply to the simple functions you are trying to do, again perhaps leave that one till you understand the basics a bit better.
It can get a bit complex setting up the FSR values and the auto incrementing etc)

So you first set up your registers

cblock 0x127
name1
name2
name3
endc

When you come to use one of these registers then you need to specify the bank 2 they are in

movlw 0xAA
banksel name1
movwf name1


You have the 3 most important Config statements specied, all the other are running on default values.
Full details are here / plus look at the pic16f877a.inc and pic16f877a.temp files found in the Mplab ASM directories.

https://www.edutek.ltd.uk/Binaries/Datasheets/Micro/PICDeviceConfig.pdf
 

    V

    Points: 2
    Helpful Answer Positive Rating
how is it possible to store address 120h in fsr?
 


I tried to write to flash program memory..But can write only to specific locations.. Is there any special sequence to follow?
 

the following code is used to write and read to flash memory

Code:
	list       F=inhx8m, P=16F877a, R=hex, N=0
	#include P16F877a.INC ; PIC definitions
	 __config _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _BODEN_OFF & _PWRTE_OFF & _LVP_OFF & _WDT_OFF & _HS_OSC 
	 ;code protection off & incircuit debugging mode off &
	 ;flash memory write protection off & data eeprom code protection off &
	 ;BROWN OUT RESET OFF & POWER UP TIMER ENABLE BIT OFF
	 ;WATCHDOG TIMER OFF & 	HIGH SPEED CRYSTAL
	Errorlevel -302      ; switches off Message [302]: Register in operand not in bank 0.
	ORG		0x00
	GOTO	start    
; Interrupt Service Routine -----------------------------------------------
;	org     0x04               ; ISR beginning
; -------------------------------------------------------------------------
; Microcontroller initialization       
	ORG 	0x0A
start:
; to read flash memory
	CLRW
	BSF		STATUS,RP1
	BCF		STATUS,RP0	;to select bank2
	MOVLW	0X00
	MOVWF	EEADRH		;the msb of program address to be read
	MOVLW	0X0D
	MOVWF	EEADR		;the lsb of program address to be read
	BSF		STATUS,RP0	;bank3
	BSF		EECON1,EEPGD;to point to program memory
	BSF		EECON1,RD	;to start read cycle
	NOP
	NOP					;program memory should be read in two cycles
	BCF		STATUS,RP0	;bank 2
	MOVF	EEDATA,W	;to move lsb data read from memory to ram 
	MOVWF	0X122		;opcode of the instruction will be saved in ram
	MOVF	EEDATH,W
	MOVWF	0X123		;to move lsb data read from memory to ram 
	;THE FOLLOWING DATA STORED IN RAM WILL BE WRITTEN TO FLASH MEMORY
	BCF		STATUS,RP1
	BCF		STATUS,RP0
	MOVLW 	0X17
	MOVWF	0X20
	MOVLW	0X03  
	MOVWF	0X21			;1703 IS THE OPCODE FOR BSF STATUS,RP1
	MOVLW 	0X01
	MOVWF	0X22
	MOVLW	0X03	
	MOVWF	0X23			;0103 IS THE OPCODE FOR CLRW
	
	;TO WRITE FLASH MEMORY WE MUST WRITE 4 WORD BLOCKS OF DATA
	;HERE FLASH MEMORY ADDRESS USED ARE FROM 0050 TO 0053
	;THE FIRST TWO INSTRUCTIONS OF MY CODE ARE WRITTEN TO FLASH MEMORY
	;THE NEXT TWO WILL BE NOP INSTRUCTIONS
	; to write flash memory		
	BSF		STATUS,RP1
	BCF		STATUS,RP0		;BANK2
	MOVLW	0X00
	MOVWF	EEADRH			;TO STORE MS BYTE OF FIRST ADDRESS ie 00 OF 0050
	MOVLW	0X50
	MOVWF	EEADR			;TO STORE LS BYTE OF FIRST ADDRESS ie 50 OF 0050
	MOVLW	0X20
	MOVWF	FSR				;TO STORE STARTING ADDRESS OF RAM IN FSR
LOOP:
	MOVF	INDF,W
	MOVWF	EEDATH			;TO STORE MS BYTE OF DATA IN EEDATH
	INCF	FSR,F
	MOVF	INDF,W
	MOVWF	EEDATA			;TO STORE LS BYTE OF DATA IN EEDATH
	INCF 	FSR,F
	BSF		STATUS,RP0
	BSF		EECON1,EEPGD	;TO POINT TO FLASH MEMORY
	BSF		EECON1,WREN		;TO ENABLE EEPROM WRITE
	BCF		INTCON,GIE		;INTERRUPTS SHOULD BE OFF
	MOVLW	55H
	MOVWF	EECON2			;THE REQUIRED SEQUENCE FOR WRITE
	MOVLW	0AAH
	MOVWF	EECON2			;THE REQUIRED SEQUENCE FOR WRITE
	BSF		EECON1,WR		;INITIATES A WRITE CYCLE
	NOP
	NOP						;PROCESSOR REQUIRES TWO CYCLES TO INITIATE WRITE CYCLE
	BCF		EECON1,WREN		;INHIBITS WRITE TO EEPROM
	BSF		INTCON,GIE		;ENABLE INTERRUPTS
	BCF		STATUS,RP0
	INCF	EEADR,F			;INCREMENT EEADR TO NEXT LOCATION
	MOVF	EEADR,W
	XORLW 	0X54			;TO CHECK IF EEADR HAS REACHED 0053	
	BTFSS	STATUS,Z
	GOTO 	LOOP	
; Main Program ------------------------------------------------------------
    END             ; end of program
 

I tried to write to flash program memory..But can write only to specific locations.. Is there any special sequence to follow?


Hi,

Do you really mean Flash memory where your program code is placed, normally by a Programmer device, or to RAM or EEPOM data memories.

If you post the code you are using we can better see what you mean.

- - - Updated - - -

=jovin555;1275912]the following code is used to write and read to flash memory

Hi,

Assume ? that is some code you found, do you know who the author is ? - it is always good to give credit where its due.

Have run the code in SIM and it does appear to work ok, but as you can see its still is lot of program code to rewrite the program code, rather than have a simpler conditional option within your program code anyway.

Have never had reason to want to use this function though clearly there must be many who do want it otherwise why make available ?

Perhaps some of the professional forum members might be able to give us some idea of when this feature is helpful ?
 

Attachments

  • 000078.jpg
    155.1 KB · Views: 89
  • 000079.jpg
    151.3 KB · Views: 89

Actually i followed what was there in pic16f877a datasheet.thats what my code is.
 

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…