• AVR Freaks

AnsweredHot!Problem on PIC16F1789 and ADC module

Author
aheuchamps
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2021/03/03 11:50:26
  • Location: 0
  • Status: offline
2021/03/04 03:44:15 (permalink)
0

Problem on PIC16F1789 and ADC module

Hello everyone, I hope you are fine.
I am working on a PIC16F1789, and I encounter some difficulties.
The idea of the code I am writing is the following:
 
        a timer generates an interrupt every 2 seconds. In the interrupt routine, the ADC is used to check a voltage level. If the measured level is below a given threshold, a LED is light up for as long as the measured level is low.
 
Now come the problems:
  1. I cannot get a timer to generate an interrupt after 2 seconds, I only can have one for a time smaller or equal to 0.5 second
  2. The comparison with the given threshold seems not to work properly, and my LED is turned on most of the time
Can someone help me please ?
 
N.B. : attached to this question is the .s file I use. Moreover, here is the .inc file included in the .s file
; Assembly source line config statements

#include <xc.inc>

; CONFIG1
  CONFIG FOSC = INTOSC ; Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
  CONFIG WDTE = OFF ; Watchdog Timer Enable (WDT disabled)
  CONFIG PWRTE = OFF ; Power-up Timer Enable (PWRT disabled)
  CONFIG MCLRE = OFF ; MCLR Pin Function Select (MCLR/VPP pin function is digital input)
  CONFIG CP = OFF ; Flash Program Memory Code Protection (Program memory code protection is disabled)
  CONFIG CPD = OFF ; Data Memory Code Protection (Data memory code protection is disabled)
  CONFIG BOREN = ON ; Brown-out Reset Enable (Brown-out Reset enabled)
  CONFIG CLKOUTEN = OFF ; Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
  CONFIG IESO = ON ; Internal/External Switchover (Internal/External Switchover mode is enabled)
  CONFIG FCMEN = ON ; Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

; CONFIG2
  CONFIG WRT = OFF ; Flash Memory Self-Write Protection (Write protection off)
  CONFIG VCAPEN = OFF ; Voltage Regulator Capacitor Enable bit (Vcap functionality is disabled on RA6.)
  CONFIG PLLEN = OFF ; PLL Enable (4x PLL disabled)
  CONFIG STVREN = ON ; Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
  CONFIG BORV = LO ; Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
  CONFIG LPBOR = OFF ; Low Power Brown-Out Reset Enable Bit (Low power brown-out is disabled)
  CONFIG LVP = OFF ; Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

#1
ric
Super Member
  • Total Posts : 30223
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Problem on PIC16F1789 and ADC module 2021/03/04 12:37:03 (permalink) ☼ Best Answerby aheuchamps 2021/03/04 12:54:27
+1 (1)
If you can't configure a timer for the time length you want, just count multiple rollovers until you get there.
e.g. four 500ms rollovers will give you two seconds.
 
For something that slow, you really don't need to use a hardware interrupt at all, your "do nothing" main loop could just poll the TMR1IF flag, and do things each time you see it set.
 
A real interrupt service should never have blocking code or time delays in it.
Even if you were doing hardware interrupts, you would normally just start an ADC conversion on one timer interrupt, and use the ADC interrupt to read the result later, not do everything inside a single call to the interrupt service.
 
your wait for "tacq" is faulty. You are decrementing memory address 0x005.
 
n.b. do NOT turn the ADC on and off like that. Just leave it on, or you are adding significantly more delays.
 
Your check for the ADC interrupt is pointless. If you wait for the conversion by polling the GO/DONE bit, the ADCIF flag will always be set too. I'm not sure why you are silently aborting if it is not set. You forgot to select bank 0 before reading PIR1, so it's testing the wrong register, so probably always silently aborting.
 
 
 
 
 
 
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
aheuchamps
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2021/03/03 11:50:26
  • Location: 0
  • Status: offline
Re: Problem on PIC16F1789 and ADC module 2021/03/04 13:09:45 (permalink)
0
Hi Ric, thank you for your quick answer.
 
I do not get why my wait for "tACQ" is faulty (I do not get why you are telling I am decreasing a memory address, I thought that using the command "#define tACQ 05h" was to a synthaxic substitution, i.e. each "tACQ" is replaced by the value "05h") ?
 
Also, I am not sure I understand correctly: each xxx time, I launch a conversion inside an interrupt (set the GO/DONE bit), then resume the "main_loop", in which I check for the value of the ADIF bit. If it is set, I check if the conversion result is smaller than a defined threshold. Is this right ?
 
Thank you once again for your answer,
aheuchamps
#3
ric
Super Member
  • Total Posts : 30223
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Problem on PIC16F1789 and ADC module 2021/03/04 14:26:11 (permalink) ☄ Helpfulby aheuchamps 2021/03/05 00:24:18
+1 (1)
aheuchamps
I do not get why my wait for "tACQ" is faulty (I do not get why you are telling I am decreasing a memory address, I thought that using the command "#define tACQ 05h" was to a synthaxic substitution, i.e. each "tACQ" is replaced by the value "05h") ?

Yes it is, so where you have:
    decfsz tACQ, 1 ;is "tACQ" equal to 0 ?

after the text substitution, you have
    decfsz 5, 1 ;is "tACQ" equal to 0 ?

The parameter to the "decfsz" instruction is the address of the register to decrement, so that instruction is decrementing the register at address 5, which is one of the "core" registers, FSR0H.
So, you are decrementing FSR0H. As you don't use that register anywhere else, after the first interrupt (which will have a random delay) all subsequent interrupts will loop 256 times when it gets there.
 

Also, I am not sure I understand correctly: each xxx time, I launch a conversion inside an interrupt (set the GO/DONE bit), then resume the "main_loop", in which I check for the value of the ADIF bit. If it is set, I check if the conversion result is smaller than a defined threshold. Is this right ?

You don't even need to use the hardware interrupt. Your main_loop could be polling the TMR1IF flag, and incrementing (or decrementing) a variable each time, then after X roll overs you could initiate an ADC conversion.
As you're not inside an interrupt service, you could just continue the same technique of waiting for the GO/DONE bit to clear before reading the result and doing the comparison. The ADIF flag is only useful if you need to be doing other things in your main loop, and need the comparison to be done inside an interrupt service triggered the moment the conversion is complete.
 
Also, when you ARE using hardware interrupts, don't set the GIE bit until all your other initialisation code has been run. You do NOT want an interrupt to trigger before you finish setting up your PIC!
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#4
aheuchamps
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2021/03/03 11:50:26
  • Location: 0
  • Status: offline
Re: Problem on PIC16F1789 and ADC module 2021/03/05 00:25:45 (permalink)
0
Oooh ok now I get it better.
 
Thanks a lot for your answer, I appreciate it.
 
Have a nice day,
aheuchamps
#5
Jump to:
© 2021 APG vNext Commercial Version 4.5