![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
Hi there ! I'm learning how to setup interrupts in PICs from
Tutorial 11 but, this is for 16f84 and I have f690, so far this is what I have done, almost copy of what is on the site, if you can guide me how interrupts work for 16f690 than Ill be thankful Code:
list p=16f690 #include <p16f690.inc> __CONFIG -_MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 UDATA temp RES 1 display RES 1 count RES 1 ;**************************STEUP THE CONSTANTS******************************* org 0x05 ;this is where we come on power up and reset ;**************************INTRUPT ROUTINE************************************ movwf temp ;this and the lable Loop will run simultenously ;move w into f in case to there was someting in ;count(see first step of Loop) incf count,f ;increase count by 1 and put result in count movlw .10 ;load w with decimal 10 subwf count,w ;subtract count from w and place result in w btfss STATUS,C ;if in above operation count<= w then carry bit ;is set, so check for that and skip next step ;if it is set goto carry_on goto clear carry_on: bcf INTCON,0x01 ;clear the INTF, just in case(read tuto. 11) movfw temp ;move temp to w retfie ;get out of intrupt loop (this will start over ; the whole INTRUPT LOOP again clear: clrf count ;set count to 0 bcf INTCON,0x01 ;clear INTF retfie ;*****************************MAIN PROGRAMME************************ Main: ;*****************************SET UP THE INTRUP REGISTERS*********** bsf INTCON,0x07 ; set globel intrupt (tell PIC that we will use intrupts) bsf INTCON,0x04 ; bcf INTCON,0x01 ;******************************SET UP THE PORTS********************** bsf STATUS,RP0 movlw b'10000000' movwf TRISC bcf STATUS,RP0 ;******************************NOW SEND THE VALUE OF COUNT TO PORTC** Loop: movf count,w movwf PORTC goto Loop END What I don't understand is that how PIC can know (in tutorial not in my code) that INTCON,4 will enable RB0 while 4 can be for PORTA also, is this because we have enable globle interrupt ? Last edited by c36041254; 17th May 2008 at 03:10 AM. |
|
|
|
|
|
|
(permalink) |
|
I don't have a 16F690 handy but I cobbled together this so you could run it through the MPLAB simulator. Should be easy to make it work with your interrupt based version.
Code:
list p=16f690
#include <p16f690.inc>
__CONFIG _WDT_OFF & _INTRC_OSC_NOCLKOUT
cblock 0x20
count
endc
Wtemp equ 0x70 ; all bank RAM
org 0x00 ; this is where we come on power up and reset
goto Init
;**************************INTRUPT ROUTINE************************************
org 0x04
IRQ movwf Wtemp ; save W
incf count,f ;increase count by 1 and put result in count
movlw .10
subwf count,w ;subtract count from w and place result in w
btfsc STATUS,C ;if in above operation count<= w then carry bit
clrf count
movf count,W
movwf PORTC ; display W on PORTC
movf Wtemp,W ; restore W
bcf INTCON,INTF
return
Init bsf STATUS,RP0 ;b1
movlw b'10000000'
movwf TRISC
bcf STATUS,RP0 ;b0
clrf count ; count = 0
bsf INTCON,T0IE
bcf INTCON,INTF
bsf INTCON,GIE
Main call IRQ ; wait till next interrupt
goto Main
END
|
|
|
|
|
|
|
(permalink) |
|
Sorry, but I'm unable to understand your codes, what I make out of it is that it uses an internal interrupt timer 0 and whenever interrupt occur (bsf TOIE) it goes to IRQ but, i don't get how it automatically goes to IRQ and if it does do by call IRQ then how it can be called differrent from normal (interrupt less) codes, please explain me step by step so I can understand how actually codes suddenly switch to interrupt loop.
Oh ! and why the nuber increases by 4 on port c it should be incresed by 1, I mean that is what incf does. Last edited by c36041254; 17th May 2008 at 05:54 AM. |
|
|
|
|
|
|
(permalink) |
|
You seem a little confused with interrupts. When an interrupt occurs, the code stops what it is doing and jumps to location 4. It executes the code at that location until it meets a retfie (Return from interrupt) instruction and then returns to where it was before the instruction.
Bit 4 of INTCON enables the GP2 interrupt. This interrupt happens whenever GP2 goes from 0 to 1. Bit 3 enables the GPIE. This interrupt happens whenever any GPIO pin changes. Also, your code states, "org 0x05 ;this is where we come on power up and reset" - this is wrong. At reset or power up the processor goes to location zero. It is normal to put a goto at zero to jump over the interrupt code. Download the data sheet from Microchip for more information. Mike. |
|
|
|
|
|
|
(permalink) |
|
Forget about my codes I don't understand what "blueroomelectronics " codes mean(scrool up).what I make out of it is that it uses an internal interrupt timer 0 and whenever interrupt occur (bsf TOIE) it goes to IRQ but, i don't get how it automatically goes to IRQ and if it does do by call IRQ then how it can be called differrent from normal (interrupt less) codes, please explain me step by step so I can understand how actually codes suddenly switch to interrupt loop.Oh ! and why the number increases by 4 on port c it should be incresed by 1, I mean that is what incf does, and when I write "org 0x04" where it is in blueroomelectronics's codes I have the error:
Error - section '.org_1' can not fit the absolute section. Section '.org_1' start=0x00000004, length=0x0000002a changing "org 0x05" fixes this problem (don't know why, may be because the linker has vectors in 0x00 to 0x04, agin don't know what are the vectors are and why it is used for, I did read some MPLAB help file on it). And yes I do understand what an interrupt is, but should that alway start with 0x04? what if two or more interrupts are there? |
|
|
|
|
|
|
(permalink) |
|
Forget about the linker and just have 1 asm file to start with. To get your code to compile without the linker, change it to,
Code:
list p=16f690 #include <p16f690.inc> __CONFIG -_MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 cblock 0x20 temp RES 1 display RES 1 count RES 1 endc ;**************************STEUP THE CONSTANTS******************************* org 0x0 ;this is where we come on power up and reset goto Main ;**************************INTRUPT ROUTINE************************************ org 0x04 movwf temp ;this and the lable Loop will run simultenously ;move w into f in case to there was someting in ;count(see first step of Loop) incf count,f ;increase count by 1 and put result in count movlw .10 ;load w with decimal 10 subwf count,w ;subtract count from w and place result in w btfss STATUS,C ;if in above operation count<= w then carry bit ;is set, so check for that and skip next step ;if it is set goto carry_on goto clear carry_on: bcf INTCON,0x01 ;clear the INTF, just in case(read tuto. 11) movfw temp ;move temp to w retfie ;get out of intrupt loop (this will start over ; the whole INTRUPT LOOP again clear: clrf count ;set count to 0 bcf INTCON,0x01 ;clear INTF retfie ;*****************************MAIN PROGRAMME************************ Main: ;*****************************SET UP THE INTRUP REGISTERS*********** bsf INTCON,0x07 ; set globel intrupt (tell PIC that we will use intrupts) bsf INTCON,0x04 ; bcf INTCON,0x01 ;******************************SET UP THE PORTS********************** bsf STATUS,RP0 movlw b'10000000' movwf TRISC bcf STATUS,RP0 ;******************************NOW SEND THE VALUE OF COUNT TO PORTC** Loop: movf count,w movwf PORTC goto Loop END Edit, forget Bill's code as well at the moment. It doesn't demonstrate interrupts at all and has just served to confuse you. Mike. |
|
|
|
|
|
|
(permalink) | |
|
Quote:
Error[121] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 57 : Illegal label (temp RES 1) Error[121] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 58 : Illegal label (display RES 1) Error[121] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 59 : Illegal label (count RES 1) Error[113] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 71 : Symbol not previously defined (temp) Error[113] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 75 : Symbol not previously defined (count) Error[113] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 77 : Symbol not previously defined (count) Error[113] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 86 : Symbol not previously defined (temp) Error[113] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 90 : Symbol not previously defined (count) Error[113] C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT\16F690TMPO.ASM 110 : Symbol not previously defined (count) Halting build on first failure as requested. BUILD FAILED: Sat May 17 14:31:17 2008 |
||
|
|
|
|
|
(permalink) |
|
hi c90,
Your code assembles OK on my system, had to REM out the 'RES' in cblock, otherwise its OK. Are you sure about the paths for the assembler to the INC files etc.??? Code:
list p=16f690 #include <p16f690.inc> __CONFIG -_MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 cblock 0x20 temp ;;RES 1 display ;;RES 1 count ;;RES 1 endc ;**************************STEUP THE CONSTANTS******************************* org 0x0 ;this is where we come on power up and reset goto Main ;**************************INTRUPT ROUTINE************************************ org 0x04 movwf temp ;this and the lable Loop will run simultenously ;move w into f in case to there was someting in ;count(see first step of Loop) incf count,f ;increase count by 1 and put result in count movlw .10 ;load w with decimal 10 subwf count,w ;subtract count from w and place result in w btfss STATUS,C ;if in above operation count<= w then carry bit ;is set, so check for that and skip next step ;if it is set goto carry_on goto clear carry_on: bcf INTCON,0x01 ;clear the INTF, just in case(read tuto. 11) movfw temp ;move temp to w retfie ;get out of intrupt loop (this will start over ; the whole INTRUPT LOOP again clear: clrf count ;set count to 0 bcf INTCON,0x01 ;clear INTF retfie ;*****************************MAIN PROGRAMME************************ Main: ;*****************************SET UP THE INTRUP REGISTERS*********** bsf INTCON,0x07 ; set globel intrupt (tell PIC that we will use intrupts) bsf INTCON,0x04 ; bcf INTCON,0x01 ;******************************SET UP THE PORTS********************** bsf STATUS,RP0 movlw b'10000000' movwf TRISC bcf STATUS,RP0 ;******************************NOW SEND THE VALUE OF COUNT TO PORTC** Loop: movf count,w movwf PORTC goto Loop END
__________________
Eric "Good enough is Perfect" PIC tutorials: Gramo's: www.digital-diy.net/ Bill's: www.blueroomelectronics.com/ |
|
|
|
|
|
|
(permalink) |
|
hi 360,
Just in case you did not follow my comment about the paths. Look in this folder on the hard drive. C:\PROGRAM FILES\MICROCHIP\MPASM SUITE\TEMPLATE\OBJECT and you should be able to see this file 16F690TMPO.ASM Did you use the MPLAB Project Wizard.?
__________________
Eric "Good enough is Perfect" PIC tutorials: Gramo's: www.digital-diy.net/ Bill's: www.blueroomelectronics.com/ |
|
|
|
|
|
|
(permalink) |
|
Thanks, that makes a successful build, there are some things I don't understand, that why I alwways have to change org 0x04 to org 0x05 (other wise it encounters the error:Error - section '.org_1' can not fit the absolute section. Section '.org_1' start=0x00000004, length=0x0000002a ) and I can not get that while there is no label specifying interrupt then how the programme automaticaly switch to interrupt loop? This is my final code and don't know why it does'nt work. What I want to do is that let the PIC to display whatever in count on PORT C (in binary ,by four LEDs ) and as I give HIGH to RA2 (which is external interrupt) it goes to interuupt loop and add 1 to count and then display that on PORT C and continue this till COUNT reaches 9 then it get reset.
Code:
list p=16f690 #include <p16f690.inc> __CONFIG -_MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 cblock 0x20 temp ;RES 1 display ;RES 1 count ;RES 1 endc ;**************************STEUP THE CONSTANTS******************************* org 0x00 ;this is where we come on power up and reset goto Main ;**************************INTRUPT ROUTINE************************************ org 0x05 movwf temp ;this and the lable Loop will run simultenously ;move w into f in case to there was someting in ;count(see first step of Loop) incf count,f ;increase count by 1 and put result in count movlw .10 ;load w with decimal 10 subwf count,w ;subtract count from w and place result in w btfss STATUS,C ;if in above operation count<= w then carry bit ;is set, so check for that and skip next step ;if it is set goto carry_on goto clear carry_on: bcf INTCON,0x01 ;clear the INTF, just in case(read tuto. 11) movfw temp ;move temp to w retfie ;get out of intrupt loop (this will start over ; the whole INTRUPT LOOP again clear: clrf count ;set count to 0 bcf INTCON,0x01 ;clear INTF retfie ;*****************************MAIN PROGRAMME************************ Main: ;*****************************SET UP THE INTRUP REGISTERS*********** bsf INTCON,0x07 ; set globel intrupt (tell PIC that we will use intrupts) bsf INTCON,0x04 ; bcf INTCON,0x01 ;******************************SET UP THE PORTS********************** bsf STATUS,RP0 movlw b'10000000' movwf TRISC movlw b'00000100' movwf TRISA ;set RA2 as input (for interrupt) bcf STATUS,RP0 ;******************************NOW SEND THE VALUE OF COUNT TO PORTC** Loop: movf count,w movwf PORTC goto Loop END I know these are too many quastions but please answer me I'm getting more and more confused, atleast try to answer the quastion in RED, Pleazzzzz!! |
|
|
|
|
|
|
(permalink) |
|
Sorry about leaving those Res' there.
You need to remove the linker script and change the source back to org 4 to get it to compile. You don't need a label at location 4 as the interrupt always goes there. You can put a label there if you wish. Your code is probably not working because you have RA2 setup as analogue because it is the default. Try adding clrf ANSEL (bank 2). Mike. |
|
|
|
|
|
|
(permalink) |
|
The error still persists,
Error - section '.org_1' can not fit the absolute section. Section '.org_1' start=0x00000004, length=0x00000038 and this is what I have done to code (see in RED): Code:
list p=16f690 #include <p16f690.inc> __CONFIG -_MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 cblock 0x20 temp display count endc ;**************************STEUP THE CONSTANTS******************************* org 0x00 ;this is where we come on power up and reset goto Main ;**************************INTRUPT ROUTINE************************************ org 0x04 movwf temp ;this and the lable Loop will run simultenously ;move w into f in case to there was someting in ;count(see first step of Loop) incf count,f ;increase count by 1 and put result in count movlw .10 ;load w with decimal 10 subwf count,w ;subtract count from w and place result in w btfss STATUS,C ;if in above operation count<= w then carry bit ;is set, so check for that and skip next step ;if it is set goto carry_on goto clear carry_on: bcf INTCON,0x01 ;clear the INTF, just in case(read tuto. 11) movfw temp ;move temp to w retfie ;get out of intrupt loop (this will start over ; the whole INTRUPT LOOP again clear: clrf count ;set count to 0 bcf INTCON,0x01 ;clear INTF retfie ;*****************************MAIN PROGRAMME************************ Main: ;*****************************SET UP THE INTRUP REGISTERS*********** bsf INTCON,0x07 ; set globel intrupt (tell PIC that we will use intrupts) bsf INTCON,0x04 ; bcf INTCON,0x01 ;******************************SET UP THE PORTS********************** bsf STATUS,RP0 movlw b'10000000' movwf TRISC bcf STATUS,RP0 bsf STATUS,RP1 clrf ANSEL movlw b'00000100' movwf TRISA ;set RA2 as input (for interrupt) bcf STATUS,RP0 ;******************************NOW SEND THE VALUE OF COUNT TO PORTC** Loop: movf count,w movwf PORTC goto Loop END |
|
|
|
|
|
|
(permalink) |
|
Have you removed the linker script from the project?
You are now writing to the TRISA register in bank 2! Try, Code:
;******************************SET UP THE PORTS********************** bsf STATUS,RP0 ;bank 1 movlw b'10000000' movwf TRISC movlw b'00000100' movwf TRISA ;set RA2 as input (for interrupt) bcf STATUS,RP0 ;bank 0 bsf STATUS,RP1 ;bank 2 clrf ANSEL bcf STATUS,RP1 ;bank 0 ;******************************NOW SEND THE VALUE OF COUNT TO PORTC** |
|
|
|
|
|
|
(permalink) |
|
Sorry, I had not removed linker now it builds successfully but still all LED remains off even when I give HIGH to RA2
This is the modified code: Code:
list p=16f690 #include <p16f690.inc> __CONFIG -_MCLRE_ON & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 cblock 0x20 temp display count endc ;**************************STEUP THE CONSTANTS******************************* org 0x00 ;this is where we come on power up and reset goto Main ;**************************INTRUPT ROUTINE************************************ org 0x04 movwf temp ;this and the lable Loop will run simultenously ;move w into f in case to there was someting in ;count(see first step of Loop) incf count,f ;increase count by 1 and put result in count movlw .10 ;load w with decimal 10 subwf count,w ;subtract count from w and place result in w btfss STATUS,C ;if in above operation count<= w then carry bit ;is set, so check for that and skip next step ;if it is set goto carry_on goto clear carry_on: bcf INTCON,0x01 ;clear the INTF, just in case movfw temp ;move temp to w retfie ;get out of intrupt loop (this will start over ; the whole INTRUPT LOOP again clear: clrf count ;set count to 0 bcf INTCON,0x01 ;clear INTF retfie ;*****************************MAIN PROGRAMME************************ Main: ;*****************************SET UP THE INTRUP REGISTERS*********** bsf INTCON,0x07 ; set globel intrupt (tell PIC that we will use intrupts) bsf INTCON,0x04 ; bcf INTCON,0x01 ;******************************SET UP THE PORTS********************** bsf STATUS,RP0 movlw b'10000000' movwf TRISC movlw b'00000100' movwf TRISA ;set RA2 as input (for interrupt) bcf STATUS,RP0 bsf STATUS,RP1 clrf ANSEL bcf STATUS,RP1;******************************NOW SEND THE VALUE OF COUNT TO PORTC** Loop: movf count,w movwf PORTC goto Loop END |
|
|
|
|
|
|
(permalink) |
|
hi c360,
As Mike is sorting out the program I will leave that to him. With regard to the Interrupts. You choose in your program which Interrupts are going to be active, that is when the conditions set out in your program are met, an Interrupt will occur. When the Interrupt occurs, the Program Counter is set by the PIC to 0x0004. The PIC starts executing the program code it finds at 0x0004 until it reaches the RETFIE instruction, at which time the PIC will return to the next program code byte it was executing BEFORE the Interrupt occurred. Do you follow.?
__________________
Eric "Good enough is Perfect" PIC tutorials: Gramo's: www.digital-diy.net/ Bill's: www.blueroomelectronics.com/ |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| PIC16F628a Problem generating a RCIE interrupt | Norlin | Micro Controllers | 3 | 16th January 2008 01:43 AM |
| Priority Interrupt Controller | Stellarcore | Datasheet/Parts Requests | 14 | 13th September 2007 04:13 PM |
| Help with timer and interrupt please.. | AntRoFiZ | Micro Controllers | 2 | 29th May 2007 11:48 AM |
| Question about Interrupt | tinhnho | Micro Controllers | 3 | 11th February 2007 07:07 PM |
| Interrupt on GP Change problem | Dan East | Micro Controllers | 2 | 22nd May 2004 05:12 PM |