That is not enough code to make a whole program.
Please post your entire code.
Also include the PIC you are using and the compiler version.
Printable View
That is not enough code to make a whole program.
Please post your entire code.
Also include the PIC you are using and the compiler version.
I work with 12F683 and MPASM v5.42.
1000 x thx
Code :
'************************************************* ***************
'* Name : Test_SPWM.pbp *
'* Author : Darrel Taylor *
'* Date : 9/30/2006 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
; Initialize your hardware first
DEFINE OSC 20
CLEAR
INCLUDE "..\DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module
wsave VAR BYTE $20 SYSTEM
wsave1 VAR BYTE $A0 SYSTEM
DEFINE SPWM_FREQ 40 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution
DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]
ASM
SPWM_LIST macro ; Define PIN's to use for SPWM
SPWM_PIN GPIO, 0, _DutyVar1
SPWM_PIN GPIO, 1, _DutyVar2
SPWM_PIN GPIO, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
;_________________________________________________ ____________________________
RandVar VAR WORD : RandVar = 12345
LoopCount VAR WORD
Main:
DutyVar1 = 5
DutyVar2 = 50
DutyVar3 = 150
GOTO Main
How fast is the led blinking?
Ioannis
I apreciate 4-5 blinks/sec
1) Are you really using a 20 Mhz crystal?
Not very many people use crystals on an 8-pin PIC.
2) 40 Hz is really slow for LED's
Increase the SPWM_FREQ.
I use in config : @_INTRC_OSC_NOCLKOUT . its necessary to use external crystal ?
I increased the SPWM_FREQ at 219 and leds are relativelly well
No, it is not necessary to use a crystal.
But your DEFINE OSC must match your actual oscillator frequency.
If you have specified the internal oscillator in your configs, then the default is 4Mhz, not 20Mhz.
And your program is running at 1/5th the speed it is supposed to.
Thank you for your help and patience !
Can somebody help me with this code for 12F683: ?
I want to blink very quikly a led in background ,independent of my code, random, pause between 1-20 ms. I think that this interval is ok, the best if its possible to set pause limits.
I want learn about intrerupts but i think that I'm too old ...
thx in advance !!
...or , how I can make SPWM without intrerupts...?
Try this as an intro to Darrel Interrupts and blinking LED:
http://darreltaylor.com/DT_INTS-14/blinky.html
It's worth the time to practice. His routines make things so much easier and flexible later on as you add more complexity to your code.
Robert
I've been using DT_INTS-14 for a while with various types of interrupts but now I want to implement one for A/D. I've created the dummy interrupt handler, but my question is whether I can read the value of the conversion using PBP's ADCIN or should I grab directly from the registers. If the latter, I could use some help with that.
My ADC set up is as follows:
I'm working on implementing Darrel's MIBAM with a trim pot to set the brightness of an LED.Code:; PIC12F1840
DEFINE ADC_BITS 8 ; Set number of bits in result
DEFINE ADC_SAMPLEUS 5 ; Set sampling time in uS
DEFINE ADC_CLOCK 3 ; Set clock source (3=rc)
FVRCON = 0 ' Fixed Voltage Reference is disabled
ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only
ADCON0 = %00000101 ' ADC (analog-to-digital) is enabled on AN1 (RA1) only
ADCON1.7 = 0 ; Left-justified results in 8-bits
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
INT_Handler AD_INT, _ADC_change, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
' Enable interrupts
@ INT_ENABLE INT_INT ; INT Interrupt
@ INT_ENABLE AD_INT ; A/D Interrupt
Darrel came up with a terrific piece of code for my project - have a look at this thread:
http://www.picbasic.co.uk/forum/showthread.php?t=17299
Hi,
I guess you COULD use ADCIN but it kind of defeats the purpose of the interrupt since it is a self timed command.
When using ADC interrupts you basically set the GO/DONE bit to start the converstion and the interrupt fires when the ADC conversion is done. If you then use ADCIN in the interrupt handler it would perform another, self-timed, conversion which, again, kind of defeats the use of interrupts in the first place.
The idea is to start the conversion and then either go to sleep or go do something important while the ADC does its job. The interrupt fires when the conversion is complete and you go grab the result by reading ADRESH/ADRESL register pair.
/Henrik.
Thanks Henrik. I've never done A/D conversion before other than through ADCIN but I guessed it wouldn't make sense to use in an interrupt. I'll have to do a search on 'ADRESH' to see how to read the result when I turn the trim pot dial.
I've set up and ADC interrupt using DT_INST-14 with the following handler code:
Is that right? I just need 8-bit ADC resolution (0-255)Code:' ***************************************************************
' [A/D - interrupt handler]
' ***************************************************************
ADC_change:
PAUSEUS 50 ' Wait for A/D channel acquisition time
ADCON0.1 = 1 ' Start conversion
WHILE ADCON0.1 ' Wait for it to complete
WEND
ADCInVal = ADRESH
@ INT_RETURN
Hi,
Well, that too defeats the purpose of using the interrupt in the first place since you trig the conversion and sit around waiting for it to complete while IN the interrupt handler. You could just as well have used ADCIN in the ISR.
One thing we need to get squared away just so we're clear. Your ISR is called ADC_Change and from that I get the feeling that you might think the ADC interrupt fires when the voltage at the input changes - that's not the case. If that was already obvious to you then I appologise, I just wanted to clarify that.
You start the conversion from within your main code or possibly from another ISR, whatever. Then, instead of sitting around waiting for the duration of the conversion you go do something else or go to sleep to provide a quiet environment for the ADC. The interrupt then fires when the conversion is complete and all you need to do in the ISR is grab the result by reading ADRESH, just like you're doing now.
As you probably know using, when using DT-ints, PBP needs to do a whole lot of context saving/restoring when entering/exiting the ISR and this takes time. So it might not even be worth it using interrupts as the time taken to enter and exit the ISR could very well be longer than the ADC conversion time. I don't know for sure, and it depends, just saying..... If reading the result is all you're going to do in the ISR then you can probably get away with an ASM type handler still written in PBP which will be much quicker to get in and out of - but that's always "risky" so lets not go there untill you have something that works and does what you need.
/Henrik.
Thanks for your detailed reply, Henrik. In the past, I've just used a GOSUB in the main loop and in the subroutine call ADCIN and compare the current value to a previous value; if it's different, I use that 8-bit value to set a PWM duty cycle to brighten/dim an LED. For this project, I thought it might be more efficient to set up an AD_INT interrupt which I thought would be triggered whenever I turn the dial on the trim pot and hence slightly more efficient. I think I see now that I'm wrong in what I thought would trigger this interrupt and that I guess I have to go back to the GOSUB approach.
Hi,
You don't have to go back to the GOSUB aproach but yes, it does look like you've misunderstood how the ADC interrupt works.
If, for example, you have timer interrupt in your program you could use that to start to AD conversion and then either wait for the conversion or let the ADC trip another interrupt when it's done.
/Henrik.
That makes sense, thanks Henrik. I may tie this to a button so that it's not constantly reading the trim pot - I only want to adjust the LED brightness (PWM duty cycle) infrequently and deliberately.
Wow! 7 years & still adding pages! A conversation with Daryl led me here. I want to have an event occur just prior to the end of a PWM period. I was told it had to be done in assembly. My project is based on the PIC16F1828, uses CCP for PWM, DSM (Digital Signal Modulation) to embed HF within a slower PWM clock, and just before the Off/On I need to trigger an event. Got it working thanks to Daryl. Here's what it looks like:
http://i223.photobucket.com/albums/d...ps91083c15.jpg
The code looks like this:
define OSC 32
define ADC_BITS 8
define ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
#CONFIG
CONFIG1_FOSC_INTOSC
CONFIG1_MCLRE_OFF
CONFIG1_CLKOUTEN_OFF
CONFIG2_PLLEN_ON
#endconfig
OSCCON = %11110011
TRISA = %00111100
TRISB = %01100000
TRISC = %11001011
ANSELA = %00011111
ANSELB = %01100000
ANSELC = %11001011
WPUA = 0
WPUB = 0
WPUC = 0
MDSRC = %10000010 'DSM Activated (.7) on CCP1 (RC5) (<3:0>
MDCARH = %10000011 'OOK Mode
MDCARL = %10100000 'Disables Low Carrier Signal; OOK Mode
MDCON = %11000000 '.7 Enables OOK, .3 Current State (read only)
CLKRCON = %10110000
b0 var byte
b1 var byte
b1 = 0
LED1 VAR PORTC.5
TPS_In var PORTC.7 'AN9
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR2_INT, _SetTR4, PBP, yes
INT_Handler TMR4_INT, _GP, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
'T1CON = %00110001 ; Prescaler=8, TMR1ON
@ INT_ENABLE TMR2_INT ; enable Timer 2 interrupts
Main:
adcin 9, b0
hpwm 1, b0, 1056
PAUSE 1
GOTO Main
'---[TMR1 - interrupt handler]--------------------------------------------------
SetTR4:
T4CON = T2CON
PR4 = PR2
TMR4 = TMR2 - 246
@ INT_ENABLE TMR4_INT
@ INT_RETURN
GP:
pulsout PORTC.5, 5
@ INT_DISABLE TMR4_INT
'@ INT_CLEAR TMR1_INT
@ INT_RETURN
end
All I can say is, I'm so glad I found ME Labs and now this forum. Overwhelming thanks to Charles, Daryl, and many whose work I've gleened from, but have yet to get to know personally.
Mike
Hi, is there any known error /workaround for using eeprom "read"(didn't test write) while @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts ?
I use 16f1827, if I comment INT_enable line, all works great, but if line is enabled, read command return same index instead value
i experimented with putting int_disable before read int_enable after, putting some pause between disabling/enabling GIE before/after read
but nothing give me result, only when INT_enable commented, never executed, then works...
ShoKre, I have never had a problem using the READ and WRITE commands while having the interrupts enabled. I have used it with 18F8722, 18F67k22, 18f46k22, 18f4620, 18f452, 16f1825, 18f1320, 16f88, 12f1840.
Maybe you should post some code and we here can have a look?
i figured out what interfere, i have readcode command in my (basic)ISR, and read in main-loop, after i commented readcode in isr read in main-loop has began to work, so, now i have to find another way
for reading LED gamma table in isr, or pattern eeprom in main, at least I found what interfere, and the way will come, maybe put read in isr too.... there is more than 500ln of code so it will probably make
treed dirty with non important/regarded stuff...
..it is good to know that there isn't other problems with dt-ints and read.
...found interesting or sad errata for 16f1827 http://ww1.microchip.com/downloads/e...Doc/80485G.pdf so ih you bught chip with 1M/100k read write eeprom/flash, you actually get 1k/10k :), good to know for save lifespan with fewer writes... i was reading that when couldn't read eeprom...
(sorry for my bad English if sentences sometime don't have sense :)
thanx anyway,
Hi all
Could anybody help me with a problem I'm having with using instant interrupts "Thanks to Darrel for all his work" and the IC3 module of the PIC18F2431
I can get IC1 (CAP1) to work OK also IC2(CAP2) but when I compile using IC3 (CAP3) I get the following errors.
Symbol not previously defined (IntFlagReg)
Symbol not previously defined (IntFlagBit)
ERROR: (Interrupt Source IntFlagReg,IntFlagBit) not found)
Following is a snip-it from parts of the program and if I substitute IC3DRIF_INT for IC1IF_INT or IC2QEF and change the CAP3BUF's for 1 or 2 every thing works OK.
I've tried every thing I can think of but not bright enough to sort this out.
Using PBX 3.0.4.1
INT_Handler IC3DRIF_INT
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler IC3DRIF_INT, _InputSignal, ASM, yes
@ INT_Handler IC3DRIF_INT
InputSignal: 'Input pulse width capture of CAP3
ReciverOutput.lowbyte = CAP3BUFL
ReciverOutput.highbyte = CAP3BUFH
Passthrough = ReciverOutut
Thanks in advance Geoff
Totally wild guess, Darrel's routine only has code for #1 and 2. Can't check includes and asm files from my phone, but I'd start there.
Robert
have a look at these threads with dt's guidance I added unsupported interrupts to dt_int18
http://support.melabs.com/threads/39...with-pic18f248
http://support.melabs.com/threads/32...TMR4-int-ERROR
Hi,
I think the problem is that you're mixing up the names of the interrupt source and the interrupt handler. The interrupt source is called IC3DRIF_INT - you can't call the interrupt handler that as well. This compiles just fine:/Henrik.Code:Include "DT_INTS-18.pbp" 'Include the interrupt system files.
ASM
INT_LIST macro ;IntSource Label Type ResetFlag
INT_Handler IC3DRIF_INT, _InputSignal, ASM, yes
endm
INT_CREATE
ENDASM
@ INT_ENABLE IC3DRIF_INT
Main:
Toggle PortB.0
Pause 500
Goto Main
InputSignal:
@ NOP
@ INT_RETURN
Hi all
Thanks Henrik, Richard and Demon for the response with my problem, it is much appreciated.
It turns out Henrik spotted the problem and it is now sorted. Being lazy I copied and pasted a line for the interrupt enable from the handler line but didn't change from Handler to Enable as Henrik spotted. I then spent a week of evenings trying to find the problem, it is true sometimes you cannot see the wood for the trees.
Thanks again Geoff.
Good Afternoon All-
I have gone through this thread and apologies if this is not the correct place for me to post this question;
I have a home project in which I want to use 2 USARTs for my humble home automation idea. I know that DT's interrupts-18 will handle 2 serial ports and have used it - works quite well and again Kudos to DT!
The chip I want to use is the 16F1527 which looks to be a great choice, capable and cheap!
I see by DT's site that there is no 2nd serial interrupt as in the -18. In looking through DT_INTS-14 I do not see one either.
My question, is there a way (surely?) to add this to DT_INTS-14?
I read a post in where you can add an interrupt on change but I am not experienced enough to see how I might apply this philosophy to the 2nd serial port.
Any advice would be greatly appreciated.
BTW, after reading all 19 pages of this thread, my cap will no longer fit on my head - its swollen <grin>........
Regards to All.
Hi,
If you have a way of testing the uarts you can try the below, no guarantees
I think if you define the the interupt and related registers, DT's macro will do the rest
for you? Edit DT_INTS-14.bas include file
Existing uart define, from DT_INTS-14.bas version 1.10
Code:
#define TX_INT PIR1,TXIF, PIE1,TXIE ;-- USART Transmit
#define RX_INT PIR1,RCIF, PIE1,RCIE ;-- USART Receive
Try adding this right below the above (info from page 89 pic16f1527 data sheet)
Code:#define TX1_INT PIR1,TX1IF, PIE1,TX1IE ;-- USART1 Transmit
#define RX1_INT PIR1,RC1IF, PIE1,RC1IE ;-- USART1 Receive
#define TX2_INT PIR4,TX2IF, PIE4,TX2IE ;-- USART2 Transmit
#define RX2_INT PIR4,RC2IF, PIE4,RC2IE ;-- USART2 Receive
I changed the file for you
Code:'***************************************************************************
'* Name : DT_INTS-14.bas *
'* Author : Darrel Taylor *
'* Version : 1.10 (8/13/2010) *
'* Date : OCT 13, 2009 *
'***************************************************************************
'* REV 1.10 Fixes Duplicate label error when Handlers cross page boundary *
'* Fixes error with 16F1's and MPLAB 8.53 (high) *
'* REV 1.00 Completely re-written, with optimization and F1 chips in mind *
'* REV 0.93 Fixed CMIF and EEIF problem with older PIC's *
'* that have the Flags in PIR1 instead of PIR2 *
'* Rev 0.92 solves a "Missed Interrupt" and *
'* banking switching problem *
'***************************************************************************
DEFINE DT_INTS_VERSION 110
DEFINE INTHAND INT_ENTRY
;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register
psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register
fsave VAR BYTE BANK0 SYSTEM ' location for FSR register
RetAddr VAR WORD BANK0
INT_Bits VAR BYTE BANK0
Serviced VAR INT_Bits.0
Vars_Saved VAR INT_Bits.1
GIE VAR INTCON.7
PEIE VAR INTCON.6
ASM
ifdef PM_USED ; verify MPASM is the assembler
"ERROR: DT_INTS does not support the PM assembler, USE MPASM"
endif
;---------------------------------------------------------------------------
ifdef ReEnterUsed
ifdef ReEnterVersion
if (ReEnterVersion < 34)
error "Wrong version of ReEnterPBP.bas - Ver 3.4 or higher required
endif
else
error "Wrong version of ReEnterPBP.bas - Ver 3.4 or higher required
endif
endif
;---------------------------------------------------------------------------
if (BANK0_END == 0x7F)
ifdef BANK1_END
if (BANK1_END == 0xEF) ; doesn't find 12F683
variable ACCESSRAM = 1
else
variable ACCESSRAM = 0
endif
else
variable ACCESSRAM = 0
endif
else
variable ACCESSRAM = 0
endif
;---------------------------------------------------------------------------
#define OrChange Or change to wsave BYTE $70 SYSTEM
AddWsave macro B
if (B == 0)
if (ACCESSRAM == 1)
error " Add:" wsave VAR BYTE $70 SYSTEM
else
error " Add:" wsave VAR BYTE $20 SYSTEM
endif
endif
if (B == 1)
if (ACCESSRAM == 1)
error " Add:" wsave1 VAR BYTE $A0 SYSTEM, OrChange
else
error " Add:" wsave1 VAR BYTE $A0 SYSTEM
endif
endif
if (B == 2)
if (ACCESSRAM == 1)
error " Add:" wsave2 VAR BYTE $120 SYSTEM, OrChange
else
error " Add:" wsave2 VAR BYTE $120 SYSTEM
endif
endif
if (B == 3)
if (ACCESSRAM == 1)
error " Add:" wsave3 VAR BYTE $1A0 SYSTEM, OrChange
else
error " Add:" wsave3 VAR BYTE $1A0 SYSTEM
endif
endif
endm
#define WsaveE1(B) Chip has RAM in BANK#v(B), but wsave#v(B) was not found.
;#define WsaveE2(B) Uncomment wsave#v(B) in the DT_INTS-14.bas file.
#define WsaveCouldBe This chip has access RAM at $70
#define WsaveError(B) error WsaveE1(B)
ifndef FSR0L ; not a 16F1
ifndef wsave
; if (ACCESSRAM == 1)
error wsave variable not found,
AddWsave(0)
variable wsave = 0 ; stop further wsave errors
; else
; endif
else
if (wsave == 0x70)
if (ACCESSRAM == 0)
error This chip does not have AccessRAM at $70, change to wsave VAR BYTE $20 SYSTEM
endif
else
if (wsave != 0x20)
error wsave must be either $20 or $70
endif
endif
endif
ifdef BANK1_START
ifndef wsave1
ifdef wsave
if (wsave != 0x70)
WsaveError(1)
AddWsave(1)
endif
else
if (ACCESSRAM == 1)
if (wsave != 0x70)
WsaveCouldBe
endif
endif
endif
endif
endif
ifdef BANK2_START
ifndef wsave2
ifdef wsave
if (wsave != 0x70)
WsaveError(2)
AddWsave(2)
endif
endif
endif
endif
ifdef BANK3_START
ifndef wsave3
ifdef wsave
if (wsave != 0x70)
WsaveError(3)
AddWsave(3)
endif
endif
endif
endif
endif
ENDASM
ASM
asm = 0
Asm = 0
ASM = 0
pbp = 1
Pbp = 1
PBP = 1
yes = 1
Yes = 1
YES = 1
no = 0
No = 0
NO = 0
#define ALL_INT INTCON,GIE, INTCON,GIE ;-- Global Interrupts *
#define T1GATE_INT PIR1,TMR1GIF, PIE1,TMR1GIE ;-- Timer1 Gate *
#define INT_INT INTCON,INTF, INTCON,INTE ;-- External INT
#define GPC_INT INTCON,GPIF, INTCON,GPIE ;-- GPIO Int On Change *
#define IOC_INT INTCON,IOCIF, INTCON,IOCIE ;-- Int On Change *
#define RAC_INT INTCON,RAIF, INTCON,RAIE ;-- RA Port Change *
#define RBC_INT INTCON,RBIF, INTCON,RBIE ;-- RB Port Change
#define RABC_INT INTCON,RABIF, INTCON,RABIE ;-- RAB Port Change *
ifdef T0IF
#define TMR0_INT INTCON,T0IF, INTCON,T0IE ;-- TMR0 Overflow
else
ifdef TMR0IF
#define TMR0_INT INTCON,TMR0IF, INTCON,TMR0IE ;-- TMR0 alternate sym
endif
endif
ifdef TMR1IF
#define TMR1_INT PIR1,TMR1IF, PIE1,TMR1IE ;-- TMR1 Overflow
else
ifdef T1IF
#define TMR1_INT PIR1,T1IF, PIE1,T1IE ;-- TMR1 alternate sym
endif
endif
ifdef TMR2IF
#define TMR2_INT PIR1,TMR2IF, PIE1,TMR2IE ;-- TMR2 - PR2 Match
else
#define TMR2_INT PIR1,T2IF, PIE1,T2IE ;-- TMR2 - PR2 Match alt
endif
#define TMR4_INT PIR3,TMR4IF, PIE3,TMR4IE ;-- TMR4 - PR4 Match *
#define TMR6_INT PIR3,TMR6IF, PIE3,TMR6IE ;-- TMR6 - PR6 Match *
#define TX_INT PIR1,TXIF, PIE1,TXIE ;-- USART Transmit
#define RX_INT PIR1,RCIF, PIE1,RCIE ;-- USART Receive
;----------------------------------------------------------------------------Modified 11-2-2014
#define TX1_INT PIR1,TX1IF, PIE1,TX1IE ;-- USART1 Transmit
#define RX1_INT PIR1,RC1IF, PIE1,RC1IE ;-- USART1 Receive
#define TX2_INT PIR4,TX2IF, PIE4,TX2IE ;-- USART2 Transmit
#define RX2_INT PIR4,RC2IF, PIE4,RC2IE ;-- USART2 Receive
;----------------------------------------------------------------------------End addition
#define PSP_INT PIR1,PSPIF, PIE1,PSPIE ;-- Parallel Slave Port
#define AD_INT PIR1,ADIF, PIE1,ADIE ;-- A/D Converter
ifdef SSPIF
#define SSP_INT PIR1,SSPIF, PIE1,SSPIE ;-- (M)SSP module
#define BUS_INT PIR2,BCLIF, PIE2,BCLIE ;-- Bus Collision
else
ifdef SSP1IF
#define SSP_INT PIR1,SSP1IF, PIE1,SSP1IE ;-- (M)SSP module 1 *
#define SSP1_INT PIR1,SSP1IF, PIE1,SSP1IE ; *
#define BUS_INT PIR2,BCL1IF, PIE2,BCL1IE ;-- Bus Collision 1 *
#define BUS1_INT PIR2,BCL1IF, PIE2,BCL1IE ; *
endif
ifdef SSP2IF
#define SSP2_INT PIR4,SSP2IF, PIE4,SSP2IE ;-- (M)SSP module 2 *
#define BUS2_INT PIR4,BCL2IF, PIE4,BCL2IE ;-- Bus Collision 2 *
endif
endif
#define CCP1_INT PIR1,CCP1IF, PIE1,CCP1IE ;-- CCP1
#define CCP2_INT PIR2,CCP2IF, PIE2,CCP2IE ;-- CCP2
#define CCP3_INT PIR3,CCP3IF, PIE3,CCP3IE ;-- CCP3 *
#define CCP4_INT PIR3,CCP4IF, PIE3,CCP4IE ;-- CCP4 *
#define CCP5_INT PIR3,CCP5IF, PIE3,CCP5IE ;-- CCP5 *
ifdef CMIF
ifdef PIR2
#define CMP_INT PIR2,CMIF, PIE2,CMIE ;-- Comparator
else
#define CMP_INT PIR1,CMIF, PIE1,CMIE
endif
else
ifdef C1IF
#define CMP_INT PIR2,C1IF, PIE2,C1IE ;-- Comparator 1 *
#define CMP1_INT PIR2,C1IF, PIE2,C1IE ;-- Comparator 1 *
endif
ifdef C2IF
#define CMP2_INT PIR2,C2IF, PIE2,C2IE ;-- Comparator 2 *
endif
endif
ifndef PIR2
#define EE_INT PIR1,EEIF, PIE1,EEIE
#define OSCF_INT PIR1,OSFIF, PIE1,OSFIE ;-- OSC Fail if no PIR2 *
#define LVD_INT PIR1,LVDIF, PIE1,LVDIE ;-- Low-Voltage Detect *
else
#define EE_INT PIR2,EEIF, PIE2,EEIE ;-- EEPROM/FLASH Write
#define OSCF_INT PIR2,OSFIF, PIE2,OSFIE ;-- OSC Fail *
#define LVD_INT PIR2,LVDIF, PIE2,LVDIE ;-- Low-Voltage Detect *
endif
#define LCD_INT PIR2,LCDIF, PIE2,LCDIE ;-- LCD controller *
#define CRYPT_INT PIR1,CRIF, PIE1,CRIE ;-- KeeLoq Cryptographic*
#define USB_INT PIR1,USBIF, PIE1,USBIE ;-- USB 16C745/765 only *
ENDASM
ASM
;---[Returns the Address of a Label as a Word]------------------------------
GetAddress macro Label, Wout
CHK?RP Wout
movlw low Label ; get low byte
movwf Wout
; movlw High Label ; get high byte MPLAB 8.53 killed high
movlw Label >> 8 ; get high byte
movwf Wout + 1
endm
;---[find correct bank for a BIT variable]----------------------------------
CHKRP?T macro reg, bit
CHK?RP reg
endm
;---[This creates the main Interrupt Service Routine (ISR)]-----------------
INT_CREATE macro
local OverCREATE
L?GOTO OverCREATE
INT_ENTRY
ifndef FSR0L
if (CODE_SIZE <= 2)
movwf wsave ; 1 copy W to wsave register
swapf STATUS,W ; 2 swap status reg to be saved into W
clrf STATUS ; 3 change to bank 0
movwf ssave ; 4 save status reg to a bank 0 register
movf PCLATH,W ; 5 move PCLATH reg to be saved into W reg
movwf psave ; 6 save PCLATH reg to a bank 0 register
endIF
movf FSR,W ; 7 move FSR reg to be saved into W reg
movwf fsave ; 8 save FSR reg to a bank 0 register
else
banksel 0 ; BANK 0 for F1 chips
endif
variable PREV_BANK = 0
MOVE?CT 0, _Vars_Saved
List_Start
ifdef LoopWhenServiced
MOVE?CT 0, _Serviced ; indicate nothing has been serviced
endif
INT_LIST ; Expand the users list of interrupt handlers
; INT_LIST macro must be defined in main program
ifdef LoopWhenServiced
BIT?GOTO 1, _Serviced, List_Start
endif
ifdef ReEnterUsed ; if ReEnterPBP.bas was included
CHKRP?T _Vars_Saved
btfss _Vars_Saved ; if PBP system vars have been saved
goto INT_EXIT
L?GOTO _RestorePBP ; Restore PBP system Vars
endif
INT_EXIT
variable PREV_BANK = 0
ifndef FSR0L ; if chip is not an F1 - restore context
clrf STATUS ; BANK 0
movf fsave,W ; Restore the FSR reg
movwf FSR
movf psave,w ; Restore the PCLATH reg
movwf PCLATH
swapf ssave,w ; Restore the STATUS reg
movwf STATUS
swapf wsave,f
swapf wsave,w ; Restore W reg
endif
retfie ; Exit the interrupt routine
;-----------------------------
LABEL?L OverCREATE
bsf INTCON, 6 ; Enable Peripheral interrupts
bsf INTCON, 7 ; Enable Global interrupts
endm
ENDASM
ASM
;---[Add an Interrupt Source to the user's list of INT Handlers]------------
#INT_HANDLER macro FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
list
local AfterSave, AfterUserRoutine, NoInt
ifdef FlagBit
CHK?RP EnableReg
btfss EnableReg, EnableBit ; if the INT is enabled
goto NoInt
CHK?RP FlagReg
btfss FlagReg, FlagBit ; and the Flag set?
goto NoInt
ifdef LoopWhenServiced
MOVE?CT 1, _Serviced
endif
if (Type == PBP) ; If INT handler is PBP
ifdef ReEnterUsed
btfsc _Vars_Saved
goto AfterSave
GetAddress AfterSave, _RetAddr
L?GOTO _SavePBP ; Save PBP system Vars
LABEL?L AfterSave
else
error ReEnterPBP must be INCLUDEd to use PBP type interrupts
endif
endif
GetAddress AfterUserRoutine, _RetAddr ; save return address
L?GOTO Label ; goto the users INT handler
LABEL?L AfterUserRoutine
if (Reset == YES)
CHK?RP FlagReg
bcf FlagReg, FlagBit ; reset flag (if specified)
endif
else
INT_ERROR "INT_Handler"
endif
NoInt
banksel 0
PREV_BANK = 0
endm
;-----------------------------------
#define INT_HANDLER(FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset) #INT_HANDLER FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
ifndef INT_Handler
#define INT_Handler(FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset) #INT_HANDLER FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
#define int_handler(FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset) #INT_HANDLER FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
#define Int_Handler(FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset) #INT_HANDLER FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
#define Int_handler(FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset) #INT_HANDLER FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
#define int_Handler(FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset) #INT_HANDLER FlagReg,FlagBit, EnableReg,EnableBit, Label, Type,Reset
endif
;---[Returns from a "goto" subroutine]--------(RetAddr must be set first)---
#INT_RETURN macro
CHK?RP _RetAddr
movf _RetAddr + 1, W ; Set PCLATH with top byte of return address
movwf PCLATH
movf _RetAddr, W ; Go back to where we were
movwf PCL
endm
;_____________________________
#define INT_RETURN #INT_RETURN
ifndef INT_Return
#define INT_Return #INT_RETURN
#define int_return #INT_RETURN
#define Int_Return #INT_RETURN
#define Int_return #INT_RETURN
#define int_Return #INT_RETURN
endif
;----[Display not found error]----------------------------------------------
INT_ERROR macro From
error From - Interrupt Flag ( FlagReg,FlagBit ) not found.
endm
;---[Enable an interrupt source]--------------------------------------------
ifndef INT_ENABLECLEARFIRST
#define INT_ENABLECLEARFIRST 1 ; default to Clear First
endif ; use DEFINE INT_ENABLECLEARFIRST 0 to NOT clear First
#INT_ENABLE macro FlagReg, FlagBit, EnableReg, EnableBit
ifdef FlagBit
ifdef INT_ENABLECLEARFIRST
if (INT_ENABLECLEARFIRST == 1) ; if specified
MOVE?CT 0, FlagReg, FlagBit ; clear the flag first
endif
endif
MOVE?CT 1, EnableReg, EnableBit ; enable the INT source
else
INT_ERROR "INT_ENABLE"
endif
endm
;_____________________________
#define INT_ENABLE(FlagReg, FlagBit, EnableReg, EnableBit) #INT_ENABLE FlagReg, FlagBit, EnableReg, EnableBit
ifndef INT_Enable
#define INT_Enable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_ENABLE FlagReg, FlagBit, EnableReg, EnableBit
#define int_enable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_ENABLE FlagReg, FlagBit, EnableReg, EnableBit
#define Int_Enable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_ENABLE FlagReg, FlagBit, EnableReg, EnableBit
#define Int_enable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_ENABLE FlagReg, FlagBit, EnableReg, EnableBit
#define int_Enable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_ENABLE FlagReg, FlagBit, EnableReg, EnableBit
endif
;---[Disable an interrupt source]-------------------------------------------
#INT_DISABLE macro FlagReg, FlagBit, EnableReg, EnableBit
ifdef FlagBit
MOVE?CT 0, EnableReg, EnableBit ; disable the INT source
else
INT_ERROR "INT_DISABLE"
endif
endm
;_____________________________
#define INT_DISABLE(FlagReg, FlagBit, EnableReg, EnableBit) #INT_DISABLE FlagReg, FlagBit, EnableReg, EnableBit
ifndef INT_Disable
#define INT_Disable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_DISABLE FlagReg, FlagBit, EnableReg, EnableBit
#define int_disable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_DISABLE FlagReg, FlagBit, EnableReg, EnableBit
#define Int_Disable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_DISABLE FlagReg, FlagBit, EnableReg, EnableBit
#define Int_disable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_DISABLE FlagReg, FlagBit, EnableReg, EnableBit
#define int_Disable(FlagReg, FlagBit, EnableReg, EnableBit) #INT_DISABLE FlagReg, FlagBit, EnableReg, EnableBit
endif
;---[Clear an interrupt Flag]-----------------------------------------------
#INT_CLEAR macro FlagReg, FlagBit, EnableReg, EnableBit
ifdef FlagBit
MOVE?CT 0, FlagReg, FlagBit ; clear the flag
else
INT_ERROR "INT_CLEAR"
endif
endm
;_____________________________
#define INT_CLEAR(FlagReg, FlagBit, EnableReg, EnableBit) #INT_CLEAR FlagReg, FlagBit, EnableReg, EnableBit
ifndef INT_Clear
#define INT_Clear(FlagReg, FlagBit, EnableReg, EnableBit) #INT_CLEAR FlagReg, FlagBit, EnableReg, EnableBit
#define int_clear(FlagReg, FlagBit, EnableReg, EnableBit) #INT_CLEAR FlagReg, FlagBit, EnableReg, EnableBit
#define Int_Clear(FlagReg, FlagBit, EnableReg, EnableBit) #INT_CLEAR FlagReg, FlagBit, EnableReg, EnableBit
#define Int_clear(FlagReg, FlagBit, EnableReg, EnableBit) #INT_CLEAR FlagReg, FlagBit, EnableReg, EnableBit
#define int_Clear(FlagReg, FlagBit, EnableReg, EnableBit) #INT_CLEAR FlagReg, FlagBit, EnableReg, EnableBit
endif
ENDASM
Thanks to All-
It looks as if I may be on my way!
An AMAZING amount of info here on this board.........
Where can I download the latest DT-Ints-18 AND ReEnterPBP-18? PIC18F67K90, PBP3 - Thanks - DarrelTaylor.com is all links, no beef.
As in chat box,
http://www.picbasic.co.uk/forum/showthread.php?t=19638
Under 18 bit link.
Then DOWNLOAD link at very top.
Links are there.
Robert
Thanks - just what I needed! Now the fun starts...
Thanks a lot, Robert. I have installed them and they do exactly what I needed. Thanks Darrel...
Now I have a question. I added the RTCC interrupt to the DT-INTS-18 coding by adding a define and the "ifdef" statement (using an 18F67K90). I noticed that after I return from my RTCC_INT handler, the RTCCIF flag bit is cleared, apparently by the INT_RETURN macro. Did I leave out more changes to the DT-INTS-18 code, or are all interrupt flags cleared by INT_RETURN? My work around was to create a copy of RTCCIF and poll it instead.
Clock_Int: 'RTCC ISR
RTCC_IF = 1 'set the interrupt flag copy because macro INT_RETURN clears RTCCIF
@ INT_RETURN
Howard
Howard, you must be setting the reset flag to TRUE by entering YES in the interrupt declaration ResetFlag field like this:
ASM
INT_LIST macro ;IntSource Label Type ResetFlag
INT_Handler IC3DRIF_INT, _InputSignal, ASM, yes
endm
INT_CREATE
ENDASM
Hello
Where can I find the homepage that were on these two links?
And where do I download the latest DT_INTS?
DT_INTS-14 (12F-16F)
http://darreltaylor.com/DT_INTS-14/intro.html
DT_INTS-18 (18F)
http://darreltaylor.com/DT_INTS-18/home.html