SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
WEll , another day, another bug
This one stems from what i think is a result of sillion issue with the ADC
Chip is a 16F1947 Rev 2 device ID is shown as 2522
The erratica from microchip tells of a ADC problem under some conditions , from what i am seeing is under most conditions and it hangs the cpu
http://ww1.microchip.com/downloads/e...Doc/80497F.pdf
The code has worked fine on other chips ( 16f1825, 16F1829 ,) and does work ok on this one when it does not hang the chip
Typically the chip hangs ranging form 1 min to to 20mins , but the code functions as it should during that time
i confirmed this part of the code by not doing the ADcin command and setting the "Value" variable = to a set number with no other changes and no cpu occured - tested for over 1 hour
Unfortunately i dont have another silicon revision to confirm my thoughts , but a workable get around would confirm the issue
Microchip tells of 2 workarounds , ...
1. is change to dedicated RC oscillator - not an option - when using the internal osc
2. Provide a fixed delay in software to stop the A-to-D conversion manually, after all ten bits are
converted, but before the conversion would complete automatically
Option 2 means that the command of ADCIN cant be used ?? and need to be a set register , counter and flag approch , which i not done for
ADC, so some input on this would be helpful.
snippets of code as it relate to the ADC as follows
regards
Sheldon
my internal is 32Mhz
Code:
DEFINE ADC_BITS 10 ' Number of bits in ADCIN result - Required for adcin command
DEFINE ADC_SAMPLEUS 10 ' ADC sampling time in microseconds - Required for adcin command
' ------------ADC Settings , routines and Variables ----------------
ADCON0 = %00010001 ' bit 7 -N/A , Bit 6-2 = ADC chan Sel /Temperature output /FVR output = AN4 sel = 00100 ,
' Bit 1 - Go/_done status flag - 1 = Go do ADC / 0 = Done ADC , Bit 0 = Enable ADC = 1 / 0 = Disable ADC
ADCON1 = %11110000 ' bit 7 = 1 ADFM ( ADRESH, ADRESL - right justify ).Bit 6-4 ADCS = 111 - using FRC internal ( 1.6us per sample)
' Bit3 - N/A , Bit2 = 0 (Vref- is connected to Vss) , Bit1-0 = 00 - Vref+ connected to VDD
FVRCON = %00000010 ' Bit 7 =0 disable Fixed Voltage Ref Modual, Bit 6 = VRef ready bit =1 always ok on 16F1825, Bit 5 - Temp indicator 1= enable/0 = disable
' Bit 4 = Temp Indicator Range Sel 0=Vout -Low range / 1= Vout -High range , Bit 3-2 = 00( DAC Fixed volt sel )
' Bit 1-0 = 10 - ADC Fixed Vref of 2.048v
AvgCount CON 10 ' Number of samples to average in Average routine
Fastspread CON 200 ' Fast Average threshold +/- in Average routine
ADavg VAR WORD ' Accumulated Varable of Readings in Average routine
Value VAR WORD ' Temp varable assigned in Average routine
' ----------------------------------------------------------------------------------------
y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
ADCIN 4 ,Value ' Read PortA.5 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
' to comparitor and ADC pin selected and gives result.
gosub Average ' Go do running average of ADC reading
y = y+1 ' Increment loop counter
wend
' -=-=-=-=-=-= Average Analog values - a DT routine -=-=-=-=-=-=-=-=-=-=
Average:
IF Value = ADavg Then NoChange
IF ABS (Value - ADavg) > Fastspread OR Value < AvgCount Then FastAvg
IF ABS (Value - ADavg) < AvgCount Then RealClose
ADavg = ADavg - (ADavg/AvgCount)
ADavg = ADavg + (Value/AvgCount)
GoTo AVGok
FastAvg:
ADavg = Value
GoTo AVGok
RealClose:
ADavg = ADavg - (ADavg/(AvgCount/4))
ADavg = ADavg + (Value/(AvgCount/4))
AVGok:
Value = ADavg ' Put Average back into Value
NoChange:
Return
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
by setting the ADC command enable / disable at the beginning / end of the subrouting which has the adcin command , the hanging is not as often but its there still
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
Wow, what a ballsie guy. If I saw anything from from Microchip even hinting at such a problem, I'd drop that PIC so fast.
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
well i next time ill ask the chip supplier for rev3 or better , but like most supplier its is very rare they actually supply details of the silicon ver with chip supplied details
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
I think chips are like children in that once you own them you have to work with what you have... Certainly abandoning one to start again with another is, except under the rarest circumstances, a difficult choice.
While many of you do not share the holiday, I wish for you all the blessings we in the US celebrate this Thanksgiving season.
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
rereading the methods to get around the problem option 1 actully looks the best way , but i am not sure how to do this
but it appears that by setting the ADC f/OSC conversion clock to the FRC internal , then putting the CPU into low power mode ( SLEEP mode ) , then doing a sample , then exit low power mode (SLEEP mode) by using the watchdog timer ( no other way i can see to make sleep mode exit)
i am guessing this may work but not sure ,
1. set up watchdog timer to be enabled by software bit ( _WDTE_SWDTEN ) ;WDT controlled by the SWDTEN bit in the WDTCON register) in config1 word
2. set WDTCON with 1ms timeout and enable watchdog timer lowest time
3. do asm command of sleep - to enter low power mode ( NAP 0 = too long a time about 18ms)
4. do adcin command which should complete a sample in 1.6uS
5.turn off watchdog timer
so the assumption is that the adcin command will work in low power mode and sample will complete in a max of 1ms
test to see !!!!!!!!!!!!
but anyone else can advise then please do
Cheers sheldon
item 1
Code:
' config for 16F1947
#CONFIG
;----- CONFIG1 Options --------------------------------------------------
__config _CONFIG1, _FOSC_INTOSC & _WDTE_SWDTEN & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
;----- CONFIG2 Options --------------------------------------------------
__config _CONFIG2, _LVP_OFF & _BORV_HI & _STVREN_ON & _PLLEN_ON & _WRT_OFF & _VCAPEN_OFF
#ENDCONFIG
item 2 - 5
Code:
ADCON0 = %00010001 ' enable ADC AN4 , ADCON1 setup at start of program
y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
' silicon bug in rev2 of 16F1947 , requires ADC to be done in lowpower mode and with FDC osc clock internal
WDTCON = %00000001 ' start watchdog timer set for 1ms so that sleep mode is exit after doing adcin commands
asm
SLEEP ;'Put cpu into low power mode
endasm
ADCIN 4 ,Value ' Read PortA.5 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
WDTCON = %00000000 ' stop watchdog timer after adcin commands
gosub Average ' Go do running average of ADC reading
y = y+1 ' Increment loop counter
wend
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
That won't work, since it will have to wake from sleep before running the ADCIN command.
I might suggest something like this...
It doesn't work in the simulator, but hopefully it will work on real hardware.
It uses the ADIF interrupt to wake from sleep. With the FRC clock, it only takes 48uS to complete a conversion.
Waiting for the WDT is going to take 1000uS or more.
The WDT is enabled just in case the conversion doesn't complete, but the ADIF should always wake it up first.
It assumes you are using other interrupts, and disables them accordingly.
Code:
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
OSCCON = %11110000 ; 32Mhz Internal
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25 ' 19200 Baud @ 32MHz, 0.16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
ADON VAR ADCON0.0 ; A/D converter Enable
GoDone VAR ADCON0.1 ; A/D conversion in progress
ADIE VAR PIE1.6 ; A/D Interrupt Enable
ADIF VAR PIR1.6 ; A/D Interrupt Flag
GIE VAR INTCON.7 ; Global Interrupt Enable
GIEsave VAR BIT ; Saves state of GIE
ADchan VAR BYTE ; Current A/D channel
ADvalue VAR WORD ; A/D result
ADCON1 = %10110000 ; Right Justify, FRC clock
ADON = 1
Main:
FOR ADchan = 0 TO 16 ; Loop through all A/D channe
ADCON0 = (ADCON0 & %11) | (ADchan << 2) ; Set Analog Channel
PAUSEUS 20 ; Acquisition time
GIEsave = GIE ; Save state of Global Interrupts
GIE = 0 ; Disable Global interrupts
ADON = 0 ; reset A/D module
ADON = 1
ADIF = 0 ; Clear Analog Interrupt Flag
ADIE = 1 ; Enable Analog Interrupt
GoDone = 1 ; Start Analog conversion
@ SLEEP ; go to SLEEP
ADIE = 0 ; Disable Analog Interrupt
GIE = GIEsave ; Restore Global Interrupt state
ADvalue.HighByte = ADRESH ; Get A/D result
ADvalue.LowByte = ADRESL
HSEROUT [DEC2 ADchan," = ",DEC ADvalue,13,10]
PAUSE 200
NEXT ADchan
GOTO Main
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
thanks Darrel,
I have put this code in for the AN4 sensor only , however it seems i will have to do this for other A/D services for this rev of chip ???? :mad:
your DT_INTS-14.bas is included as part of this code for timer0 , and the variable GIE was already in use ,
timer0 setup as 8ms timer , and this A/D routine is called from it after incrementing counters of timer0 = 5sec duration to do a read of the Voltage level
couple of questions
1. Is the duration of the sample time of 20us seemed long for 1 A/D channel ? as the spec sheet for conversion using FRC is about 1.6us average - a max period of 6uS
2. i thought the sleep instruction ( low power mode ) may need to be issued prior to the conversion starting , or are all commands after a sleep command not actioned till sleep mode is terminated ?
3. as this now monitors the interrupt for sleep to finish , then the duration of this routine must be shorter than any other generated interrupts using DT_INT14 else this will not work ??
the code as it stands now
waiting on a Battery power duration test to complete to see if this works ok
Cheers
Sheldon
Code:
Get_volts :
ADON VAR ADCON0.0 ; A/D converter Enable
GoDone VAR ADCON0.1 ; A/D conversion in progress
ADIE VAR PIE1.6 ; A/D Interrupt Enable
ADIF VAR PIR1.6 ; A/D Interrupt Flag
GIEsave VAR BIT ; Saves state of GIE
ADCON0 = %00010001 ' enable ADC AN4 ,( ADCON1 setup at start of program , Right Justify, FRC clock )
y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
' silicon bug in rev2 of 16F1947 , requires ADC to be done in lowpower mode and with FDC osc clock internal
' also ADCIN command wont work in sleep mode , interupts exit sleep mode
PAUSEUS 20 ; Acquisition time
GIEsave = GIE ; Save state of Global Interrupts ( GIE defined in DT_INTS-14.bas )
GIE = 0 ; Disable Global interrupts
ADON = 0 ; reset A/D module
ADON = 1 ; turn on A/D module
ADIF = 0 ; Clear Analog Interrupt Flag
ADIE = 1 ; Enable Analog Interrupt
GoDone = 1 ; Start Analog conversion
@ SLEEP ; go to SLEEP
ADIE = 0 ; Disable Analog Interrupt
GIE = GIEsave ; Restore Global Interrupt state ( GIE defined in DT_INTS-14.bas )
value.HighByte = ADRESH ; Get A/D result
value.LowByte = ADRESL
' ADCIN 4 ,Value ' Leave out for Rev 2 of 16F1947 - Read PortA.5 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
gosub Average ' Go do running average of ADC reading
y = y+1 ' Increment loop counter
wend
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
1) If you are only reading 1 channel, you don't need any acquisition time.
2) When you put a PIC to SLEEP, all program execution STOPS.
Some peripherals may continue to operate, but the program will not run again until it wakes up.
3) When you put a PIC to SLEEP, the main oscillator is shut-down.
If you are running TIMER0 from the system clock, it too stops during sleep, and your 8mS periods will be extended.
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
thanks darrel ,
ill let you know how it goes for testing in 24 hours
Well i wish had known of issues with this chip prior , will make an effort to check every time now for microchips erratica on each chip before using
oh well , it seems this problem is only with the silicon ver 2 , i hope the supplier can help me with higher revisions exchanged , cos this is dog of a version
cheers
Sheldon
Re: SILLION BUG issue on ADC and get around required 16F1947 rev 2 silicon
seems to be workin , cheers darrel