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.
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:
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
Bookmarks