本帖最后由 jlgcumt 于 2013-3-12 23:56 编辑
- //////////////////////////////////FSM///////////////////////////////////////
- // 状态转换
- always @ (posedge sys_clk or negedge rst_n)
- begin
- if(!rst_n)
- cstate_ad <= 0;
- else
- cstate_ad <= nstate_ad;
- end
- // 下一状态生成
- always @ (*)
- begin
- if(!rst_n)
- begin
- nstate_ad = 0;
- end
- else
- begin
- case(cstate_ad)
- 4'd0: // 判断当前ad是否使能,使能的话进入下一状态开始启动采集
- begin
- if(ADEn)
- nstate_ad = 4'd1;
- else
- nstate_ad = 4'd0;
- end
- 4'd1: // 此状态和下一状态用于AD7606采集的转换启动信号
- begin
- nstate_ad = 4'd2;
- end
- 4'd2:
- begin
- nstate_ad = 4'd3;
- end
- 4'd3: // 等待125ns,在启动信号和Busy信号有效之间延时最大为40ns(手册要求)
- begin
- nstate_ad = 4'd4;
- end
- 4'd4:
- begin
- nstate_ad = 4'd5;
- end
- 4'd5:
- if(ad_busy) // 转换正在进行中
- begin
- nstate_ad = 4'd5;
- end
- else // 转换完成
- begin
- nstate_ad = 4'd6;
- end
- 4'd6: // 开始采集
- begin
- if(ADSampNum < 4 ) // 当前8个通道采集值都已经读出来,进行下一次的采集
- begin
- nstate_ad = 4'd7;
- end
- else // 当前正在读取采集结果
- begin
- nstate_ad = 4'd0;
- end
- end
- 4'd7: // 启动SPI读取时钟
- begin
- nstate_ad = 4'd8;
- end
- 4'd8:
- begin
- nstate_ad = 4'd9;
- end
- 4'd9: // 多延时一次确保延时计数器已经开始工作
- begin
- nstate_ad = 4'd10;
- end
- 4'd10:
- begin
- if(ADDelay_Cnt > 10) // 延时时间到
- begin
- nstate_ad = 4'd11;
- end
- else // 延时时间还没到,等待中
- begin
- nstate_ad = 4'd10;
- end
- end
- 4'd11:
- begin
- if(AD_FSM_State) //
- begin
- nstate_ad = 4'd11;
- end
- else
- begin
- nstate_ad = 4'd12; //
- end
- end
- 4'd12: // 将读到的数据记录下来
- begin
- nstate_ad = 4'd13;
- end
- 4'd13: // 读取通道索引值加1,读取下一通道值
- begin
- nstate_ad = 4'd6;
- end
- // default:nstate_ad = 4'd0;
- default: nstate_ad = 4'd0;
- endcase
-
- end
- end
- // 输出值实现
- always @(posedge sys_clk or negedge rst_n)
- begin
- if(!rst_n)
- begin
- ADStart <= 0;
- ad_convsta <= 1;
- ADSampNum <= 0;
- ad_samp_value[0][15:0] <= 0;
- ad_samp_value[1][15:0] <= 0;
- ad_samp_value[2][15:0] <= 0;
- ad_samp_value[3][15:0] <= 0;
- ad_samp_value[4][15:0] <= 0;
- ad_samp_value[5][15:0] <= 0;
- ad_samp_value[6][15:0] <= 0;
- ad_samp_value[7][15:0] <= 0;
- end
- else
- begin
- case(cstate_ad)
- 4'd0:
- begin
- ad_convsta <= 1;
- ADSampNum <= 0;
- end
- 4'd1: // ad_convsta拉低62.5ns,大于手册要求的最小25ns的要求
- begin
- ad_convsta <= 0;
- end
- 4'd2:
- begin
- ad_convsta <= 1;
- end
- 4'd3:
- begin
- ;
- end
- 4'd4:
- begin
- ;
- end
- 4'd5:
- begin
- ;
- end
- 4'd6:
- begin
- ;
- end
- 4'd7: // 启动SPI时钟
- begin
- ADStart <= 1;
- end
- 4'd8:
- begin
- ADStart <= 0;
- end
- 4'd9:
- begin
- ;
- end
- 4'd10:
- begin
- ;
- end
- 4'd11:
- begin
- ;
- end
- 4'd12:
- begin
- ad_samp_value[ADSampNum][15:0] <= ad_samp_value_current_a[15:0];
- ad_samp_value[ADSampNum+4][15:0] <= ad_samp_value_current_b[15:0];
-
- end
- 4'd13:
- begin
- ADSampNum <= ADSampNum +1;
- end
- default: ;
-
-
- endcase
- end
- end
- // 延时计数器
- reg [4:0] ADDelay_Cnt;
- always @(posedge sys_clk or negedge rst_n)
- begin
- if(!rst_n)
- begin
- ADDelay_Cnt <= 0;
- end
- else
- begin
- if(ADStart)
- ADDelay_Cnt <= 0;
- else
- begin
- if( ADDelay_Cnt < 5'd21)
- ADDelay_Cnt <= ADDelay_Cnt + 1;
- else
- ADDelay_Cnt <= ADDelay_Cnt;
- end
- end
- end
- //读取采样结果例化
- ADSPI_RX ADRX(.clk_div(clk_div),.rst_n(rst_n),.spi_clk(ad_sclk),.ad_start(ADStart),.spi_en(ADEn),.spi_miso_a(ad_miso_a),.spi_miso_b(ad_miso_b),.spi_ncs(ad_cs_n),
- .rx_value_a(ad_samp_value_current_a[15:0]),.rx_value_b(ad_samp_value_current_b[15:0]),.spi_state(AD_FSM_State));
|