Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

Auto switching between ADC channel in DE0-Nano

Altera_Forum
Honored Contributor II
2,190 Views

Hello, I'm want to create a program to collect data from 4 microphone using De0-nano board. I tried to create an auto switching program for 2 potensiometer ,using the basic ADC demo from terasic. I used counter to count for 1 second then change the channel selector, but it didn't work. Can somebody help? 

 

the part of the code was like this 

 

always @ (posedge iCLK) 

begin 

cont <= cont + 1; 

switchcount <= + 1; 

end 

 

 

always @ (posedge iCLK_n) 

begin 

iCH <= 0; 

if (cont == 2) 

data <= iCH[2]; 

else if (cont == 3) 

data <= iCH[1]; 

else if (cont == 4) 

data <= iCH[0]; 

else 

data <= 0; 

if (switchcount == 50000000) 

iCH <= iCH + 1; 

end
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
1,088 Views

I don't have the adc demo code here, so I can't fully understand the exact purpose and usage of data and iCH. 

The problem is definitely with the iCH <= 0 assignment in the very beginning of second always block: this will be executed at each clock pulse and will keep iCH in the zero state.  

Anyway I think your code is somehow wrong; cont never resets and it would keep on growing, so the cont=x conditions would be hit only once and then data will be always 0.
0 Kudos
Altera_Forum
Honored Contributor II
1,088 Views

Sorry, forgot to mention that the cont is only 4 bit long, so it will resets after 16 cycles. the iCH is the 3-bit data for mux input (because the ADC is 8-channel, so it is like the channel selector). Anyway, the problem already solved. I think you're right too, the iCH is the problem. I made another file in the project specific for switching channels and it works. Thank you Cris72

0 Kudos
Altera_Forum
Honored Contributor II
1,088 Views

if i want to read just 2 input how about switch count that i use ? 

i want to read 2 sensor LDR(light dependent resistor)
0 Kudos
Altera_Forum
Honored Contributor II
1,088 Views

Would it be possible to post your solution. I am having the same problem.

0 Kudos
Altera_Forum
Honored Contributor II
1,088 Views

Would you kindly post your solution? I'm having the same problem.

0 Kudos
Altera_Forum
Honored Contributor II
1,088 Views

I thought I had a solution and this code seems to work but the channel 1 bleeds into channel 2 if channel 2 is set to 3.3 V. I can't figure out if it is a wire /antenna problem or code problem. This is especially prevalent when switchcounter is very small. I'd like switch counter to be 0 so I can sample fast, but I can't tell if it is working or not.  

 

Note for this to work I have to change the if (cont == 1) to 1 from 2. it appeared that the ADC chip was off by 1 bit if using all channels. possibly I have other problems.  

 

module ADC_CTRL2 (  

 

iCLK, 

iCLK_n, 

oCH0, 

oCH1, 

oCH2, 

oCH3, 

oCH4, 

 

oDIN, 

oCS_n, 

oSCLK, 

oCH, 

iDOUT 

); 

 

 

input iCLK; 

input iCLK_n; 

 

output [11:0] oCH0; 

output [11:0] oCH1; 

output [11:0] oCH2; 

output [11:0] oCH3; 

output [11:0] oCH4; 

output [1:0] oCH; 

 

output oDIN; 

output oCS_n; 

output oSCLK; 

input iDOUT; 

 

reg data =0; // serial address data out  

reg go_en=1; // always enabled after power up 

reg [1:0] ch_sel = 2'b00; // Start at channel 0  

reg [1:0] chOUT = 2'b00; // Register to store channnel output 

reg sclk; 

reg [3:0] cont; 

reg [3:0] m_cont; 

reg [11:0] adc_data; 

reg [11:0] ch0; 

reg [11:0] ch1; 

reg [11:0] ch2; 

reg [11:0] ch3; 

reg [11:0] ch4; 

reg [8:0] switchcount; // Slow enough to see at 21 bits. ~ 1 change per sec at 15 very fast 

 

 

assign oCS_n = ~go_en; 

assign oSCLK = (go_en)? iCLK:1'b1; 

assign oDIN = data; 

 

assign oCH0 = ch0; 

assign oCH1 = ch1; 

assign oCH2 = ch2; 

assign oCH3 = ch3; 

assign oCH4 = ch4; 

assign oCH = chOUT; 

 

 

always@(posedge iCLK ) 

// always running 

begin 

cont <= cont + 4'b001; 

end 

 

always@(posedge iCLK_n) 

begin 

if(iCLK_n) 

 

begin // on some clock check to see if timer expired 

m_cont <= cont; 

switchcount <= switchcount + 1; 

if (switchcount == 0) //if last bit is set the increment to next sample addresss 

begin 

ch_sel <= ch_sel + 1; // increment the address  

end 

end 

end 

 

always@(posedge iCLK_n ) 

// always running 

 

begin 

 

if(iCLK_n) 

begin 

if (cont == 1) //MSB add in MSB if using all 8 ADC inputs  

data <= 0; 

else if (cont == 2) // Middle Bit 

data <= ch_sel[1]; 

else if (cont == 3) // LSB 

data <= ch_sel[0]; 

else data <= 0; // if not sending out address send out 0 to DOUT 

end 

 

end 

 

always@(posedge iCLK) 

begin 

 

begin 

if(iCLK) 

begin 

if (m_cont == 4) 

adc_data[11] <= iDOUT; 

else if (m_cont == 5) 

adc_data[10] <= iDOUT; 

else if (m_cont == 6) 

adc_data[9] <= iDOUT; 

else if (m_cont == 7) 

adc_data[8] <= iDOUT; 

else if (m_cont == 8) 

adc_data[7] <= iDOUT; 

else if (m_cont == 9) 

adc_data[6] <= iDOUT; 

else if (m_cont == 10) 

adc_data[5] <= iDOUT; 

else if (m_cont == 11) 

adc_data[4] <= iDOUT; 

else if (m_cont == 12) 

adc_data[3] <= iDOUT; 

else if (m_cont == 13) 

adc_data[2] <= iDOUT; 

else if (m_cont == 14) 

adc_data[1] <= iDOUT; 

else if (m_cont == 15) 

adc_data[0] <= iDOUT; 

else if (m_cont == 1) // on first clock store data to output port 

begin  

ch4 <= adc_data; 

case (ch_sel) // Select last channel data store to corresponding output port 

3'b00 : ch0 <= adc_data;  

3'b01 : ch1 <= adc_data; 

3'b10 : ch2 <= adc_data; 

3'b11 : ch3 <= adc_data; 

default : ch4 <= adc_data; 

endcase 

chOUT <= ch_sel; 

end 

end 

end 

end 

 

endmodule
0 Kudos
Reply