Created
May 3, 2012 23:20
-
-
Save jjcarrier/2590356 to your computer and use it in GitHub Desktop.
MCP3002 ADC Module (Interlaced)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
////////////////////////////////////////////////////////////////////////////////// | |
// Engineer: Jon Carrier | |
// | |
// Create Date: 13:47:10 12/03/2009 | |
// Design Name: MCP3002 ADC SPI | |
// Module Name: adc | |
// Project Name: MCP3002 ADC SPI | |
// Target Devices: MCP3002, Spartan3E | |
// Tool versions: ISE 11 | |
// Description: SPI for MCP3002 ADC | |
// | |
// Dependencies: None | |
// | |
// Revision: | |
// Revision 0.01 - File Created | |
// Additional Comments: You will need to modify this code if you are not using a 24MHz clock source | |
// Only the first section should need to be changed (where cnt20 is generated) | |
// | |
// This code uses the ADC in an alternating channel mode. | |
// This means the sample rate is ~26us per alternating sample | |
// since a sample takes 16 clocks (technically 15) which means | |
// (16 clocks)/(1.2MHz) ~= 13us | |
////////////////////////////////////////////////////////////////////////////////// | |
module adc(clk, cs, clk_1_20, dout, din); | |
input clk; //p181 | |
output cs; //p22 | |
output clk_1_20; //p24 | |
input dout; //p26 | |
output din; //p28 | |
wire clk; | |
wire dout; | |
reg clk_1_20; | |
reg din; | |
reg cs; | |
//---------------------------------------------------- | |
//First generate the 1.2MHz clock from the 24MHz clock | |
//To do this we must create a counter that counts to 20 | |
reg [4:0] cnt20; //This will create 32 values but we only want 20 | |
reg [4:0] cnt20_next; | |
//Lets create the top level state update to cnt20 | |
always @(posedge clk) cnt20<=cnt20_next; | |
//Lets create a simple process to limit this range | |
always @(posedge clk) | |
begin | |
if (cnt20==20) | |
begin | |
cnt20_next<=0; //Reset to zero | |
clk_1_20<=~clk_1_20; //Flip the state of clk_1_20 | |
end | |
else | |
begin | |
cnt20_next<=cnt20_next+1; //Continue with increment | |
clk_1_20<=clk_1_20; //Maintain the state of clk_1_20 | |
end | |
end | |
//---------------------------------------------------- | |
//In this code we will be using both the positive and negative edge | |
//of the clk_1_20 signal. The order that these processes execute are important | |
//because of this we need to ensure that the negative edge processes start | |
//before the postive edge processes. To do this we must create a latch signal. | |
reg init_latch; | |
always @(posedge clk_1_20) init_latch<=1; | |
//---------------------------------------------------- | |
//Now that we have the 1.2MHz clock, we can generate | |
//another counter that counts to 16 at 1.2MHz | |
reg [3:0] cnt16; | |
always @(posedge clk_1_20) if (init_latch==1) cnt16<=cnt16+1; | |
//---------------------------------------------------- | |
//Lets also create a channel selection bit | |
//This bit will flip after each sample has been acquired | |
reg channel; | |
always @(negedge clk_1_20) if (init_latch==1) if (cnt16==15) channel<=~channel; else channel<=channel; | |
//---------------------------------------------------- | |
//With the newly created counter, cnt16, | |
//we can now create the 16 step SPI | |
//The input signals to the SPI should operate on the negative edge | |
//This is because the SPI on the ADC samples on the positive edge | |
//We want to maximize the settling time of the signal as to avoid | |
//communication errors | |
always @(negedge clk_1_20) | |
begin | |
if (init_latch==1) | |
begin | |
case (cnt16) | |
0://Bring cs high to initialize | |
begin | |
cs<=1; | |
din<=0; | |
end | |
1://START BIT :: Bring cs low and din high to initiate communication | |
begin | |
cs<=0; | |
din<=1; | |
end | |
2://MODE BIT :: Bring din high to set the mode to single-ended | |
begin | |
cs<=0; | |
din<=1; | |
end | |
3://CHANNEL BIT :: Bring din low to select channel 0 | |
begin | |
cs<=0; | |
din<=0; //channel; | |
end | |
4://MSBF BIT :: Bring din high to set the output in MSB First format | |
begin | |
cs<=0; | |
din<=1; | |
end | |
5://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
6://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
7://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
8://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
9://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
10://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
11://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
12://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
13://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
14://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
15://Maintain cs low for the remainder of the 16 clocks | |
begin | |
cs<=0; | |
din<=0; | |
end | |
endcase | |
end | |
end | |
//---------------------------------------------------- | |
//Now that the input into the ADC's SPI has been created | |
//we can now grab the output | |
//First create the sample signal which will act as a 10-bit FIFO | |
reg [9:0] sample; | |
//---------------------------------------------------- | |
//Now with the sample signal created, start sampling dout | |
//The output is only valid on clock 6-15 | |
//This data should be grabbed on the positive edge so that | |
//the ADC's output has time to settle | |
// | |
always @(posedge clk_1_20) | |
begin | |
if (init_latch==1) | |
begin | |
if (cnt16>=6) | |
begin | |
sample[9:1]<=sample[8:0]; | |
sample[0]<=dout; | |
end | |
else sample<=sample; | |
end | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment