MAX1247 4-Channel, 12-Bit ADC


Closed Thread
Results 1 to 15 of 15

Hybrid View

  1. #1
    Join Date
    Aug 2005
    Posts
    57


    Did you find this post helpful? Yes | No

    Default

    Attached is code used with a 16F877 and Max 1270 a/d,similar I believe.
    Attached Files Attached Files

  2. #2
    Join Date
    Sep 2006
    Location
    Florida, USA
    Posts
    94


    Did you find this post helpful? Yes | No

    Default

    Arniepj - Thanks for the code! I will give it a try (with some modifications, of course). I will let you know how it goes...

    Thanks!

  3. #3
    Join Date
    Sep 2006
    Location
    Florida, USA
    Posts
    94


    Did you find this post helpful? Yes | No

    Talking IT WORKS!!! (almost)

    Arniepj - Tried your code and am now actually able to get a reading!!! It is off by about 200 mV but it might be because I am using a 4.096 Vref reference (were you using one?). I will play with this a little more to tweek it so that it is accurate and post the final code. What I have now that works is posted below. The other thing that I changed based on your code was going from an external to internal clock on the Control Byte for the chip.

    Thanks a million!!!

    (and thanks to you too, Steve!)


    ' Set compiler to use HS (20 mHz)
    @ DEVICE HS_OSC
    DEFINE OSC 20 'resonator frequency at 20 Mhz
    ADCON1 = 7 ' Disable PORTA Analog

    ' Define the LCD Hookup parameters
    ' data pins D4-D7 are hooked to pins C.0-C.3, respectively
    define LCD_DREG PORTC 'Data Port = PORTC
    define LCD_DBIT 0 'Data starting bit = 0
    define LCD_RSREG PORTC 'Register Select Port = PORTC
    define LCD_RSBIT 4 'RS bit = PortC.4
    define LCD_EREG PORTC 'Enable Port = PORTC
    Define LCD_EBIT 5 'Enable Bit = PortC.5
    define LCD_BITS 4 'LCD Bus Size = 4
    define LCD_LINES 2 'Number of lines on LCD

    Pause 1000 ' Wait for LCD to startup
    Lcdout $fe, $80, "MAX1247"
    lcdout $fe, $C0, "Example"
    pause 1000
    Lcdout $FE, 1 ' Clear LCD screen

    'Variables for ADC
    CB var byte
    CB0 var Byte
    CB1 var Byte
    CB2 var Byte
    CB3 var Byte

    'Control Byte Setup:
    ' Bit 7: Start Bit = 1
    ' Bit 6: Channel Select Bit 2 (SEL2) -See Channel Selection Below
    ' Bit 5: SEL1
    ' Bit 4: SEL0
    ' Bit 3: UNI/BIP - 1=Unipolar 0=Bipolar
    ' Bit 2: SNGL/DIF - 1=Single Ended 0=Differential
    ' Bit 1: PD1 - Sets clock and power down mode
    ' Bit 0: PD0 - Sets clock and power down mode
    ' 00 - full power down
    ' 01 - fast power down
    ' 10 - internal clock mode
    ' 11 - external clock mode

    'Channel Selection:
    ' SEL2 SEL1 SEL0
    'CH0 0 0 1
    'CH1 1 0 1
    'CH2 0 1 0
    'CH3 1 1 0

    ' To read channel 0 in Unipolar, single ended, internal clock mode,
    ' Control Byte (CB) = 10011110
    CB0 = %10011110 'To read Channel 0
    CB1 = %11011110 'To read Channel 1
    CB2 = %10101110 'To read Channel 2
    CB3 = %11101110 'To read Channel 3

    ' Set up MAX1247 4-channel 12-bit ADC
    CLKpin var PORTA.0 'SPI clock pin
    CSpin var PORTA.1 'DAC chip select
    DINpin var PORTA.2 'Data in pin
    DOUTpin var PORTA.3 'Data Out Pin

    'set up Max1247 pins
    TRISA.0 = 0 'CLKpin as output
    TRISA.1 = 0 'CSpin as output
    TRISA.2 = 0 'DIpin as output
    TRISA.3 = 1 'DOpin as input

    ' ******** Declarations *******************************
    Voltage1 var word
    Voltage2 var word
    Voltage3 var word
    Voltage4 var word
    SerialDataOut var byte ' Serial data out to Max1247 A/D
    SerialDataIn var word ' Serial data in from Max1247 A/D
    Indexer var byte ' Loop indexer for data in

    ' ********* Presets ****************************
    SerialDataOut = cb0
    SerialDataIn = 0
    clkpin = 0 ' Clock signal
    cspin = 0 ' Chip select: low selects
    dinpin = 0 ' Serial data out
    doutpin = 0 ' Serial data in

    '******Main Program ********************************
    DataOut:
    gosub DataAcquisition 'Read data from Max1247
    Voltage1 = SerialDataIn * 2 ' Convert data to voltage
    Voltage2 = (SerialDataIn * 4)/10 ' Convert data to voltage
    Voltage3 = (SerialDataIn * 4)/100 ' Convert data to voltage
    Voltage4 = Voltage1 + Voltage2 + Voltage3 + 9 ' Convert data to voltage
    lcdout $FE, $80, #Voltage4, " " ' Display data
    SerialDataIn = 0
    goto Dataout

    '************ Data Acquisition ***************************
    DataAcquisition:
    for Indexer = 7 to 0 step -1 ' Output data,8 clock pulses
    dinpin = SerialDataOut.0[Indexer] ' Output data port
    pulsout clkpin,5 ' Output clock pulse
    next Indexer ' Next data bit,next clock pulse

    for Indexer = 1 to 12 ' Read data,12 clock pulses
    SerialDataIn = SerialDataIn * 2 ' Shift each bit to the left
    SerialDataIn = SerialDataIn + doutpin ' Data in port
    pulsout clkpin,5 ' Output clock pulse
    next Indexer ' Next data bit,next clock pulse

    return

    end

  4. #4
    Join Date
    Sep 2006
    Location
    Florida, USA
    Posts
    94


    Did you find this post helpful? Yes | No

    Talking Final Version

    Hello All - Here is the final version of the software. Note that I am using a 2.5V Vref with the MAX1247, so you will have to change the voltage calculation if you are using a different Vref or none at all.

    Enjoy!

    ' Set compiler to use HS (20 mHz)
    @ DEVICE HS_OSC
    DEFINE OSC 20 'resonator frequency at 20 Mhz
    ADCON1 = 7 ' Disable PORTA Analog

    ' Define the LCD Hookup parameters
    ' data pins D4-D7 are hooked to pins C.0-C.3, respectively
    define LCD_DREG PORTC 'Data Port = PORTC
    define LCD_DBIT 0 'Data starting bit = 0
    define LCD_RSREG PORTC 'Register Select Port = PORTC
    define LCD_RSBIT 4 'RS bit = PortC.4
    define LCD_EREG PORTC 'Enable Port = PORTC
    Define LCD_EBIT 5 'Enable Bit = PortC.5
    define LCD_BITS 4 'LCD Bus Size = 4
    define LCD_LINES 2 'Number of lines on LCD

    Pause 1000 ' Wait for LCD to startup
    Lcdout $fe, $80, "MAX1247"
    lcdout $fe, $C0, "Example"
    pause 1000
    Lcdout $FE, 1 ' Clear LCD screen

    'Variables for ADC
    CB var byte
    CB0 var Byte
    CB1 var Byte
    CB2 var Byte
    CB3 var Byte

    'Control Byte Setup:
    ' Bit 7: Start Bit = 1
    ' Bit 6: Channel Select Bit 2 (SEL2) -See Channel Selection Below
    ' Bit 5: SEL1
    ' Bit 4: SEL0
    ' Bit 3: UNI/BIP - 1=Unipolar 0=Bipolar
    ' Bit 2: SNGL/DIF - 1=Single Ended 0=Differential
    ' Bit 1: PD1 - Sets clock and power down mode
    ' Bit 0: PD0 - Sets clock and power down mode
    ' 00 - full power down
    ' 01 - fast power down
    ' 10 - internal clock mode
    ' 11 - external clock mode

    'Channel Selection:
    ' SEL2 SEL1 SEL0
    'CH0 0 0 1
    'CH1 1 0 1
    'CH2 0 1 0
    'CH3 1 1 0

    ' To read channel 0 in Unipolar, single ended, internal clock mode,
    ' Control Byte (CB) = 10011110
    CB0 = %10011110 'To read Channel 0
    CB1 = %11011110 'To read Channel 1
    CB2 = %10101110 'To read Channel 2
    CB3 = %11101110 'To read Channel 3

    ' Set up MAX1247 4-channel 12-bit ADC
    CLKpin var PORTA.0 'SPI clock pin
    CSpin var PORTA.1 'DAC chip select
    DINpin var PORTA.2 'Data in pin
    DOUTpin var PORTA.3 'Data Out Pin

    'set up Max1247 pins
    TRISA.0 = 0 'CLKpin as output
    TRISA.1 = 0 'CSpin as output
    TRISA.2 = 0 'DIpin as output
    TRISA.3 = 1 'DOpin as input

    ' ******************************** Declarations ********************************************
    Voltage var word
    SerialDataOut var byte ' Serial data out to Max1247 A/D
    SerialDataIn var word ' Serial data in from Max1247 A/D
    Indexer var byte ' Loop indexer for data in

    ' ******************************** Presets ************************************************
    SerialDataOut = cb0
    SerialDataIn = 0
    clkpin = 0 ' Clock signal
    cspin = 0 ' Chip select: low selects
    dinpin = 0 ' Serial data out
    doutpin = 0 ' Serial data in

    '********************************* Main Program *********************************************
    DataOut:
    gosub DataAcquisition ' Read data from Max1247
    lcdout $FE, $80, #Serialdatain, " " ' Display data
    lcdout $FE, $C0, #voltage, " " ' Display calculated voltage
    goto Dataout

    '******************************** Data Acquisition ***************************
    DataAcquisition:
    SerialDataIn = 0
    for Indexer = 7 to 0 step -1 ' Output data,8 clock pulses
    dinpin = SerialDataOut.0[Indexer] ' Output data port
    pulsout clkpin,5 ' Output clock pulse
    next Indexer ' Next data bit,next clock pulse

    for Indexer = 1 to 12 ' Read data,12 clock pulses
    SerialDataIn = SerialDataIn * 2 ' Shift each bit to the left
    SerialDataIn = SerialDataIn + doutpin ' Data in port
    pulsout clkpin,5 ' Output clock pulse
    next Indexer ' Next data bit,next clock pulse

    SerialDataIn = SerialDataIn * 2 ' Shift each bit to the left

    'Using a 2.5V Reference with ADC, therefore, 2500 / 4096 = 0.6 mV per step
    'Multiply the result (SerialDataIn) by 6
    voltage = serialdatain * 6
    voltage = voltage / 10 'shift decimal point

    return

    end

  5. #5
    Join Date
    Aug 2005
    Posts
    57


    Did you find this post helpful? Yes | No

    Default

    Atom050,
    Glad to help.An alternative is to use the hardware spi,but since you had a board already,changing i/o might not be possible.

  6. #6
    Join Date
    Sep 2006
    Location
    Florida, USA
    Posts
    94


    Did you find this post helpful? Yes | No

    Default New (minor) problem...

    Hello - I'm back with a question. I was testing my design and code with a power supply that can deliver precise mV outputs in the 0.00 to 102.00 mV range. I was looking to see if my design would work all the way down to 0 mV. Well, I am getting about a 14 mV difference in my readings. In otherwords, my LCD displays 0 mV when 14 mV or below is input. All readings above that are good but off by 14 mV. If I didn't need to measure below 14 mV, I would just add 14 to the value that was being displayed by my LCD and call it good. But I need to see below 14... Anyone have an idea why that might be? And how I might correct it?

    Atom058

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I would tend to believe the problem is with the power supply.

    Or more specificaly, the measurement of the power supply's voltage.

    A simple test is to use a voltage that you don't need to "read" to know what it is. And the easiest way to do that is with a simple voltage divider.

    With 2 resistors 100k to Vdd(+5V) and 220 ohms to Vss. you will get approximately 11mv at the junction. Of course it depends on the tolerance of the resistors you use, but it will still be very close even with 5%.

    With 12 bits and 2.5Vref, that should give an A/D value of 22, and due to integer truncating should read 10 mv after the *6/10.

    So if it reads 10mv, then the problem is the difference between the actual power supply voltage and the external measuement of that voltage.
    <br>
    DT

Similar Threads

  1. MCP3208 12 bit A/D driver
    By polymer52 in forum Code Examples
    Replies: 0
    Last Post: - 5th February 2010, 11:59
  2. PICBasic newbie problem
    By ELCouz in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 12th February 2008, 00:55
  3. Flash PIC with 12 bit ADC
    By Steve_88 in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 12th October 2007, 20:35
  4. Microcontroller with 2 way paging application problem
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 20th April 2007, 17:27
  5. Real Time Clock & Eeprom
    By smart_storm in forum General
    Replies: 8
    Last Post: - 17th February 2006, 19:03

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts