20x2 and FVR

ckoehn

Member
The 20X2 doesn't support the FVR directly but it does appear it contains FVR hardware which could perhaps be used through direct SFR access.
I need a FVR on the 20x2 also and seen this post from Hippy. How would I go about doing this?

Later,
Clint
 

AllyCat

Senior Member
Hi Clint,

First, you need the Microchip Data Sheet from this link.

The FVR is described in section 20.2 and it appears you need to use the Special Function Register VREFCON0 .

Then go to the Tables in section 3.2. The full address appears to be $FBA . The PICaxe command only supports a single byte and M2s (which I always use) and X2s are handled differently, but it appears that you just need to drop the first F.

Therefore, I believe you should use a POKESFR $BA, %xxxx0000 to set the FVR.

Then you may need to check other modules (e.g. the comparator in section 17) to see how to select the FVR as an input.

Cheers, Alan.
 

ckoehn

Member
I tried this..

symbol ADCON1=$C1
symbol VREFCON0=$BA

pokesfr ADCON1, %1000
pokesfr VREFCON0, %10110000
but I don't think that worked.

That is one reason I ask for help, I've never done this before. :)

Later,
Clint
 

hippy

Technical Support
Staff member
You can use PEEKSFR to check what values are in SFR registers once written.

When using unsupported features it is possible they may conflict with PICAXE firmware and you will have to check if they do or not and work round those issues if they arise. For example a READADC command may set SFR's for how it wants things. I don't know if it does; you would have to check that, see if SFR's are the same as how you want them after a READADC as before etc.

When it comes to things not working; it helps to explain exactly what did not work, how the results differ from what was expected, the manner in which you are obtaining the result, and how you are determining things did not work. Details of the program and hardware being used will help identify other potential mistakes such as reading the wrong pins or not using the correct commands, and will help others confirm what you are doing is right or should work.

Not everything will immediately work but results obtained against results expected help point to why things aren't working and ways round those obstacles.
 

ckoehn

Member
When I said I've never done this before, I meant on a 20x2. I have used the settings with gcbasic on a 18F14k22 chip, like I posted above, and it worked.

The volt reading I had going in and the readadc10 readings I had coming out computed with a 5v ref not 4.096v ref, so.. it didn't work.

I think the adc registers are configured with the readadc10 commands and it won't work to use the sfr to change the settings.

I moved to the 20M2 which is easy to set the 4.096v ref and I think I'll have enough program memory for what I need it for.

If someone finds how to make the 20X2 have a FVR I sure hope they post it here.

Later,
Clint
 

hippy

Technical Support
Staff member
Have you checked to see if it is the READADC10 command changing the SFR's from how you set them ?

If that is the case you should be able to achieve what you want by setting the SFR's and undertaking the equivalent of a READADC10 by poking and peeking the ADC controlling SFR's.

I would have expected that to work but I haven't tried it.
 

hippy

Technical Support
Staff member
It appears the PICAXE firmware continually resets the ADCON1 SFR to zero so it's not possible to use the FVR for Vref on the 20X2.
 

AllyCat

Senior Member
Hi,

