Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Auto switching between ADC channel in DE0-Nano

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

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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