Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

need to understand about serial reception interrupt, plz hlp

Status
Not open for further replies.

peter002

Member level 3
Joined
Mar 18, 2013
Messages
56
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Hindusthaan
Activity points
1,765
helo elder brothers,

i m using the pic16f877a to communicate with the sim800 modem,
i am using assembly for the programming..

i have succesfully paired it and checked the at and other commans and they are working properly.

now i need to use the reception interrupts..
i just need to know that do i have to follow the below procedure to get the reception interrupt working???

set bit7th and 6th of intcon register
and then set pie1,rcie and wait for it to be cleared,
if it is found cleared then it means RCREG has got the received byte and I HAVE TO set rcie again for the next reception..

means when ever the byte is received the rcie is cleared??? and i have to set it again to detect next reception?

is that all or m i wrong somewhere??

thanx in advace
 
Last edited:

Sorry, but you are wrong!

Set the RCIE bit to enable interrupts when a character is received,
Set the GIE bit to enable the global interrupt system. Don't set them both in the same instruction.

What happens then is every byte arriving into the USART, assuming you have it configured to match the Sim800 makes the program jump to the interrupt vector at address 0x0004.

So at address 0x0004 you have to place some code to deal with the interrupt, this is called an ISR or Interrupt Service Routine. Note that ALL interrupts cause a jump to that address so you need to read the INTCON or PIR registers to find out which caused it. In your case, the RCIF bit should be set because the USART caused it.

Whatever address your code was executing when the ISR was called is automatically pushed to the stack so it can be used to return to and continue your original program flow. The ISR has to do at least four things:
1. Save the W, STATUS and PCLATH registers because these might be changed within the ISR and therefore hold wrong values when you return.
2. Do whatever is necessary to process the byte in RCREG.
3. Restore W, STATUS and PCLATH to their original values.
4. Finish with a RETFIE instruction.

The RETFIE makes the PIC copy the address it saved when the interrupt occurred back to PCL so the next instruction it executes is the one it would have executed had the interrupt not happened.

The idea of an interrupt is that it suspends normal program flow when triggered by a hardware event (such as a byte arriving in the USART), then executes some special code at a reserved address (the ISR) then resumes the original program flow. You CAN do it by polling the RCIF bit but it means the whole program has to wait for the bit to set before it can continue, using interrupts leaves it free to run your program and only stop when needed.

The individual interrupt bits are not changed by the ISR so you do not have to re-enable them. What does happen though is the GIE bit AUTOMATICALLY gets cleared when an ISR starts and set again when it ends, you do not and should not change the GIE bit during an ISR. It does that so the interrupt can't get stuck in a loop.

Some interrupt sources require that you clear their interrupt flags before leaving the ISR but the USART is an exception, it's interrupt bit RCIF is cleared when you read the RCREG register so there is no need to do it as a separate instruction.

As you are writing in assembly language, by far the easiest way to write code is to copy the template code from Microchip to your working folder and then add your own code to it. The template already has all the declarations and a skeleton ISR in it, making the rest of the code much easier to write.

I use Linux and the template is in '/opt/microchip/mplabx/v4.20/mpasmx/templates/Code/16F877ATEMP.asm' but if you are using Windows, it will be somewhere similar but in the 'program files/Microchip...' folder. There are hundreds of templates so it should be easy to find them.

Brian.
 

wow! thanx a lot bro for such a breif explanation, thats was awesum, u meant that i have to place my isr after "org h'0004', so it can be executed, and before that i hav to save the contents of w ,pclath and status register to be used after the isr completed...indeed i have searched a lot of threads that were insisting to enable them al so i was confused nd decided to make that thread...i m using rcif but it keeps me around it and normal operation of the program get hung around it and i can go further to do other works, so i needed to use the interrupt...
 

This is the contents of Microchips template for the 18F877A, I'm sure they wont mind me posting it here as it contains no copyright and is freely available to download anyway:
Code:
;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F877A. This file contains the basic code              *
;   building blocks to build upon.                                    *  
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     * 
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F877A.INC                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


	list		p=16f877A	; list directive to define processor
	#include	<p16f877A.inc>	; processor specific variable definitions
	
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _RC_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.






;***** VARIABLE DEFINITIONS
w_temp		EQU	0x7D		; variable used for context saving 
status_temp	EQU	0x7E		; variable used for context saving
pclath_temp	EQU	0x7F		; variable used for context saving			






;**********************************************************************
	ORG     0x000             ; processor reset vector

	nop			  ; nop required for icd
  	goto    main              ; go to beginning of program


	ORG     0x004             ; interrupt vector location

	movwf   w_temp            ; save off current W register contents
	movf	STATUS,w          ; move status register into W register
	movwf	status_temp       ; save off contents of STATUS register
	movf	PCLATH,w	  ; move pclath register into w register
	movwf	pclath_temp	  ; save off contents of PCLATH register

; isr code can go here or be located as a call subroutine elsewhere

	movf	pclath_temp,w	  ; retrieve copy of PCLATH register
	movwf	PCLATH		  ; restore pre-isr PCLATH register contents
	movf    status_temp,w     ; retrieve copy of STATUS register
	movwf	STATUS            ; restore pre-isr STATUS register contents
	swapf   w_temp,f
	swapf   w_temp,w          ; restore pre-isr W register contents
	retfie                    ; return from interrupt



main

; remaining code goes here


	END                       ; directive 'end of program'
You might have to change the CONFIG for your own program.
Note that the 'ORG 0x000' is followed by a jump to 'main' so it passes over the ISR, no matter how big the ISR code actually is.

Where the comment ' ; isr code can go here...' is, you add the code for dealing with your USART data. Because there is only one ISR but several kinds of interrupt, you have to check the bits in PIR (INTCON in some cases) to check which one caused it. So in your case, you need to do something like this:
Code:
    btfss   PIE,RCIF          ;check if the USART caused the interrupt
    goto    not_from_usart
    
    ; your code goes here
    
not_from_usart

Brian.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top