Thursday, May 19, 2011

Using an MCP3002 ADC for Interfacing an FPGA with a Photocell

The MCP3002 ADC Chip is a very handy device. You can interface with it via a very simple SPI (Serial Peripheral Interface) protocol. The Verilog module that I designed to interface with this chip works beautifully.

The module I created uses both channels of the MCP3002 in an "interlaced" single-ended mode. The module is strictly configured to work with a local oscillator of 24MHz, but minor adjustments to the process that converts the local clock to a 1.2MHz clock is all that needs to be modified. The 1.2MHz clock is the maximum frequency that the IC can operate at while powered at 2.7V as specified in the datasheet (pg3) under the "Timing Parameters". In my case my FPGA uses 3.3V logic so Fclk(max) should reside somewhere between this and 3.2MHz. If we assume a linear relationship between voltage and operating frequency, then the maximum expected operating frequency at 3.3V would be ~1.688MHz, thus operating at 1.2MHz "should" be a safe level of operation while pushing the IC to work at its maximum.

As far as the code goes, it is really self explanatory. I would recommend anyone that is attempting to use this code to have a copy of the datasheet on hand so that you can see the relationship from my code and the datasheet's timing diagram. Figure 5-1 was specifically used to design this Verilog Module.

On a hardware interfacing note, be sure to pay attention to Figure 4-2 in the datasheet, this clearly states that the ADC's CH0 and CH1 input signals NEED to be buffered (i.e. use an opamp in a buffer configuration or similar). If you skip this, your maximum operating frequency will be lower that the one defined in the datasheet.

The code that I provide here is free to use however you would like, but I would appreciate it if you give me credit for my work. Also constructive criticism is welcome, if you see something that could be done better another way, let me know.

Download: MCP3002 ADC Module


  1. Very cool, thanks. If you can get around to posting more information, I'd be interested in checking it out.

    I came across your page while searching for "mcp3002 projects". I'm brand-new to SPI and the MCP3002, and would like to figure out how to use it to digitize output from a Sharp infrared sensor.

    1. Hi byff,
      Thank you for the feedback. I have updated the post to give some more details on the Verilog Module and a link to the code itself. Enjoy.

  2. hey, just a quick did you set up the ADC, i see that in the data sheet pin 4, Vss, says you can put -.6v-.6v and a professor of mine is saying to put half of Vref, pin 7. either way i can not get it to work. also, did you connect your voltage directly into vref? or did you use some sort of low pass filter?. and what kind of buffer did you use for your analog input into Ch1, Ch0?

    1. Its been a while since I set this chip up but I believe I had:
      Vdd=3.3V (from a regulated power source on my FPGA board)
      CLK was a 3.3V clock source (which as I state in the blog was 1.2MHz)
      DIN used 3.3V for HI and 0V for LO

      I don't know what your professor is alluding to, but you can drive a 3.3V clock signal into Pin7 when using a Vdd=3.3. My only guess is that he is concerned with noise.

      I believe I used an LM358 dual opamp IC to act as my buffer for both channels

      What clock source and logic levels are you working with?

    2. i am using the altera DE1 board. i am using the 5v VCC. and i am trying to run it with 1.25MHz clock speed. the DE1 has a 50MHz clock so i am dividing it down to 1.25MHz. i was trying to program this using C code through NIOS, however i can't interface with the hardware the way you can with VHDL or Verilog. so i have moved over to trying it in VHDL.