PDA

View Full Version : MCP3301 A/D converter SPI reading



flotulopex
- 1st February 2024, 21:15
Hi there,

I'm trying to read a 13 bits MCP3301 A/D converter who's output value should go from 0 to 8191.

Unfortunately, even if I can read something, it looks to be only the "upper half" of the expected full value.

9580




Could I have a hardware (wiring) issue or is there something in my code that would be wrong?


' ====== DESCRIPTION ================================================== =============================
' MCP3301: SPI 13Bits ADC

' ====== FUSES ================================================== ===================================
' PIC 16F690 Fuses - Internal oscillator (activate OSCCON register)

'@ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

#CONFIG
__config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF
#ENDCONFIG

@ ERRORLEVEL -306
@ ERRORLEVEL -202

' ====== REGISTERS ================================================== ===============================
' 76543210
OPTION_REG = %10000000 'PORT A&B Pull-Ups disabled (see WPUA & WPUB)
OSCCON = %01100000 'Internal RC set to 4MHZ
ANSEL = %00010100 'Select analog inputs Channels 0 to 7 (AN2 + AN4 selected)
ANSELH = %00000000 'Select analog inputs Channels 8 to 11
ADCON0 = %10000000 'A/D Module (Bit5:2 select channels 0:11)
ADCON1 = %00000000 'A/D control register
CM1CON0 = %00000000 'Comparator1 Module is OFF
CM2CON0 = %00000000 'Comparator2 Module is OFF
INTCON = %00000000 'INTerrupts CONtrol (TMR0 OFF)
TRISA = %00000100 'Set Input/Output (0 to 5)
PORTA = %00000000 'Ports High/Low (0 to 5)
TRISB = %00000000 'Set Input/Output (4 to 7)
PORTB = %00000000 'Ports High/Low (4 to 7)
TRISC = %00000001 'Set Input/Output (0 to 7)
PORTC = %00000000 'Ports High/Low (0 to 7)

' ====== DEFINES ================================================== =================================
DEFINE OSC 4
DEFINE NO_CLRWDT 1 'Don't waste cycles clearing WDT
DEFINE HSER_CLOERR 1 'Automatic clear overrun error
DEFINE SHIFT_PAUSEUS 100

' ====== VARIABLES ================================================== ===============================
SD var PORTB.4 'SPI Data pin
CS var PORTB.5 'SPI Chip Select
SCK var PORTB.6 'SPI Clock pin
Serial_Out VAR PORTB.7
Mode Var WORD
MCP3301 Var WORD

' ====== INITIALIZE VARIABLES ================================================== ====================
CS = 1
Mode = 84 'serial com
MCP3301 = 0

' ====== PROGRAM ================================================== =================================
MAIN:

CS = 0 'initiate 3301 comm
SHIFTIN SD,SCK,1,[MCP3301\13] 'shift 13 bits of data in, lowest bit first
CS = 1 'stop 3301 comm

Serout2 Serial_Out,Mode,["MCP3301: ", BIN13 MCP3301," - ", DEC4 MCP3301,13,10]

PAUSE 1000

GOTO MAIN
END

richard
- 1st February 2024, 21:42
according to the data sheet the data read is 12 data bits + sign bit

flotulopex
- 1st February 2024, 21:45
Really?

9582

I don't get it :frown:

richard
- 1st February 2024, 23:29
i'm looking at the data sheet you posted, that's what i see

9583

9584

tumbleweed
- 1st February 2024, 23:29
Keep reading. It's a 13-bit differential converter.

From the datasheet section 5.1:

and the device uses the collected charge to produce a serial 13-bit binary two’s complement output code.

So that's 12 bits of data + sign. See Section 6.1.

flotulopex
- 2nd February 2024, 07:20
Okay then, didn't see that one 😵

So I'll get a 12 bits "value" and the last bit will indicate either "+" or "-", right?

richard
- 2nd February 2024, 08:44
the last bit will indicate either "+" or "-", right?

if by last bit you mean the msb then yes
not forgetting its a 13-bit binary two’s complement number

flotulopex
- 3rd February 2024, 15:28
not forgetting its a 13-bit binary two’s complement number

...and that means what exactly please? :confused:

Ioannis
- 3rd February 2024, 17:12
Your ADC is differential one. So, that means it can convert positive and also negative (in relation to the two inputs + and -) voltages.

If the + input is more positive than the - input of the converter then the output will be a plain 12 bit binary number.

But if the - input is more positive than the + input, then as you can understand the result of the ADC should be negative. This is shown in binary with the most significant bit (MSB) of the value being 1. That is the sign bit.

But the rest of the 12 bits follow a specific rule then. All bits are reversed and also -1.

For example, 1 1111 1111 1111 means negative number and this number is the reverse of 1111 1111 1111 plus one, or just 1. So in total -1.

Or, 1 0000 1111 0000 is also negative and the value is -3856

Hope this clear a bit of the mud!

Ioannis

More here https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html

flotulopex
- 8th February 2024, 19:47
Thanks Ioannis and sorry for the late reply,

So, if I would connect GND to the "-" input and measure i.e. a + signal from 0 to 5 Volts, I should have as 12 bits result, right?




Or, 1 0000 1111 0000 is also negative and the value is -3856
This is confusing to me. I get the positive and negative thing but I can't figure out how you come to this 3856 number?

9594

richard
- 8th February 2024, 20:36
to expand a 13 bit negative two's complement number to a 16 bit number bits 13,14 an 15 need to be set accordingly
in general the "sign bit" needs to be extended to the new width
so 1 0000 1111 0000 becomes 1111 0000 1111 0000 qed -3856
9595

Ioannis
- 9th February 2024, 11:06
Yes, Richard is correct. I forgot to mention you have to adjust the value to the byte, word or whatever width you have.

So the sign is the left most bit but the rest should also be 1. Remember we reverse the bits to get the absolute value disregarding the left most, sign bit.

Seems confusing at first, but has its logic.

Ioannis

flotulopex
- 9th February 2024, 19:22
Got it now!

Thanks a lot :wink:

tumbleweed
- 10th February 2024, 00:06
Remember we reverse the bits to get the absolute value disregarding the left most, sign bit
To convert a 2's compliment negative value to a positive number, invert all the bits (NOT) and add 1.

For example 2's compliment -1 = FFFF
invert = 0000, add 1 = 0001

Ioannis
- 10th February 2024, 12:07
I was reffering to the left most bits but yes. Absolutely correct, to convert a positive to negative after reversing all bits you add one.

Ioannis