one wire(單總線)FPGA代碼篇

一.引言

????????單總線(OneWire)是一種串行通信協議,它允許多個設備通過一個單一的數據線進行通信。這個協議通常用于低速、短距離的數字通信,特別適用于嵌入式系統和傳感器網絡。

?

二.one wire通信優點缺點

優點:

  1. 單一數據線:?單總線僅需要一根數據線,這極大地簡化了硬件連接。設備可以在同一總線上連接,并且通過地址來區分彼此。
  2. 低成本:?單總線協議不需要復雜的硬件,這降低了成本。這使其成為連接多個設備的經濟實惠選擇。
  3. 數據傳輸速率:?單總線通常以較低的數據傳輸速率工作,適用于一些低功耗和簡單的應用。
  4. 異步通信:?數據在單總線上傳輸是異步的,不需要共享時鐘信號。這使得它適用于各種設備和微控制器。
  5. 支持供電:?單總線通常支持從總線上獲得電源,這對于一些小型設備非常有用。

缺點:

  1. 傳輸距離有限:由于采用單線傳輸數據,因此傳輸距離有限,通常在幾米以內。
  2. 抗干擾能力較弱:由于采用單線傳輸數據,因此容易受到外界干擾的影響,導致數據傳輸錯誤。
  3. 擴展性較差:由于采用單線傳輸數據,因此無法實現多從機的通信,擴展性較差。

三.one wire工作原理

  1. 物理層連接:?單總線通信通常包括一個總線上的主設備和一個或多個從設備。這些設備通過一根物理數據線連接。總線上還可能有一個電源線用于為從設備提供電源。
  2. 數據幀:?通信基于數據幀的傳輸。一個數據幀通常包括起始位(Start Bit)、數據位、可選的校驗位,以及停止位(Stop Bit)。
  3. 數據傳輸:?數據傳輸是異步的,沒有共享時鐘信號。數據通過時間間隔來表示邏輯 0 和邏輯 1。邏輯 0 和邏輯 1通常是通過時間長短來區分的,即短脈沖表示邏輯 0,長脈沖表示邏輯 1。
  4. 設備地址:?每個從設備都有一個唯一的地址,主設備通過發送從設備的地址來選擇與之通信的特定設備。
  5. 總線控制:?主設備負責控制總線上的通信。它生成起始條件(Start Condition)和停止條件(Stop Condition)來開始和結束通信。
  6. 時序要求:?單總線通信非常依賴時序。每個位都必須在特定的時間內傳輸和采樣,以確保數據的正確性。
  7. 供電:?一些單總線設備可以從總線上獲得電源,這減少了對額外電源線的需求。
  8. 錯誤處理:?單總線通信通常包括錯誤檢測和糾正機制,以確保數據的完整性。

四.協議簡介? ?

????????One Wire總線的通信過程分為三個階段:

  1. 初始化階段:主機發送一個復位信號,將總線上的所有設備復位。
  2. 數據傳輸階段:主機發送一個時鐘信號,從機根據主機的時鐘信號逐位發送數據。主機可以接收從機發送的數據,也可以向從機發送數據。
  3. 結束階段:主機發送一個停止信號,結束通信過程。

復位和應答

寫協議

讀協議?

?

?五.verilog代碼

? ? ? ? 代碼以狀態機的方式展示,根據上圖協議我們可以把狀態機分成復位脈沖和在線應答脈沖的復位序列、寫 0 時隙、寫 1 時隙、讀時隙等等。