Yes, my thoughts exactly (Edit: to post #6). I have used the same procedure for "Higher Resolution" versions of READINTERNALTEMP and CALIBADC10.

As said before, I use only M2s, but the basic code should be similar (previously posted on the forum, but easier to list again):

Code:
#picaxe 08M2		; Or any other M2
readitempFVR:
      pokesfr ADCON1, %10010011 	; Right justify; clock/8; REF=FVR     
      pokesfr ADCON0, %01110101 	; Select Temperature input and Turn ADC On
      pokesfr ADCON0, %01110111 	; Start conversion
      peeksfr ADRESL,b4,b5 		; Read lower and upper bytes into w2
      return
Cheers, Alan.
 

inglewoodpete

Senior Member
It appears the PICAXE firmware continually resets the ADCON1 SFR to zero so it's not possible to use the FVR for Vref on the 20X2.
It would be interesting to see if the PICAXE constantly resets ADCON1 all the time or only when ADC config and read commands are used. If so, with further experimentation, it may be possible to perform the equivalent of a ReadADC10 command using PokeSFR and PeekSFR commands. Edit: The PokeSFR and PeekSFR method is what AllyCat is suggesting, above
 

hippy

Technical Support
Staff member
It would be interesting to see if the PICAXE constantly resets ADCON1 all the time or only when ADC config and read commands are used.
All the time. Observed by poking a value to ADCON1 and immediately peeking the value back.
 

AllyCat

Senior Member
Hi,

All the time. Observed by poking a value to ADCON1 and immediately peeking the value back.
Hmm, I wonder why, when it contains only ADC-relevant flags?

Conversely, it appears that the M2 (or at least my just-tested 20M2) never clears ADCON1, to the extent that if an ADCCONFIG 3 is used in a basic program, then any subsequent CALIBADC{10} gives the "wrong" answer. :(

Cheers, Alan.
 

PhilHornby

Senior Member
14M2 and ADC...

I couldn't decide whether to start a new thread or not. I think this is vaguely related to this discussion (though I am using a 14M2) :-

I've been working my way through the (many) Code Snippets for reading the supply voltage (e.g. this one), trying to follow the detail of what happens at the PIC level.

The FVRSETUP, DACSETUP and DACLEVEL commands all appear to make the expected changes to their related SFRs, but ADCCONFIG has me confused.

The following code snippet issues an ADCCONFIG 3 command, but the contents of the associated SFRs do not change until a READDAC10 command is executed. At one point, I wondered if I was looking at the wrong SFRs, but when they do change, the contents look in line with my expectations :-
Code:
[COLOR=navy]#picaxe [/COLOR][COLOR=black]14m2[/COLOR]
[COLOR=green];Various SFR definitions[/COLOR]
[COLOR=blue]symbol ADCON0  [/COLOR][COLOR=darkcyan]= [/COLOR][COLOR=navy]$3D                            [/COLOR][COLOR=green];9Dh[/COLOR]
[COLOR=blue]symbol ADCON1  [/COLOR][COLOR=darkcyan]= [/COLOR][COLOR=navy]$3E                            [/COLOR][COLOR=green];9Eh[/COLOR]
[COLOR=blue]do
      peekSFR ADCON0[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b0 [/COLOR][COLOR=black]: [/COLOR][COLOR=blue]sertxd (cr[/COLOR][COLOR=black],[/COLOR][COLOR=blue]lf[/COLOR][COLOR=black],[/COLOR][COLOR=red]"ADCON0: "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit7[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit6[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit5[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit4[/COLOR][COLOR=black],[/COLOR][COLOR=red]" "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit3[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit2[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit1[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit0[/COLOR][COLOR=black],[/COLOR][COLOR=red]" "[/COLOR][COLOR=blue]) 
      peekSFR ADCON1[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b0 [/COLOR][COLOR=black]: [/COLOR][COLOR=blue]sertxd ([/COLOR][COLOR=red]"ADCON1: "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit7[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit6[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit5[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit4[/COLOR][COLOR=black],[/COLOR][COLOR=red]" "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit3[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit2[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit1[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit0[/COLOR][COLOR=blue])
      
      adcconfig [/COLOR][COLOR=navy]3

      [/COLOR][COLOR=blue]peekSFR ADCON0[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b0 [/COLOR][COLOR=black]: [/COLOR][COLOR=blue]sertxd (cr[/COLOR][COLOR=black],[/COLOR][COLOR=blue]lf[/COLOR][COLOR=black],[/COLOR][COLOR=red]"ADCON0: "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit7[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit6[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit5[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit4[/COLOR][COLOR=black],[/COLOR][COLOR=red]" "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit3[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit2[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit1[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit0[/COLOR][COLOR=black],[/COLOR][COLOR=red]" "[/COLOR][COLOR=blue]) 
      peekSFR ADCON1[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b0 [/COLOR][COLOR=black]: [/COLOR][COLOR=blue]sertxd ([/COLOR][COLOR=red]"ADCON1: "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit7[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit6[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit5[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit4[/COLOR][COLOR=black],[/COLOR][COLOR=red]" "[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit3[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit2[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit1[/COLOR][COLOR=black],#[/COLOR][COLOR=purple]bit0[/COLOR][COLOR=blue])

      readdac10 [/COLOR][COLOR=purple]W5
      [/COLOR]
[COLOR=blue]loop[/COLOR]
The output is as follows :-
Code:
-> initial condition
ADCON0: 0000 0000 ADCON1: 0000 0000
-> adcconfig 3 - seems to have no effect
ADCON0: 0000 0000 ADCON1: 0000 0000
-> readdac10 W5 - now ADCON0 and ADCON1 update
ADCON0: 0111 1000 ADCON1: 1010 0011
-> adcconfig 3 - values don't change after this
ADCON0: 0111 1000 ADCON1: 1010 0011
This is part of a larger code snippet, which runs and gives the correct answer :-
Code:
[COLOR=navy]#picaxe [/COLOR][COLOR=black]14m2[/COLOR]

[COLOR=blue]do
      
      fvrsetup fvr2048                          [/COLOR][COLOR=green]; Select the 2.048 volt reference 
      [/COLOR][COLOR=blue]dacsetup [/COLOR][COLOR=navy]$80                              [/COLOR][COLOR=green]; Enable the DAC referenced to Vdd
      [/COLOR][COLOR=blue]daclevel [/COLOR][COLOR=navy]10                               [/COLOR][COLOR=green]; DAC = Vdd * 10 / 32 so always should be less than the FVR2048 reference (Vdd < 6v)
      [/COLOR][COLOR=blue]adcconfig [/COLOR][COLOR=navy]3                               [/COLOR][COLOR=green]; Use the FVR as reference voltage for ADC and READDAC
      [/COLOR][COLOR=blue]readdac10 [/COLOR][COLOR=purple]W5                              [/COLOR][COLOR=green]; Read the voltage on the "wiper" of the DAC
      [/COLOR][COLOR=purple]W7 [/COLOR][COLOR=darkcyan]= [/COLOR][COLOR=purple]W5 [/COLOR][COLOR=darkcyan]* [/COLOR][COLOR=navy]7 [/COLOR][COLOR=darkcyan]** [/COLOR][COLOR=navy]59919 [/COLOR][COLOR=darkcyan]+ [/COLOR][COLOR=navy]55 [/COLOR][COLOR=darkcyan]/ [/COLOR][COLOR=navy]100           [/COLOR][COLOR=green];Calculate to 3 dp, then round to 1.
      [/COLOR][COLOR=blue]bintoascii [/COLOR][COLOR=purple]W7[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b2[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b1[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b0                    [/COLOR][COLOR=green];Convert to ASCII
      [/COLOR][COLOR=blue]sertxd (cr[/COLOR][COLOR=black],[/COLOR][COLOR=blue]lf[/COLOR][COLOR=black],[/COLOR][COLOR=red]"Voltage: "[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b1[/COLOR][COLOR=black],[/COLOR][COLOR=red]"."[/COLOR][COLOR=black],[/COLOR][COLOR=purple]b0[/COLOR][COLOR=black],[/COLOR][COLOR=red]"V"[/COLOR][COLOR=black], _
              [/COLOR][COLOR=blue]cr[/COLOR][COLOR=black],[/COLOR][COLOR=blue]lf[/COLOR][COLOR=black],[/COLOR][COLOR=red]"*****************"[/COLOR][COLOR=blue])
    [/COLOR]
[COLOR=blue]loop[/COLOR]
If I replace the ADCCONFIG 3 with PokeSFR commands (using the values that ADCON0 and ADCON1 eventually acquire, the code gives the wrong answer for the Supply Voltage (less than 1/2 what it should be). (On the other hand, if I have the PokeSFR's as well as the ADCCONFIG 3, they don't do any 'harm' - the code gives the correct answer)

In other words, you can't replace the ADCCONFIG 3 command with :-
Code:
[COLOR=blue]POKESFR ADCON0[/COLOR][COLOR=black],[/COLOR][COLOR=navy]%01111000   [/COLOR][COLOR=green]
[/COLOR][COLOR=blue]POKESFR ADCON1[/COLOR][COLOR=black],[/COLOR][COLOR=navy]%10100011[/COLOR]
even though that is what it seems to eventually do itself...

I clearly don't understand the inner workings of ADCCONFIG. Can anyone shed any light?
 
Last edited:

AllyCat

Senior Member
Hi,

This might not be the most apprpriate thread to discuss the M2s because it appears that the X2 and M2 behave quite differently.

It's rather late to consider this in detail tonight, but maybe I will try tomorrow, when I can have a real PICaxe connected to my PC. I am rather surprised if the SFRs are not being updated by ADCCONFIG, but what did become apparent in another thread is that READADC does do more than just the apparent (minimal) SFR commands (which I documented somewhere in another of my threads). In particular it disconnects the digital input of the appropriate pin (which is not absolutely essential) and of course the 14M2 port pin names are remapped relative to the "base" PIC. But I don't think those should affect your observations.

Cheers, Alan.
 

Technical

Technical Support
Staff member
The PICAXE firmware makes extensive use of shadow registers, an internal memory location that contains a copy of the value for when it is later required (e.g. remembering which pins are set as input or outputs or adcs). Therefore if you pokesfr a particular hardware register, it may be overwritten again later (e.g. during a readadc command) via the internal shadow value instead. So the genuine PICAXE command may also update the shadow register, and this doesn't occur when you directly pokesfr the direct register instead.
 
Top