Has anyone seen this behaviour before? I've got trim pots hooked up to a PIC18F2455, and my code simply reads ADRESH and ADRESL, converts to decimal and displays the result.
What happens is that the readings seem to span ranges, rather than putting out values from 0 to 1023 as I expected. For instance, as I turn the pot, the reading starts out at 0, then reads 011 for a bit, then 111, 139,
239, 267, 367, etc. It's always the same numbers, running up the sequence or down.
Well, that should use Vdd for the full scale reference and Vss for the zero scale reference.
Take me through the rest of the bits in ADCON0, 1 and 2. How many inputs are you scanning? How long do you let each settle before converting? What is the resistance of the pots?
Some things to check: Which way the result is justified (left or right) Your binary to decimal conversion routine Bypass caps on pots from center terminal to ground
Which reminds me: can someone explain what left justify gets used for?
BINTODEC ; derive decimal digits from TEMP vars CLRF HUNDRED_S CLRF TEN_S CLRF ONE_S
BTFSC TEMPHI, 1 ; if bit 1 of TEMPHI is one, add 256 to decimal CALL DEC256 BTFSC TEMPHI, 0 ; if bit 0 of TEMPHI is one, add 128 to decimal CALL DEC128
BSF ADCON2,7 ; right justify BSF ADCON2,4 ; set Tad = 32 BSF ADCON2,2 ; Fosc/4
movlw 0x03 movwf ADCON1 ; set inputs AN0-AN10, vrefs internal
Currently 5; more later. I just thought of something: would leaving the unused inputs floating cause this?
ADCREAD MOVWF ADCON0 ; set A/D to channel defined in WREG BSF ADCON0,0 ; start conversion CALL ONE_US CALL ONE_US CALL ONE_US ; wait 7us for A/D to settle CALL ONE_US CALL ONE_US CALL ONE_US CALL ONE_US BSF ADCON0,1 ; set the GO bit btfsc ADCON0,1 ; GO bit will change to zero when the conversion is complete goto $-2 MOVFF ADRESH, TEMPHI MOVFF ADRESL, TEMPLO
That could be part of the problem. The pot should be equal to or less that the input impedance of the ADC and I think on most PICs that is 25K. The next thing is the MCU should have good power decoupling caps to keep Vref as stable as possible.
So Tad is 4 cycles of Fosc and Taq is 4*4/Fosc, or 16 cycles of Fosc.
What is Fosc?
So, 12 inputs set as analog.
Not normally a problem. Driving current in or out of any input (beyond the supply rails) *will* affect the accuracy of the A/D conversions.
I see ADCON and ADRESH/L are bank one registers. Where do you select that bank?
Shouldn't that comment say 'power up A/D converter'?
Where on the data sheet do you find the time required for the A/D to settle after being enabled? I see the input settling time stuff (ADCON2,3 to 5), but nothing about enable (ADCON0,0) settling requirements.
These should work, though the 100k pots in the middle area (about 25k source impedance) will settle a bit slowly. But the error should be fairly fixed, not the walking steps you are seeing.
There's a small cap, but power supply fluctuations would cause fluctuations in a steady reading, would it not? If anything, I'm not getting *enough* fluctuation! :)
That's one of the parts of this process that still confuses me, but I *think* it's 24 or
48 MHz:
config CPUDIV = OSC1_PLL2 config PLLDIV = 12
Actually 11. I needed one pin for digital.
I can imagine it would. ;-)
I don't need to, do I? IIRC, pic18 devices don't use banks.
The datasheet overview says 'start conversion', so I used that.
I used page 258, equation 21-3 as the example; the worst-case time was 6.4us, and I already had a ONE_US function, so I rounded to 7. If I can just get it to work, I'll shave it down later. ;-)
I'm also confused. You will have to help me through your=20 clock set up (including crystal frequency, if any) for me to=20 understand.
I haven't programmed the PIC18F series, yet, so I may be=20 completely off base, here.
(excerpt from data sheet, section 5.3.2, Bank Select=20 Register (BSR))
The data memory in PIC18 devices is implemented as static RAM. Each register in the data memory has a
12-bit address, allowing up to 4096 bytes of data Large areas of data memory require an efficient addressing scheme to make rapid access to any address possible. Ideally, this means that an entire address does not need to be provided for each read or write operation. For PIC18 devices, this is accomplished with a RAM banking scheme. This divides the memory space into 16 contiguous banks of 256 bytes. Depending on the instruction, each location can be addressed directly by its full 12-bit address, or an 8-bit low-order address and a 4-bit Bank Pointer.
Most instructions in the PIC18 instruction set make use of the Bank Pointer, known as the Bank Select Register (BSR). This SFR holds the 4 Most Significant bits of a location=92s address; the instruction itself includes the eight Least Significant bits. Only the four lower bits of the BSR are implemented (BSR3:BSR0). The upper four bits are unused; they will always read =910=92 and cannot be written to. The BSR can be loaded directly by using the MOVLB instruction. The value of the BSR indicates the bank in data memory. The eight bits in the instruction show the location in the bank and can be thought of as an offset from the bank=92s lower boundary. The relationship between the BSR=92s value and the bank division in data memory is shown in Figure 5-6. Since up to sixteen registers may share the same low-order address, the user must always be careful to ensure that the proper bank is selected before performing a data read or write. For example, writing what should be program data to an 8-bit address of F9h, while the BSR is 0Fh, will end up resetting the program counter.
While any bank can be selected, only those banks that are actually implemented can be read or written to. Writes to unimplemented banks are ignored, while reads from unimplemented banks will return =910=92s. Even so, the STATUS register will still be affected as if the operation was successful. The data memory map in Figure 5-5 indicates which banks are implemented.
In the core PIC18 instruction set, only the MOVFF instruction fully specifies the 12-bit address of the source and target registers. This instruction ignores the BSR completely when it executes. All other instructions include only the low-order address as an operand and must use either the BSR or the Access Bank to locate their target registers. (end excerpt)
I think bank select bits are still in use.
I think that is the description of the Go bit.
That calculation refers to the acquisition time, that is=20 controlled automatically by setting ADCON2, bits 3 to 5 (in=20 conjunction with the Fosc setup). The PIC 16F series=20 required you to time out the acquisition time, but this one=20 appears to do that as part of the A/D conversion cycle,=20 automatically. But you adding this delay shouldn't be=20 involved in your problem. It is just wasted code and time.
I would be very suspicious of your conversion routine. I seem to get (mostly) 1011 and 1111 in the least significant 4 bits for all those values. I am also suspicious of seeing jumps of exactly 100 - that would opit at a logic error in the conversion.
Can you print out the sequence (you say it always repeats) in binary (no conversion, just print out High/Low
I just pointed out 2 quick things that I see often as problems with stability/accuracy in using on board ADCs and PIC MCUs. Truthfully, I didn't pick through the enitire post. I just noticed the pot values and thought I would throw that out there.
Since your decimal conversion would produce some weird results, for example an input of 218 would convert to '1;8', I'm assuming that you are not printing what you think you're printing.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.