日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          新聞中心

          EEPW首頁 > 嵌入式系統 > 設計應用 > 基于Verilog HDL的I2C總線功能的實現

          基于Verilog HDL的I2C總線功能的實現

          作者: 時間:2017-06-05 來源:網絡 收藏

          開發(fā)FPGA時,利用EDA工具設計芯片實現系統功能已經成為支撐電子設計的通用平臺,并逐步向支持系統級的設計方向發(fā)展。在軟件設計過程中,越來越強調模塊化設計。總線是Philips公司推出的雙向兩線串行通訊標準,具有接口線少?通訊效率高等特點。把總線設計成相應的模塊,有利于相關FPGA的開發(fā)。目前有一些介紹相關開發(fā)的資料[1],但都是利用VHDL語言或AHDL語言實現的。本文給出利用 HDL語言設計的總線模塊。

          本文引用地址:http://yuyingmama.com.cn/article/201706/349158.htm

          1 I2C總線概述

          I2C總線系統由兩根總線即SCL(串行時鐘)線和SDA(串行數據)線構成。這種總線可以設計成很多種通訊配置,但本文只討論主從系統的應用。主器件控制總線通訊,開始/結束傳送?發(fā)送信息并產生I2C系統時鐘。在寫操作過程中,從器件一旦被主控器件尋址,就執(zhí)行特定的相應功能。在讀操作過程中,主控器件從從器件那里獲得數據。在整個主從傳送過程中,所有的事件都通過主控器件的SCL時鐘線達到同步。連到總線上的器件的接口形式必須是漏極開路或集電極開路輸出狀態(tài)。通過上拉電阻,使得兩根總線在空閑的狀態(tài)下都為高電平狀態(tài)。因此I2C總線上具有線與功能,即總線上的所有器件都達到高電平狀態(tài)時,I2C總線才能達到高電平狀態(tài),從而使總線上的高速器件和慢速器件工作同步。

          在I2C協議中,從器件地址是一個唯一的7位地址。接下來是一個讀寫方向標志位,讀狀態(tài)是高電平?寫狀態(tài)是低電平。

          2 I2C模塊的設計與實現

          根據I2C協議中傳輸過程的特點,I2C模塊可以劃分為字節(jié)發(fā)送模塊、字節(jié)接收模塊、開始條件模塊、停止條件模塊。其中,字節(jié)發(fā)送模塊、字節(jié)接收模塊和停止條件模塊為基本模塊。在開始條件模塊中,因為需要發(fā)送從器件地址,所以要調用字節(jié)發(fā)送模塊。

          下面給出用 HDL語言[3]實現字節(jié)發(fā)送模塊的關鍵程序。相關變量的聲明在此略去。程序在Max+PlusII環(huán)境下編譯?調試?仿真。

          assign en_sdao=tempen_sdao; //設置SDA三態(tài)輸出使能

          assign send_byte_over=tempsend_byte_over;

          assign NO_ACK=tempNO_ACK;

          assign sdao=tempsda;

          assign sclo=tempscl;

          always@(posedge send_byte_clk)

          begin

          case(send_byte_zt)

          sendbit1:

          begin

          if(send_byte_num==0)

          begin

          shiftdata[7:0]=indata[7:0];

          end

          shiftdata=shiftdata 1;

          tempsda=shiftdata[8];

          tempscl=1; //置SCL為高電平

          send_byte_zt= delay_1;

          send_byte_num=send_byte_num+1;

          end

          delay_1: //延時三個周期

          begin

          if(delay_counter>=2)

          begin

          send_byte_zt = sendbit2;

          delay_counter=0;

          end

          else

          begin

          delay_counter=delay_counter+1;

          send_byte_zt = send_byte_zt;

          end

          end

          sendbit2:

          begin

          tempscl=0; //SCL置零

          send_byte_zt = delay_2;

          end

          delay_2: //延時三個周期

          begin

          if(delay_counter>=2)

          begin

          send_byte_zt = sendbit3;

          delay_counter=0;

          end

          else

          begin

          delay_counter=delay_counter+1;

          send_byte_zt = send_byte_zt;

          end

          end

          sendbit3: //判斷是否字節(jié)中所有位都發(fā)送完畢

          begin

          if(send_byte_num=8)

          begin

          send_byte_zt=sendbit1;

          end

          else

          begin

          send_byte_zt=ForACK1;

          send_byte_num=0;

          end

          end

          ForACK1:

          begin

          tempsda=1; //釋放數據線,等待應答信號

          send_byte_zt=delay_ACK;

          end

          delay_ACK: //延時

          begin

          if(delay_counter>=3)

          begin

          send_byte_zt = ForACK2;

          delay_counter=0;

          end

          else

          begin

          delay_counter=delay_counter+1;

          send_byte_zt = send_byte_zt;

          tempscl=1;

          end

          end

          ForACK2:

          begin

          send_byte_zt=AckYESNO;

          tempen_sdao=0; //輸出SDA使能信號,控制sdao和sdai

          end

          AckYESNO:

          begin

          if(sdai) //如果應答信號sdai為1,NO_ACK置1

          begin

          tempNO_ACK=1; //設置未應答標志信號

          end

          tempscl=0; //終止應答位

          send_byte_zt=Finish_delay;

          end

          Finish_delay: //延時

          begin

          if(delay_counter>=2)

          begin

          tempsend_byte_over=1;

          send_byte_zt = FinishACK1;

          delay_counter=0;

          end

          else

          begin

          delay_counter=delay_counter+1;

          send_byte_zt = send_byte_zt;

          end

          end

          FinishACK1:

          begin

          send_byte_zt=sendbit1;

          send_byte_num=0;

          end

          default:

          begin

          send_byte_zt=sendbit1;

          send_byte_num=0;

          end

          endcase

          end

          程序中sdao、sclo為輸出信號,sdai為應答信號,en_sdao是對sdao和sdai進行切換的信號。I2C總線具有SDA和SCL兩根信號線,所以在整個模塊設計中,把sdao/sclo和sdai/scli作為兩組信號。當需要向外部SDA信號線上輸出信息時,sdao連到SDA信號線上;當需要從外部SDA信號線上讀入信息時,置sdao成高阻態(tài),sdai連到SDA信號線上。en_sdao信號作為這一過程的切換信號。在程序中定義了一些狀態(tài)信號:NO_ACK、send_byte_over。其中,NO_ACK信號判斷從器件是否對發(fā)送的信號給予了應答。send_byte_over信號判斷字節(jié)是否傳輸完畢。這些信號可以傳遞給上一層設計模塊,以控制程序的流程。為了使I2C總線能夠有效地通訊,必須考慮信號的建立和保持時間,所以程序中設置了相應的延時部分。另外,在以clk為觸發(fā)信號的過程模塊中,定義send_byte_clk信號為時鐘信號的兩倍頻信號,并加入字節(jié)發(fā)送模塊使能信號start_send_byte控制模塊工作,由于篇幅所限,略去該過程模塊。

          字節(jié)發(fā)送模塊的仿真測試結果如圖1所示。

          根據I2C總線標準,利用 HDL很容易實現字節(jié)接收模塊?開始條件模塊?停止條件模塊這三個模塊。圖2是數據發(fā)送過程的仿真測試結果。從器件的7位地址為101011,向從器件發(fā)送的數據為00010111。aensclo和aensdao分別是sclo/scli和sdao/sdai的切換信號。

          圖3是數據接收過程的仿真測試結果。從器件的7位地址為0011001,從器件發(fā)送的數據為11111111。ensclo和ensdao分別是sclo/scli和sdao/sdai的切換信號。

          將圖2和圖3所模擬的I2C總線時序與I2C總線協議中相關要求進行比較,滿足I2C總線的時序要求。

          對各個模塊進行多層次處理,形成I2C總線模塊。

          以該I2C總線模塊為基礎,編寫FPGA與AT24C01A(ATMEL公司生產的E2PROM)的通訊程序。然后把相關程序下載到EPF10K10LC84-3中,與AT24C01A進行實際通訊實驗,效果良好。



          關鍵詞: Verilog I2C 仿真時序

          評論


          相關推薦

          技術專區(qū)

          關閉