久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6298|回復: 5
收起左側

FAGA+ADS1118+異步FIFO+串口源程序

[復制鏈接]
ID:264904 發表于 2017-12-21 16:55 | 顯示全部樓層 |閱讀模式
該資源為FPGA工程文件,基于Quartus II 15.1開發環境,使用verilog編寫,備注詳細。16bit四通道模數轉換芯片ADS1118采集模擬電壓信號(通道可選,電壓范圍可變),通過SPI接口和FPGA通信,數據在自己編寫的異步FIFO緩存,經過UART接口,將數據傳輸至PC,使用串口調試助手可查看接收數據,經驗證可在工程中使用。

0.png

源程序如下:
  1. //---------------------------------------------------------------------------
  2. //--        文件名                :        ADS1118_module.v
  3. //--        作者                :        Chen.s.y
  4. //--        描述                :        ADS1118模/數轉換芯片驅動時序
  5. //--        修訂歷史        :        2017-8-20
  6. //---------------------------------------------------------------------------

  7. `define SCLK_TIME                        11'd2000                        //0.025M=25khz, 40us,40 / (1 / 50M) = 2000
  8. `define SCLK_TIME_HALF        10'd1000                        //40us / 2 = 20us  10 / 2 = 1000

  9. module ADS1118_module(CLK_50M,RST,CS,DIN,DOUT,SCLK,fifo_wclk,ADC_result);

  10. /*parameter ADS_config_AIN0=16'h458A;        //ADS1118配置數據(模擬通道0)0100_0101_1000_1010
  11. parameter ADS_config_AIN1=16'h558A;        //ADS1118配置數據(模擬通道1)0101_0101_1000_1010
  12. parameter ADS_config_AIN2=16'h658A;        //ADS1118配置數據(模擬通道2)0110_0101_1000_1010
  13. parameter ADS_config_AIN3=16'h758A;        //ADS1118配置數據(模擬通道3)0111_0101_1000_1010*/
  14. /*parameter ADS_config_AIN0=16'h448A;        //ADS1118配置數據(模擬通道0)0100_0100_1000_1010
  15. parameter ADS_config_AIN1=16'h548A;        //ADS1118配置數據(模擬通道1)0101_0100_1000_1010
  16. parameter ADS_config_AIN2=16'h648A;        //ADS1118配置數據(模擬通道2)0110_0100_1000_1010
  17. parameter ADS_config_AIN3=16'h748A;        //ADS1118配置數據(模擬通道3)0111_0100_1000_1010*/

  18. parameter ADS_config_AIN0=16'hC2E3;        //ADS1118配置數據(模擬通道0)1100_0010_1110_0011
  19. parameter ADS_config_AIN1=16'hC2E3;        //ADS1118配置數據(模擬通道1)0101_0100_1000_1010
  20. parameter ADS_config_AIN2=16'hE2E3;        //ADS1118配置數據(模擬通道2)1110_0010_1110_0011
  21. parameter ADS_config_AIN3=16'hE2E3;        //ADS1118配置數據(模擬通道3)0111_0100_1000_1010

  22. //---------------------------------------------------------------------------
  23. //--        外部端口聲明
  24. //---------------------------------------------------------------------------
  25. input  CLK_50M,RST;
  26. input  DOUT;                                                                //The result of ADC
  27. output CS;                                                                        //The signal of starting converting
  28. output DIN;                                                                        //The signal of serial input       
  29. output SCLK;                                                                //The clock siganl of ADC chip
  30. output fifo_wclk;                                                        //The write clk of fifo module
  31. output [ 7:0]ADC_result;                                //The 8bit data of ADC

  32. //---------------------------------------------------------------------------
  33. //--        內部端口聲明
  34. //---------------------------------------------------------------------------
  35. wire                                         DIN;                                        //AD串行數據輸入
  36. reg                                        DIN_N;                                //DIN的下一個狀態
  37. reg                                        CS;                                        //AD片選信號
  38. reg                                        CS_N;                                        //CS的下一個狀態
  39. reg                                        SCLK;                                        //AD時鐘,最大不超過4MHz,最小為35.71Hz,這里設置為2.5MHz
  40. reg                                        SCLK_N;                                //SCLK的下一個狀態

  41. reg                [ 2:0]        fsm_cs;                                //狀態機的當前狀態
  42. reg                [ 2:0]        fsm_ns;                                //狀態機的下一個狀態


  43. reg                [ 11:0]        time_cnt;                        //用于記錄一個時鐘所用時間的定時器
  44. reg                [ 11:0]        time_cnt_n;                        //time_cnt的下一個狀態
  45. reg                [ 4:0]        bit_cnt;                                //用來記錄時鐘周期個數的計數器
  46. reg                [ 4:0]        bit_cnt_n;                        //bit_cnt的下一個狀態

  47. reg                 [ 1:0]        flag;                                        //用來標記四個通道采樣的順序
  48. reg                 [ 1:0]        flag_n;                                //flag的下一個狀態

  49. reg                [15:0]        ADC_DATA;                        //用來保存穩定的16bit AD數據
  50. reg                [15:0]        ADC_DATA_n;                        //ADC_DATA的下一個狀態
  51. reg                [15:0]        ad_data_reg;                //用于保存數據的移位寄存器
  52. reg                [15:0]        ad_data_reg_n;                //ad_data_reg的下一個狀態

  53. reg                [15:0]        ADS_config_data;        //ADS1118配置寄存器

  54. reg                                        wfifo_clk_n1;                //fifo_wclk_n的下一個狀態
  55. reg                                        wfifo_clk_n2;                //fifo_wclk_n的下一個狀態
  56. reg                [15:0]        wfifo_clk_cnt;                //用于計數ADC_DATA的脈寬
  57. reg                [15:0]        wfifo_clk_cnt_n;        //wfifo_clk_cnt的下一個狀態

  58. reg                                        data_flag;                        //16bit ADC數據拆分為8bit的標志
  59.                                                                                                 //1:發送低8位
  60.                                                                                                 //0:發送高八位
  61. reg                [ 7:0]        ADC_result;                        //拆分ADS芯片16bit的采樣結果(便于串口傳輸)

  62. //---------------------------------------------------------------------------

  63. assign DIN = DIN_N;
  64. assign fifo_wclk=~wfifo_clk_n1;

  65. parameter        FSM_IDLE                        = 3'h0;        //狀態機的初始狀態
  66. parameter        FSM_CS0                        = 3'h1;        //CS下降沿到第一個SCK上升沿的等待狀態,最小為值100ns
  67. parameter        FSM_DATA                        = 3'h2;        //讀取16個數據狀態
  68. parameter        FSM_CS1                        = 3'h3;        //最后一個SCK下降沿到CS上升沿的等待狀態,最小為值100ns
  69. parameter        FSM_END                        = 3'h4;        //結束的狀態

  70. //---------------------------------------------------------------------------
  71. //--        邏輯功能實現       
  72. //---------------------------------------------------------------------------
  73. //時序電路,用來給fsm_cs寄存器賦值
  74. always @ (posedge CLK_50M or negedge RST)
  75. begin
  76.         if(!RST)                                                                        //判斷復位
  77.                 fsm_cs <= 1'b0;                                        //初始化ad_fsm_cs值
  78.         else
  79.                 fsm_cs <= fsm_ns;                                        //用來給ad_fsm_ns賦值
  80. end

  81. //組合電路,用來實現狀態機
  82. always @ (*)
  83. begin
  84.         case(fsm_cs)                                                        //判斷狀態機的當前狀態
  85.        
  86.         //---------------------------------------------------------------------//
  87.                 FSM_IDLE:
  88.                                                                                                 //2 x SCLK_TIME用于初始化延時
  89.                         if((bit_cnt == 5'd1 ) && (time_cnt == `SCLK_TIME))
  90.                                 fsm_ns = FSM_CS0;                        //完成就進入CS下降沿到第一個SCK上升沿的等待狀態
  91.                         else
  92.                                 fsm_ns = fsm_cs;                        //否則保持原狀態不變
  93.         //---------------------------------------------------------------------//
  94.                 FSM_CS0:
  95.                                                                                                 //2 x SCLK_TIME 用于等待延時
  96.                         if((bit_cnt == 5'd1 ) && (time_cnt == `SCLK_TIME))
  97.                                 fsm_ns = FSM_DATA;                //完成就進入讀取數據狀態
  98.                         else
  99.                                 fsm_ns = fsm_cs;                  //否則保持原狀態不變

  100.         //---------------------------------------------------------------------//
  101.                 FSM_DATA:
  102.                                                                                                 //讀取數據16位,1~16個時鐘脈沖
  103.                         if((bit_cnt == 5'd16 ) && (time_cnt == `SCLK_TIME))
  104.                                 fsm_ns = FSM_CS1;                        //如果讀取數據狀態完成就進入結束狀態
  105.                         else
  106.                                 fsm_ns = fsm_cs;                        //否則保持原狀態不變               
  107.                                
  108.         //---------------------------------------------------------------------//
  109.                 FSM_CS1:
  110.                                                                                                 //2 x SCLK_TIME 用于等待延時
  111.                         if((bit_cnt == 9'd1 ) && (time_cnt == `SCLK_TIME))
  112.                                 fsm_ns = FSM_END;                        //完成就進入結束狀態
  113.                         else
  114.                                 fsm_ns = fsm_cs;                  //否則保持原狀態不變
  115.         //---------------------------------------------------------------------//
  116.                 FSM_END:                                                               
  117.                                 fsm_ns = FSM_IDLE;                //完成一次數據轉換,進入下一次轉換
  118.                        
  119.                 default:fsm_ns = FSM_IDLE;                               
  120.         endcase
  121. end

  122. //時序電路,用來給time_cnt寄存器賦值
  123. always @ (posedge CLK_50M or negedge RST)
  124. begin
  125.         if(!RST)                                                                        //判斷復位
  126.                 time_cnt <= 12'h0;                                        //初始化time_cnt值
  127.         else
  128.                 time_cnt <= time_cnt_n;                        //用來給time_cnt賦值
  129. end

  130. //組合電路,實現SCLK_TIME的定時計數器
  131. always @ (*)
  132. begin
  133.         if(time_cnt == `SCLK_TIME)                        //判斷SCLK_TIME時間
  134.                 time_cnt_n = 12'h0;                                //如果到達SCLK_TIME,定時器清零
  135.         else
  136.                 time_cnt_n = time_cnt + 12'h1;        //如果未到SCLK_TIME,定時器繼續加1
  137. end

  138. //時序電路,用來給bit_cnt寄存器賦值
  139. always @ (posedge CLK_50M or negedge RST)
  140. begin
  141.         if(!RST)                                                                        //判斷復位
  142.                 bit_cnt <= 5'h0;                                        //初始化bit_cnt值
  143.         else
  144.                 bit_cnt <= bit_cnt_n;                        //用來給bit_cnt賦值
  145. end

  146. //組合電路,用來記錄時鐘周期個數的計數器
  147. always @ (*)
  148. begin
  149.         if(fsm_cs != fsm_ns)                                        //判斷狀態機的當前狀態
  150.                 bit_cnt_n = 5'h0;                                        //如果當前的狀態不等于下一個狀態,計時器就清零
  151.         else if(time_cnt == `SCLK_TIME_HALF)//判斷SCLK_TIME_HALF時間
  152.                 bit_cnt_n = bit_cnt + 5'b1;        //如果到達SCLK_TIME_HALF,計數器就加1
  153.         else
  154.                 bit_cnt_n = bit_cnt;                                //否則計數器保持不變
  155. end

  156. //時序電路,用來給AD_CLK寄存器賦值
  157. always @ (posedge CLK_50M or negedge RST)
  158. begin
  159.         if(!RST)                                                                        //判斷復位
  160.                 SCLK <= 1'h0;                                                //初始化AD_CLK值
  161.         else
  162.                 SCLK <= SCLK_N;                                        //用來給AD_CLK賦值
  163. end

  164. //組合電路,用來生成AD的時鐘波形
  165. always @ (*)
  166. begin
  167.         if(fsm_cs != FSM_DATA)                       
  168.                 SCLK_N = 1'h0;                                                //如果當前的狀態不等于讀取數據狀態,SCLK_N就置0
  169.         else if(time_cnt == `SCLK_TIME_HALF)//判斷SCLK_TIME_HALF時間
  170.                 SCLK_N = 1'h1;                                                //如果到達SCLK_TIME_HALF,SCLK_N就置1
  171.         else if(time_cnt == `SCLK_TIME)        //判斷SCLK_TIME時間
  172.                 SCLK_N = 1'h0;                                                //如果到達SCLK_TIME,SCLK_N就置0
  173.         else
  174.                 SCLK_N = SCLK;                                                //否則保持不變
  175. end

  176. //時序電路,用來給CONVST寄存器賦值
  177. always @ (posedge CLK_50M or negedge RST)
  178. begin
  179.         if(!RST)                                                                        //判斷復位
  180.                 CS <= 1'h0;                                                        //初始化CS值
  181.         else
  182.                 CS <= CS_N;                                                        //用來給CS賦值
  183. end

  184. //組合電路,用來生成AD的CONVST
  185. always @ (*)
  186. begin
  187.         if((fsm_cs == FSM_DATA)||(fsm_cs == FSM_CS0)||(fsm_cs == FSM_CS1))
  188.                 CS_N = 1'h0;                                                //CS置1的狀態
  189.         else
  190.                 CS_N = 1'h1;                                                //CS置0的狀態
  191. end

  192. //時序電路,用來給ad_data_reg寄存器賦值
  193. always @ (posedge CLK_50M or negedge RST)
  194. begin
  195.         if(!RST)                                                                        //判斷復位
  196.                 ad_data_reg <= 8'h0;                                //初始化ad_data_reg值
  197.         else
  198.                 ad_data_reg <= ad_data_reg_n;        //用來給ad_data_reg賦值
  199. end

  200. //組合電路,將AD線上的數據保存到移位寄存器中
  201. always @(*)
  202. begin
  203.         if((fsm_cs == FSM_DATA) && (!SCLK) && (SCLK_N))
  204.                                                                                                 //判斷每一個時鐘的上升沿
  205.                 ad_data_reg_n = {ad_data_reg[14:0],DOUT};
  206.                                                                                                 //將數據存入移位寄存器中,高位優先
  207.         else
  208.                 ad_data_reg_n = ad_data_reg;        //否則保持不變
  209. end

  210. //時序電路,用來給data_out寄存器賦值
  211. always @ (posedge CLK_50M or negedge RST)
  212. begin
  213.         if(!RST)                                                                        //判斷復位
  214.                 ADC_DATA <= 0;                                                //初始化data_out值
  215.         else
  216.                 ADC_DATA <= ADC_DATA_n;                        //用來給data_out賦值
  217. end

  218. //組合電路,將移位寄存器中的數據存入data_out中,可用于輸出
  219. always @ (*)
  220. begin
  221.         if(fsm_cs == FSM_END)
  222.                 ADC_DATA_n = ad_data_reg;
  223.         else
  224.                 ADC_DATA_n = ADC_DATA;
  225. end

  226. always @ (posedge CLK_50M)
  227. begin
  228.         case(flag)
  229.                 2'd0:ADS_config_data <= ADS_config_AIN3;
  230.                 2'd1:ADS_config_data <= ADS_config_AIN0;
  231.                 2'd2:ADS_config_data <= ADS_config_AIN1;
  232.                 2'd3:ADS_config_data <= ADS_config_AIN2;
  233.                 default:ADS_config_data <= ADS_config_AIN0;
  234.         endcase
  235. end


  236. //時序電路,用來給DIN_N寄存器賦值
  237. always @ (posedge CLK_50M or negedge RST)
  238. begin
  239.         if(!RST)
  240.                 DIN_N<=0;
  241.         else if(fsm_cs == FSM_DATA)
  242.                 case(bit_cnt)
  243.                                 5'd0,5'b1:DIN_N<=ADS_config_data[15];
  244.                                 5'd2:DIN_N<=ADS_config_data[14];
  245.                                 5'd3:DIN_N<=ADS_config_data[13];
  246.                                 5'd4:DIN_N<=ADS_config_data[12];
  247.                                 5'd5:DIN_N<=ADS_config_data[11];
  248.                                 5'd6:DIN_N<=ADS_config_data[10];
  249.                                 5'd7:DIN_N<=ADS_config_data[9];
  250.                                 5'd8:DIN_N<=ADS_config_data[8];
  251.                                 5'd9:DIN_N<=ADS_config_data[7];
  252.                                 5'd10:DIN_N<=ADS_config_data[6];
  253.                                 5'd11:DIN_N<=ADS_config_data[5];
  254.                                 5'd12:DIN_N<=ADS_config_data[4];
  255.                                 5'd13:DIN_N<=ADS_config_data[3];
  256.                                 5'd14:DIN_N<=ADS_config_data[2];
  257.                                 5'd15:DIN_N<=ADS_config_data[1];
  258.                                 5'd16:DIN_N<=ADS_config_data[0];
  259.                                 default:DIN_N<= 0;
  260.                 endcase
  261.         else
  262.                 DIN_N<= DIN_N;
  263. end


  264. always @ (posedge CLK_50M or negedge RST)
  265. begin
  266.         if(!RST)                                                                        //判斷復位
  267.                 flag <= 2'b0;                                        //初始化bit_cnt值
  268.         else
  269.                 flag <= flag_n;                                //用來給bit_cnt賦值
  270. end

  271. //組合電路,用來記錄時鐘周期個數的計數器
  272. always @ (*)
  273. begin
  274.         if((!CS)&&(CS_N))
  275.                 flag_n <= flag + 2'b1;
  276.         else
  277.                 flag_n = flag;
  278. end


  279. always @ (posedge CLK_50M or negedge RST)
  280. begin
  281.         if(!RST)
  282.                 wfifo_clk_cnt <= 16'b0;
  283.         else
  284.                 wfifo_clk_cnt <= wfifo_clk_cnt_n;
  285. end


  286. always @ (*)
  287. begin
  288.         if((fsm_cs == FSM_DATA)||(fsm_cs == FSM_CS0)||(fsm_cs == FSM_CS1)||(fsm_cs == FSM_IDLE))
  289.                 wfifo_clk_cnt_n <= wfifo_clk_cnt + 16'b1;
  290.         else if(fsm_cs == FSM_END)
  291.                 wfifo_clk_cnt_n <= 16'b0;
  292.         else
  293.                 wfifo_clk_cnt_n <= wfifo_clk_cnt;
  294. end

  295. always @ (posedge CLK_50M or negedge RST)
  296. begin
  297.         if(!RST)                                                                       
  298.                 wfifo_clk_n1 <= 0;
  299.         else
  300.                 wfifo_clk_n1 <= wfifo_clk_n2;
  301. end

  302. always @(*)
  303. begin
  304.         if((wfifo_clk_cnt == 16'd9504)||(wfifo_clk_cnt == 16'd19009)||(wfifo_clk_cnt == 16'd28513)||(wfifo_clk_cnt == 16'd38018))
  305.                 wfifo_clk_n2 <= ~wfifo_clk_n1;
  306.         else
  307.                 wfifo_clk_n2 <= wfifo_clk_n1;
  308. end

  309. always @(negedge wfifo_clk_n1 or negedge RST)
  310. begin
  311.         if(!RST)
  312.                 data_flag <= 1'b0;
  313.         else
  314.                 data_flag <= data_flag+1'b1;
  315. end

  316. always @(posedge wfifo_clk_n1 or negedge RST)
  317. begin
  318.         if(!RST)
  319.                 ADC_result <= 8'b0;
  320.         else if(data_flag == 1'b0)
  321.                 ADC_result <= ADC_DATA[15:8];
  322.         else
  323.                 ADC_result <= ADC_DATA[ 7:0];
  324. end

  325. endmodule
復制代碼

所有資料51hei提供下載:
ADS1118_FIFO_MODULE.zip (6.65 MB, 下載次數: 80)
回復

使用道具 舉報

ID:234676 發表于 2017-12-21 21:52 | 顯示全部樓層
學習一波
回復

使用道具 舉報

ID:360598 發表于 2018-6-27 21:22 | 顯示全部樓層
希望對我有用,謝謝
回復

使用道具 舉報

ID:360598 發表于 2018-7-4 06:30 | 顯示全部樓層
解釋很詳細,正好是我需要的,謝謝
回復

使用道具 舉報

ID:818590 發表于 2020-9-13 19:44 | 顯示全部樓層
正好要學習ADS1118,解釋很到位!
回復

使用道具 舉報

ID:1042417 發表于 2023-8-30 14:04 | 顯示全部樓層
可以實現多通道一塊采集嗎
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91中文字幕在线观看 | 日韩久久精品 | 中文字幕在线视频免费视频 | 91免费电影 | 国产91视频一区二区 | 国产精品久久久久久久久久久久 | 国产精品久久久久久影视 | 精品综合久久久 | 久久久久久久一区二区三区 | 亚洲视频中文字幕 | 免费在线一区二区 | 最新超碰| 黄色精品 | 日韩精品极品视频在线观看免费 | 成人在线国产 | 欧美色999| 亚洲成人免费 | 成人黄色av | 色婷婷一区二区三区四区 | av中文字幕在线 | 国产1区2区3区 | 欧洲亚洲一区 | 日韩www| 俺去俺来也www色官网cms | 一区二区av在线 | 国产在线精品一区二区三区 | 久久国产高清视频 | 午夜精品一区二区三区在线播放 | 精品亚洲一区二区三区四区五区 | 美女网站视频免费黄 | 中文字幕国产第一页 | 中文字幕亚洲欧美 | 日韩精品在线一区 | 久久亚洲91 | 亚洲91 | 天天色影视综合 | 亚洲国产二区 | 亚洲精品电影在线观看 | 久久久网| 亚洲第一成人影院 | 干干干操操操 |