module wb_onewire(  input         wb_clk_i,           // 時鐘輸入  input         wb_rst_i,            // 復位輸入  input  [15:0] wb_dat_i,            // 16位寬的數據輸入  output [15:0] wb_dat_o,            // 16位寬的數據輸出  output        wb_ack_o,           // 一拍有效的確認輸出  input         wb_we_i,             // 一拍有效的寫信號輸入  input         wb_cyc_i,            // 一拍有效的周期信號輸入  input         wb_stb_i,            // 一拍有效的穩定信號輸入  output [7:0]  onewire_o,           // 8位寬的一線串行總線輸出  output [7:0]  onewire_oe_o,        // 高表示總線為主機使用,低表示總線為從機使用  input  [7:0]  onewire_i            // 8位寬的一線串行總線輸入  
);  parameter read_block_enable_opt = 1'b1;   // 讀塊使能參數,默認為1  
parameter push_1_opt            = 1'b0;   // push 1參數,默認為0  
parameter wb_freq               = 75000000; // 時鐘頻率參數,默認為75MHz  // 函數定義:計算微秒計數器值  
function [15:0] usec_count;  
input [9:0] usec;  
begin  usec_count = (((wb_freq / 1000000) * usec) - 1) & 16'hffff;  
end  
endfunction  reg [2:0]  lun, b;                     // 3位寬的lun和b寄存器  
reg [3:0]  read_bytes;                // 4位寬的讀取字節寄存器  
reg [15:0] usec_counter;             // 16位寬的微秒計數器  
reg        rst_bit, usec_counter_run; // 重置位和微秒計數器運行標志位  
reg        wb_ack, rxdone, onewire_i_q; // wb確認、接收完成、onewire輸入隊列標志位  
reg        usec_counter2_run;        // 第二個微秒計數器運行標志位  
reg [8:0]  usec_counter2;            // 9位寬的第二個微秒計數器  
reg [7:0]  dat, shiftreg, onewire, onewire_oe; // 數據、移位寄存器、onewire數據、onewire使能標志位  assign wb_ack_o     = wb_ack;          // wb確認輸出信號  
assign wb_dat_o     = {lun, rst_bit, read_bytes, dat}; // wb數據輸出信號  
assign onewire_oe_o  = onewire_oe;      // 一線串行總線使能輸出信號  
assign onewire_o     = onewire;        // 一線串行總線輸出信號  // 主邏輯塊,在時鐘上升沿或復位信號上升沿觸發  
always @(posedge wb_clk_i or posedge wb_rst_i) beginif (wb_rst_i) beginstate            <= 4'd0 ;wb_ack           <= 1'b0 ;lun              <= 3'd0 ;read_bytes       <= 4'd0 ;usec_counter     <= 16'd0;usec_counter_run <= 1'b0 ;usec_counter2    <= 9'd0 ;usec_counter2_run<= 1'b0 ;onewire          <= 8'd0 ;onewire_oe       <= 8'd0 ;rst_bit          <= 1'b0 ;dat              <= 8'd0 ;shiftreg         <= 8'd0 ;b                <= 3'd0 ;rxdone           <= 1'b0 ;push_done        <= 1'b0 ;onewire_i_q      <= 1'b0 ;end else beginwb_ack      <= 1'b0;onewire_i_q <= onewire_i[lun];if (usec_counter_run) beginif (usec_counter == 16'd0) usec_counter_run <= 1'b0;usec_counter     <= usec_counter - 1'b1;endif (usec_counter2_run) beginif (usec_counter2 == 9'd0) usec_counter2_run <= 1'b0;usec_counter2     <= usec_counter2 - 1'b1;endif (wb_cyc_i && wb_stb_i && !wb_ack && !wb_we_i) beginif (!read_block_enable_opt || (!rst_bit && (rxdone || read_bytes == 4'd0))) beginwb_ack <= 1'b1;rxdone <= 1'b0;endendcase (state)   //代碼核心,狀態機部分4'd0:          //初始化,狀態選擇if (!rxdone && read_bytes != 4'd0) beginrst_bit <= 1'b1;state   <= 4'd7;if (read_bytes >= 4'he) b <= read_bytes[0] ? 3'd6 : 3'd7;end else if (wb_cyc_i && wb_stb_i && !wb_ack && wb_we_i) beginwb_ack     <= 1'b1;lun        <= wb_dat_i[15:13];read_bytes <= wb_dat_i[11:8];if (wb_dat_i[12] && wb_dat_i[7]) begin // reset state   <= 4'd1; rst_bit <= 1'b1;end else if (wb_dat_i[12] && wb_dat_i[6]) begin // write 1-bit state    <= 4'd5; shiftreg <= wb_dat_i[7:0];rst_bit  <= 1'b1;b        <= 3'd7; end else if (!wb_dat_i[12]) begin // write 8-bit state    <= 4'd5; shiftreg <= wb_dat_i[7:0];rst_bit  <= 1'b1;endend // Reset states 4'd1: begin // 480us low pulse onewire[lun]     <= 1'b0;onewire_oe[lun]  <= 1'b1;usec_counter     <= usec_count(480);usec_counter_run <= 1'b1;state            <= 4'd2;end4'd2: if (usec_counter_run == 1'b0) begin // 70us pull up onewire_oe[lun]  <= 1'b0;usec_counter     <= usec_count(70);usec_counter_run <= 1'b1;state            <= 4'd3;dat[1]           <= 1'b1;push_done        <= 1'b0;end4'd3: if (usec_counter_run == 1'b0) begin // sample presence, 410us delay if (onewire_i_q == 1'b0) dat[0] <= 1'b1; else dat[0] <= 1'b0;usec_counter     <= usec_count(410);usec_counter_run <= 1'b1;onewire_oe[lun]  <= 1'b0;onewire[lun]     <= 1'b0;state            <= 4'd4;end else if (onewire_i_q && !push_1_opt) dat[1] <= 1'b0;else if (!push_done && onewire_i_q && push_1_opt) begindat[1]            <= 1'b0;onewire_oe[lun]   <= 1'b1;onewire[lun]      <= 1'b1;usec_counter2     <= usec_count(2);usec_counter2_run <= 1'b1;push_done         <= 1'b1;end else if (push_done && usec_counter2_run == 1'b0) beginonewire_oe[lun] <= 1'b0;onewire[lun]    <= 1'b0;end 4'd4: if (usec_counter_run == 1'b0) beginstate   <= 4'd0;rst_bit <= 1'b0;end// Write state machine 4'd5: if (usec_counter_run == 1'b0) begin // Write of 0/1 begins with 6us low (1) or 60us low (0) onewire[lun]    <= 1'b0;onewire_oe[lun] <= 1'b1;if (shiftreg[0]) usec_counter <= usec_count(6);else usec_counter <= usec_count(60);usec_counter_run <= 1'b1;state <= 4'd6;end4'd6: if (usec_counter_run == 1'b0) begin onewire[lun] <= 1'b1;if (shiftreg[0]) usec_counter <= usec_count(64);else usec_counter     <= usec_count(10);usec_counter_run <= 1'b1;shiftreg         <= {onewire_i_q, shiftreg[7:1]}; // right shift b                <= b + 1'b1;if (b == 3'd7) state <= 4'd4; else state <= 4'd5;end// Read state machine 4'd7: beginonewire[lun]     <= 1'b0;onewire_oe[lun]  <= 1'b1;usec_counter     <= usec_count(6);usec_counter_run <= 1'b1;state            <= 4'd8;end4'd8: if (usec_counter_run == 1'b0) beginonewire_oe[lun]  <= 1'b0;usec_counter     <= usec_count(9);usec_counter_run <= 1'b1;push_done        <= 1'b0;state            <= 4'd9;end4'd9: if (usec_counter_run == 1'b0) beginshiftreg         <= {onewire_i_q, shiftreg[7:1]};usec_counter     <= usec_count(55);usec_counter_run <= 1'b1;state            <= 4'd10;onewire_oe[lun]  <= 1'b0;onewire[lun]     <= 1'b0;end else if (!push_done && onewire_i_q && push_1_opt) beginonewire_oe[lun]   <= 1'b1;onewire[lun]      <= 1'b1;usec_counter2     <= usec_count(2);usec_counter2_run <= 1'b1;push_done         <= 1'b1;end else if (push_done && usec_counter2_run == 1'b0) beginonewire_oe[lun] <= 1'b0;onewire[lun] <= 1'b0;end4'd10: if (usec_counter_run == 1'b0) beginb <= b + 1'b1;if (b == 3'd7) begindat[7:0] <= shiftreg;if (read_bytes >= 4'he) read_bytes <= 4'd0;else read_bytes <= read_bytes - 1'b1;rxdone     <= 1'b1;state      <= 4'd0;rst_bit    <= 1'b0;end else state <= 4'd7;endendcaseend
end
endmodule

?六.總結

????????在One-Wire協議中,主機和從機通過DQ線進行通信。主機向DQ線發送時鐘信號,從機根據時鐘信號將數據寫入DQ線。主機讀取DQ線上的電壓變化,從而獲取從機發送的數據。由于DQ線上只有一條信號線,因此需要采用特殊的操作來區分數據位和應答位。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536723.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536723.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536723.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity程序向Web服務器發送數據

Unity程序向Web服務器發送數據 一、介紹二、HTTP協議三、新建Unity工程&#xff0c;創建腳本1.新建Unity工程&#xff0c;創建腳本WebManager.cs&#xff0c;將其指定給場景中的任意游戲體。2.在WebManager.cs中添加一個m_info屬性和OnGUI函數顯示UI&#xff1a; 四、GET請求在…

npm使用詳解(好吧好吧是粗解)

目錄 npm是什么&#xff1f; npm有什么用&#xff1f; npm安裝 在 Windows 上 在 macOS 上 在 Linux 上&#xff08;使用 apt 包管理器為例&#xff09; 驗證 npm 安裝成功&#xff1a; npm使用 1. 初始化項目&#xff1a; 2. 安裝和管理依賴&#xff1a; 3. 查看和…

【DataV】DataV組件庫——更新數據視圖不更新

參考文章&#xff1a;dataV組件庫——改變數據視圖不主動刷新 問題&#xff1a; 拿到后端數值就直接賦值了&#xff0c;但是視圖&#xff08;頁面&#xff09;沒有更新。 解決&#xff1a; 官方文檔介紹dataV里面的組件props均未設置deep監聽&#xff0c;刷新props時&#xf…

一個利用摸魚時間背單詞的軟件

大家好&#xff0c;我是 Java陳序員。 最近進入了考試季&#xff0c;各種考試&#xff0c;英語四六級、考研、期末考等。不知道大家的英語四六級成績怎么樣呢&#xff1f; 記得大學時&#xff0c;英語四級都是靠高中學習積累的老本才勉強過關。 而六級則是考了多次&#xff…

20231224解決outcommit_id.xml1 parser error Document is empty的問題

20231224解決outcommit_id.xml1 parser error Document is empty的問題 2023/12/24 18:13 在開發RK3399的Android10的時候&#xff0c;出現&#xff1a;rootrootrootroot-X99-Turbo:~/3TB/Rockchip_Android10.0_SDK_Release$ make installclean PLATFORM_VERSION_CODENAMEREL…

靜態HTTP的常見問題和解決方法

大家好&#xff0c;歡迎來到今天的“靜態HTTP大講堂”&#xff01;今天我們要聊聊靜態HTTP的常見問題和解決方法。別小看這些問題哦&#xff0c;它們就像是那些頑皮的小妖精&#xff0c;時不時地給你的網站搞點惡作劇。不過別擔心&#xff0c;有我在&#xff0c;這些小妖精都得…

推薦一款好用的免費圖片轉換工具bmp轉png工具bmp2png

推薦一款好用的免費圖片轉換工具bmp轉png工具bmp2png 寫這個工具是因為要使用傳奇的部分素材在COCOS2DX使用&#xff0c;但是COCOS2DX不支持BMP如果直接將BMP轉換到PNG的話&#xff0c;網上找到的工具都不支持透明色轉換。難道要用PS一個一個摳圖嗎&#xff1f;要累死所以寫了…

HBase 超大表遷移、備份、還原、同步演練手冊:全量快照 + 實時同步(Snapshot + Replication)不停機遷移方案

博主歷時三年精心創作的《大數據平臺架構與原型實現:數據中臺建設實戰》一書現已由知名IT圖書品牌電子工業出版社博文視點出版發行,點擊《重磅推薦:建大數據平臺太難了!給我發個工程原型吧!》了解圖書詳情,京東購書鏈接:https://item.jd.com/12677623.html,掃描左側二維…

如何選擇適合業務的負載均衡策略?

在分布式系統的高可用設計中&#xff0c;負載均衡非常關鍵&#xff0c;我們知道&#xff0c;分布式系統的特性之一就是支持快速擴展&#xff0c;那么集群擴展之后&#xff0c;服務請求如何從服務器列表中選擇合適的一臺呢&#xff1f;這就需要依賴負載均衡策略。 負載均衡在處…

免 費 搭 建 小程序商城,打造多商家入駐的b2b2c、o2o、直播帶貨商城

在數字化時代&#xff0c;電商行業正經歷著前所未有的變革。鴻鵠云商的saas云平臺以其獨特的架構和先進的理念&#xff0c;為電商行業帶來了全新的商業模式和營銷策略。該平臺涉及多個平臺端&#xff0c;包括平臺管理、商家端、買家平臺、微服務平臺等&#xff0c;涵蓋了pc端、…

項目執行常用的ChatGPT通用提示詞模板

項目啟動與準備&#xff1a;如何確保項目按計劃啟動&#xff0c;并為項目執行做好充分準備&#xff1f; 任務分配與執行&#xff1a;如何合理分配任務&#xff0c;確保項目團隊成員明確各自的責任和目標&#xff1f; 進度監控與調整&#xff1a;如何實時監控項目進度&#xf…

Python 數據分析 Matplotlib篇 plt.rcParams 字典(第5講)

Python 數據分析 Matplotlib篇 plt.rcParams字典(第5講) ??????? ??博主 侯小啾 感謝您的支持與信賴。?? ?????????????????????????????????????????????????????????????????????????…

17.仿簡道云公式函數實戰-數學函數-ABS

1. ABS函數 ABS 函數可用于返回數字的絕對值 2. 函數用法 ABS(number) 3. 函數示例 如&#xff0c;ABS(-12)和ABS(12)的返回結果均為 12。 4. 代碼實戰 首先我們在function包下創建math包&#xff0c;在math包下創建AbsFunction類&#xff0c;代碼如下&#xff1a; pac…

Python是什么?

Python是一種高級編程語言&#xff0c;具有簡單易學、代碼可讀性強、開發效率高等特點。它采用解釋型執行方式&#xff0c;可以跨平臺運行&#xff0c;并且擁有豐富的第三方庫和框架支持&#xff0c;被廣泛應用于Web開發、數據分析、人工智能等領域。 文章目錄 一、Python的歷…

定位 CPU 高負載 Java 線程

常用命令 # 按照 CPU 使用率排序輸出進程信息 ps -eo pid,ppid,%cpu,%mem,cmd --sort-%cpu# 監控對應 pid 進程下的所有線程按照 CPU 排序 top -Hp "$pid" -o %CPU # jstack 輸出 JVM 堆棧信息 jstack $pid演示事例 查看高負載 Java 進程獲取到對應 pid $ ps -eo …

免費福利馬上截止!深圳的戶外小伙伴別錯過!COSP2024體育展來了

COSP2024戶外博覽會 展會時間&#xff1a;2024年3月14-16日 展會地址&#xff1a;深圳福田會展中心 戶外運動愛好者不可錯過&#xff01; COSP2024戶外博覽會不僅可以逛展 看各種露營裝備、戶外器材 還有各種沙龍、峰會活動 就在明年開年&#xff0c;陽春三月天&#xf…

【辦公技巧】ppt如何加密只能看不能修改?

大家是否想要給PPT文件設置加密&#xff0c;讓ppt文件變為只能查看不能修改的狀態&#xff1f;今天給大家分享給PPT文件設置帶有密碼的只讀模式&#xff08;修改權限&#xff09;。 方法如下&#xff1a; PPT文件之后&#xff0c;將PPT文件進行另存為操作&#xff0c;但是在選…

【反射1】——Java基礎(韓順平講解)

一個需求&#xff0c;引出反射 | 完整的反射使用流程&#xff1a; 在不修改源碼的情況下&#xff0c;來控制程序&#xff0c;也符合設計模式中的opc原則(開閉原則&#xff1a;不修改源碼&#xff0c;擴容功能) 1、創建配置文件&#xff1a;re.properties classfullpathcom.r…

SATA和M.2接口的異同點

SATA和M.2接口是連接存儲設備的兩種常見接口&#xff0c;它們在物理尺寸、傳輸速度、線纜和接頭以及適用設備類型等方面有著顯著的異同點。 物理尺寸 SATA接口通常用于2.5英寸硬盤、3.5英寸硬盤等傳統機械硬盤以及SSD&#xff0c;而M.2接口則是一種較為新型的接口標準&#xff…

裝飾 Web3 項目的用戶交互界面(Web3項目二實戰之四)

用戶交互界面是Web3項目必不可少的,畢竟,Web3項目最終是面向用戶的,所以,Web3項目總得需要一個優美的UI界面,已達到用戶在視覺上精彩盛宴。 誠然,一個Web3項目若到了用戶交互界面,大體上,這個Web3項目也將告一段落了。 沒錯,Web3第二個項目,也將終結于本篇,順勢拉開…