亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
FAGA+ADS1118+異步FIFO+串口源程序
[打印本頁]
作者:
Chensy
時間:
2017-12-21 16:55
標題:
FAGA+ADS1118+異步FIFO+串口源程序
該資源為FPGA工程文件,基于Quartus II 15.1開發環境,使用verilog編寫,備注詳細。16bit四通道模數轉換芯片ADS1118采集模擬電壓信號(通道可選,電壓范圍可變),通過SPI接口和FPGA通信,數據在自己編寫的異步FIFO緩存,經過UART接口,將數據傳輸至PC,使用串口調試助手可查看接收數據,經驗證可在工程中使用。
0.png
(13.33 KB, 下載次數: 61)
下載附件
2017-12-21 17:07 上傳
源程序如下:
//---------------------------------------------------------------------------
//-- 文件名 : ADS1118_module.v
//-- 作者 : Chen.s.y
//-- 描述 : ADS1118模/數轉換芯片驅動時序
//-- 修訂歷史 : 2017-8-20
//---------------------------------------------------------------------------
`define SCLK_TIME 11'd2000 //0.025M=25khz, 40us,40 / (1 / 50M) = 2000
`define SCLK_TIME_HALF 10'd1000 //40us / 2 = 20us 10 / 2 = 1000
module ADS1118_module(CLK_50M,RST,CS,DIN,DOUT,SCLK,fifo_wclk,ADC_result);
/*parameter ADS_config_AIN0=16'h458A; //ADS1118配置數據(模擬通道0)0100_0101_1000_1010
parameter ADS_config_AIN1=16'h558A; //ADS1118配置數據(模擬通道1)0101_0101_1000_1010
parameter ADS_config_AIN2=16'h658A; //ADS1118配置數據(模擬通道2)0110_0101_1000_1010
parameter ADS_config_AIN3=16'h758A; //ADS1118配置數據(模擬通道3)0111_0101_1000_1010*/
/*parameter ADS_config_AIN0=16'h448A; //ADS1118配置數據(模擬通道0)0100_0100_1000_1010
parameter ADS_config_AIN1=16'h548A; //ADS1118配置數據(模擬通道1)0101_0100_1000_1010
parameter ADS_config_AIN2=16'h648A; //ADS1118配置數據(模擬通道2)0110_0100_1000_1010
parameter ADS_config_AIN3=16'h748A; //ADS1118配置數據(模擬通道3)0111_0100_1000_1010*/
parameter ADS_config_AIN0=16'hC2E3; //ADS1118配置數據(模擬通道0)1100_0010_1110_0011
parameter ADS_config_AIN1=16'hC2E3; //ADS1118配置數據(模擬通道1)0101_0100_1000_1010
parameter ADS_config_AIN2=16'hE2E3; //ADS1118配置數據(模擬通道2)1110_0010_1110_0011
parameter ADS_config_AIN3=16'hE2E3; //ADS1118配置數據(模擬通道3)0111_0100_1000_1010
//---------------------------------------------------------------------------
//-- 外部端口聲明
//---------------------------------------------------------------------------
input CLK_50M,RST;
input DOUT; //The result of ADC
output CS; //The signal of starting converting
output DIN; //The signal of serial input
output SCLK; //The clock siganl of ADC chip
output fifo_wclk; //The write clk of fifo module
output [ 7:0]ADC_result; //The 8bit data of ADC
//---------------------------------------------------------------------------
//-- 內部端口聲明
//---------------------------------------------------------------------------
wire DIN; //AD串行數據輸入
reg DIN_N; //DIN的下一個狀態
reg CS; //AD片選信號
reg CS_N; //CS的下一個狀態
reg SCLK; //AD時鐘,最大不超過4MHz,最小為35.71Hz,這里設置為2.5MHz
reg SCLK_N; //SCLK的下一個狀態
reg [ 2:0] fsm_cs; //狀態機的當前狀態
reg [ 2:0] fsm_ns; //狀態機的下一個狀態
reg [ 11:0] time_cnt; //用于記錄一個時鐘所用時間的定時器
reg [ 11:0] time_cnt_n; //time_cnt的下一個狀態
reg [ 4:0] bit_cnt; //用來記錄時鐘周期個數的計數器
reg [ 4:0] bit_cnt_n; //bit_cnt的下一個狀態
reg [ 1:0] flag; //用來標記四個通道采樣的順序
reg [ 1:0] flag_n; //flag的下一個狀態
reg [15:0] ADC_DATA; //用來保存穩定的16bit AD數據
reg [15:0] ADC_DATA_n; //ADC_DATA的下一個狀態
reg [15:0] ad_data_reg; //用于保存數據的移位寄存器
reg [15:0] ad_data_reg_n; //ad_data_reg的下一個狀態
reg [15:0] ADS_config_data; //ADS1118配置寄存器
reg wfifo_clk_n1; //fifo_wclk_n的下一個狀態
reg wfifo_clk_n2; //fifo_wclk_n的下一個狀態
reg [15:0] wfifo_clk_cnt; //用于計數ADC_DATA的脈寬
reg [15:0] wfifo_clk_cnt_n; //wfifo_clk_cnt的下一個狀態
reg data_flag; //16bit ADC數據拆分為8bit的標志
//1:發送低8位
//0:發送高八位
reg [ 7:0] ADC_result; //拆分ADS芯片16bit的采樣結果(便于串口傳輸)
//---------------------------------------------------------------------------
assign DIN = DIN_N;
assign fifo_wclk=~wfifo_clk_n1;
parameter FSM_IDLE = 3'h0; //狀態機的初始狀態
parameter FSM_CS0 = 3'h1; //CS下降沿到第一個SCK上升沿的等待狀態,最小為值100ns
parameter FSM_DATA = 3'h2; //讀取16個數據狀態
parameter FSM_CS1 = 3'h3; //最后一個SCK下降沿到CS上升沿的等待狀態,最小為值100ns
parameter FSM_END = 3'h4; //結束的狀態
//---------------------------------------------------------------------------
//-- 邏輯功能實現
//---------------------------------------------------------------------------
//時序電路,用來給fsm_cs寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
fsm_cs <= 1'b0; //初始化ad_fsm_cs值
else
fsm_cs <= fsm_ns; //用來給ad_fsm_ns賦值
end
//組合電路,用來實現狀態機
always @ (*)
begin
case(fsm_cs) //判斷狀態機的當前狀態
//---------------------------------------------------------------------//
FSM_IDLE:
//2 x SCLK_TIME用于初始化延時
if((bit_cnt == 5'd1 ) && (time_cnt == `SCLK_TIME))
fsm_ns = FSM_CS0; //完成就進入CS下降沿到第一個SCK上升沿的等待狀態
else
fsm_ns = fsm_cs; //否則保持原狀態不變
//---------------------------------------------------------------------//
FSM_CS0:
//2 x SCLK_TIME 用于等待延時
if((bit_cnt == 5'd1 ) && (time_cnt == `SCLK_TIME))
fsm_ns = FSM_DATA; //完成就進入讀取數據狀態
else
fsm_ns = fsm_cs; //否則保持原狀態不變
//---------------------------------------------------------------------//
FSM_DATA:
//讀取數據16位,1~16個時鐘脈沖
if((bit_cnt == 5'd16 ) && (time_cnt == `SCLK_TIME))
fsm_ns = FSM_CS1; //如果讀取數據狀態完成就進入結束狀態
else
fsm_ns = fsm_cs; //否則保持原狀態不變
//---------------------------------------------------------------------//
FSM_CS1:
//2 x SCLK_TIME 用于等待延時
if((bit_cnt == 9'd1 ) && (time_cnt == `SCLK_TIME))
fsm_ns = FSM_END; //完成就進入結束狀態
else
fsm_ns = fsm_cs; //否則保持原狀態不變
//---------------------------------------------------------------------//
FSM_END:
fsm_ns = FSM_IDLE; //完成一次數據轉換,進入下一次轉換
default:fsm_ns = FSM_IDLE;
endcase
end
//時序電路,用來給time_cnt寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
time_cnt <= 12'h0; //初始化time_cnt值
else
time_cnt <= time_cnt_n; //用來給time_cnt賦值
end
//組合電路,實現SCLK_TIME的定時計數器
always @ (*)
begin
if(time_cnt == `SCLK_TIME) //判斷SCLK_TIME時間
time_cnt_n = 12'h0; //如果到達SCLK_TIME,定時器清零
else
time_cnt_n = time_cnt + 12'h1; //如果未到SCLK_TIME,定時器繼續加1
end
//時序電路,用來給bit_cnt寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
bit_cnt <= 5'h0; //初始化bit_cnt值
else
bit_cnt <= bit_cnt_n; //用來給bit_cnt賦值
end
//組合電路,用來記錄時鐘周期個數的計數器
always @ (*)
begin
if(fsm_cs != fsm_ns) //判斷狀態機的當前狀態
bit_cnt_n = 5'h0; //如果當前的狀態不等于下一個狀態,計時器就清零
else if(time_cnt == `SCLK_TIME_HALF)//判斷SCLK_TIME_HALF時間
bit_cnt_n = bit_cnt + 5'b1; //如果到達SCLK_TIME_HALF,計數器就加1
else
bit_cnt_n = bit_cnt; //否則計數器保持不變
end
//時序電路,用來給AD_CLK寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
SCLK <= 1'h0; //初始化AD_CLK值
else
SCLK <= SCLK_N; //用來給AD_CLK賦值
end
//組合電路,用來生成AD的時鐘波形
always @ (*)
begin
if(fsm_cs != FSM_DATA)
SCLK_N = 1'h0; //如果當前的狀態不等于讀取數據狀態,SCLK_N就置0
else if(time_cnt == `SCLK_TIME_HALF)//判斷SCLK_TIME_HALF時間
SCLK_N = 1'h1; //如果到達SCLK_TIME_HALF,SCLK_N就置1
else if(time_cnt == `SCLK_TIME) //判斷SCLK_TIME時間
SCLK_N = 1'h0; //如果到達SCLK_TIME,SCLK_N就置0
else
SCLK_N = SCLK; //否則保持不變
end
//時序電路,用來給CONVST寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
CS <= 1'h0; //初始化CS值
else
CS <= CS_N; //用來給CS賦值
end
//組合電路,用來生成AD的CONVST
always @ (*)
begin
if((fsm_cs == FSM_DATA)||(fsm_cs == FSM_CS0)||(fsm_cs == FSM_CS1))
CS_N = 1'h0; //CS置1的狀態
else
CS_N = 1'h1; //CS置0的狀態
end
//時序電路,用來給ad_data_reg寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
ad_data_reg <= 8'h0; //初始化ad_data_reg值
else
ad_data_reg <= ad_data_reg_n; //用來給ad_data_reg賦值
end
//組合電路,將AD線上的數據保存到移位寄存器中
always @(*)
begin
if((fsm_cs == FSM_DATA) && (!SCLK) && (SCLK_N))
//判斷每一個時鐘的上升沿
ad_data_reg_n = {ad_data_reg[14:0],DOUT};
//將數據存入移位寄存器中,高位優先
else
ad_data_reg_n = ad_data_reg; //否則保持不變
end
//時序電路,用來給data_out寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
ADC_DATA <= 0; //初始化data_out值
else
ADC_DATA <= ADC_DATA_n; //用來給data_out賦值
end
//組合電路,將移位寄存器中的數據存入data_out中,可用于輸出
always @ (*)
begin
if(fsm_cs == FSM_END)
ADC_DATA_n = ad_data_reg;
else
ADC_DATA_n = ADC_DATA;
end
always @ (posedge CLK_50M)
begin
case(flag)
2'd0:ADS_config_data <= ADS_config_AIN3;
2'd1:ADS_config_data <= ADS_config_AIN0;
2'd2:ADS_config_data <= ADS_config_AIN1;
2'd3:ADS_config_data <= ADS_config_AIN2;
default:ADS_config_data <= ADS_config_AIN0;
endcase
end
//時序電路,用來給DIN_N寄存器賦值
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST)
DIN_N<=0;
else if(fsm_cs == FSM_DATA)
case(bit_cnt)
5'd0,5'b1:DIN_N<=ADS_config_data[15];
5'd2:DIN_N<=ADS_config_data[14];
5'd3:DIN_N<=ADS_config_data[13];
5'd4:DIN_N<=ADS_config_data[12];
5'd5:DIN_N<=ADS_config_data[11];
5'd6:DIN_N<=ADS_config_data[10];
5'd7:DIN_N<=ADS_config_data[9];
5'd8:DIN_N<=ADS_config_data[8];
5'd9:DIN_N<=ADS_config_data[7];
5'd10:DIN_N<=ADS_config_data[6];
5'd11:DIN_N<=ADS_config_data[5];
5'd12:DIN_N<=ADS_config_data[4];
5'd13:DIN_N<=ADS_config_data[3];
5'd14:DIN_N<=ADS_config_data[2];
5'd15:DIN_N<=ADS_config_data[1];
5'd16:DIN_N<=ADS_config_data[0];
default:DIN_N<= 0;
endcase
else
DIN_N<= DIN_N;
end
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST) //判斷復位
flag <= 2'b0; //初始化bit_cnt值
else
flag <= flag_n; //用來給bit_cnt賦值
end
//組合電路,用來記錄時鐘周期個數的計數器
always @ (*)
begin
if((!CS)&&(CS_N))
flag_n <= flag + 2'b1;
else
flag_n = flag;
end
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST)
wfifo_clk_cnt <= 16'b0;
else
wfifo_clk_cnt <= wfifo_clk_cnt_n;
end
always @ (*)
begin
if((fsm_cs == FSM_DATA)||(fsm_cs == FSM_CS0)||(fsm_cs == FSM_CS1)||(fsm_cs == FSM_IDLE))
wfifo_clk_cnt_n <= wfifo_clk_cnt + 16'b1;
else if(fsm_cs == FSM_END)
wfifo_clk_cnt_n <= 16'b0;
else
wfifo_clk_cnt_n <= wfifo_clk_cnt;
end
always @ (posedge CLK_50M or negedge RST)
begin
if(!RST)
wfifo_clk_n1 <= 0;
else
wfifo_clk_n1 <= wfifo_clk_n2;
end
always @(*)
begin
if((wfifo_clk_cnt == 16'd9504)||(wfifo_clk_cnt == 16'd19009)||(wfifo_clk_cnt == 16'd28513)||(wfifo_clk_cnt == 16'd38018))
wfifo_clk_n2 <= ~wfifo_clk_n1;
else
wfifo_clk_n2 <= wfifo_clk_n1;
end
always @(negedge wfifo_clk_n1 or negedge RST)
begin
if(!RST)
data_flag <= 1'b0;
else
data_flag <= data_flag+1'b1;
end
always @(posedge wfifo_clk_n1 or negedge RST)
begin
if(!RST)
ADC_result <= 8'b0;
else if(data_flag == 1'b0)
ADC_result <= ADC_DATA[15:8];
else
ADC_result <= ADC_DATA[ 7:0];
end
endmodule
復制代碼
所有資料51hei提供下載:
ADS1118_FIFO_MODULE.zip
(6.65 MB, 下載次數: 80)
2017-12-21 16:54 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
Akon帝
時間:
2017-12-21 21:52
學習一波
作者:
lxh0wj
時間:
2018-6-27 21:22
希望對我有用,謝謝
作者:
lxh0wj
時間:
2018-7-4 06:30
解釋很詳細,正好是我需要的,謝謝
作者:
z384372512
時間:
2020-9-13 19:44
正好要學習ADS1118,解釋很到位!
作者:
gaogang1998
時間:
2023-8-30 14:04
可以實現多通道一塊采集嗎
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1