《電子技術應用》
您所在的位置:首頁 > 可編程邏輯 > 其他 > FPGA教學——FPGA實現IIC協議

FPGA教學——FPGA實現IIC協議

2022-08-23
作者: 電擊小子
來源: 電子技術應用專欄作家 FPGA之旅
關鍵詞: FPGA IIC協議

  一. 簡介

  這是FPGA之旅設計的第五例啦!今天給大家帶來的是IIC通信,IIC協議應用非常廣泛,例如與MPU6050進行通信,配置OV5640攝像頭、驅動OLED屏幕等等,都需要使用到IIC協議,所以掌握它是非常必要的,廢話不多說,接著往下看。文末獲取完整代碼。

  二. IIC簡介

  IIC協議分為主機和從機,所有的請求都是由主機發出,從機進行響應,從機是沒有辦法對主機進行讀或寫的。IIC協議共有兩根線,數據線SDA和時鐘線SCL,兩根線就可以完成所有的通信請求,簡直是太給力了。

  三. IIC協議

  終于到了IIC協議的部分。IIC協議簡單來說,共有五種狀態,這五種狀態的有序組合就組成了完整的IIC通信,學習IIC協議,就是學習這五種狀態。

  空閑態:  SCL 和 SDA 都為高電平,不進行通信的時候。

  起始態:在SCL為高電平的時候,將SDA拉低,主機通知從機,開始進行通信。

  數據傳輸態:數據傳輸態,又可以分為讀和寫兩個部分,過程都是一樣的,就合在一起了,都是在SCL為低電平的時候,SDA將數據發送,在SCL為高電平的時候,將數據接收。

  (非)應答態:數據傳輸態完成后,必須接一個應答態或者非應答態,為了確定對方接收到了數據。在SCL為高電平的時候,檢測到SDA為低電平,則為應答,否則為非應答。

  停止態:一次數據傳輸完成,由主機發起,在SCL為高電平的時候,SDA由低電平變成高電平。

  了解了這五種狀態后,接下來就要學習如何使用這五種狀態來進行讀寫操作了。

  (一)  IIC寫操作

  下面就是一個完整的寫操作,共包含三次數據傳輸態,第一次發送的是從機地址 + 0,第二次發送的是寄存器的地址,第三次寫的是數據,寫入寄存器中的數據。從機地址一般為7bit,與另外一bit共同組成8bit,0表示寫,1表示讀。

  微信截圖_20220823161653.png  

  (二)IIC讀操作

  讀操作要比寫操作復雜一點,需要的狀態多一些。一共有五個數據傳輸態,狀態圖如下了。

  微信截圖_20220823161712.png

  上面的流程圖都是對從機的地址為7位以及從機的寄存器地址為8位的操作。

  四. Verilog代碼實現

  有了上面的各個狀態中,SDA和SCL的變換關系,以及讀寫的序列,就可以很方便的來寫程序啦。

  1. 首先,當然離不開狀態機,根據上面敘述的五種狀態,編寫狀態機,狀態機中,將數據傳輸態分成了讀和寫兩種狀態。有了各個狀態,操作SDA和SCL兩根線不是易如反掌嘛!

  /*IIC 狀態*/

  localparam IIC_IDLE       =   6'b000_001;  /*空閑態*/

  localparam IIC_START      =   6'b000_010;  /*起始態*/

  localparam IIC_WRDATA     =   6'b000_100;  /*寫數據態*/

  localparam IIC_RDDATA     =   6'b001_000;  /*讀數據態*/

  localparam IIC_ACK        =   6'b010_000;  /*應答態*/

  localparam IIC_STOP       =   6'b100_000;  /*停止態*/

  2. 狀態機的跳轉條件如下,跳轉條件和上面敘述的一樣。單獨看這個有點難懂,有些變量不明白其具體含義,可以結和仿真圖形和完整代碼進行理解。

  /*狀態機*/

  always @(*)

  begin

  case(state)

  IIC_IDLE:

  if(IICWriteReq == 1'b1 || IICReadReq == 1'b1)

  next_state <= IIC_START;

  else

  next_state <= IIC_IDLE;

  IIC_START:

  if(IICCnt == (IIC_Pre * 'd2))

  next_state <= IIC_WRDATA;

  else

  next_state <= IIC_START;

  IIC_WRDATA:

  if(IICBitCnt == 'd8 && IICCnt == IIC_Pre /4 && iicCLK == 1'b0)

  next_state <= IIC_ACK;

  else

  next_state <= IIC_WRDATA;

  IIC_RDDATA:

  if(IICBitCnt == 'd8 && IICCnt == IIC_Pre /4 && iicCLK == 1'b0)

  next_state <= IIC_ACK;

  else

  next_state <= IIC_RDDATA;

  IIC_ACK:

  if(IICACKStopCnt == 'd1 && IICCnt == IIC_Pre /4 && iicCLK == 1'b0)

  if(IICSendBytes == 'd3)

  if(IICWriteReq == 1'b1)         /*三個字節發送完成,進入停止態*/

  next_state <= IIC_STOP;

  else

  next_state <= IIC_RDDATA;

  else if(IICSendBytes == 'd2 && IICReadReq == 1'b1)

  next_state <= IIC_START;

  else if(IICSendBytes == 'd4)

  next_state <= IIC_STOP;

  else

  next_state <= IIC_WRDATA;

  else

  next_state <= IIC_ACK;

  IIC_STOP:

  if(IICACKStopCnt == 'd1 && IICCnt == IIC_Pre/4 && iicCLK == 1'b1)

  next_state <= IIC_IDLE;

  else

  next_state <= IIC_STOP;

  default:  next_state <= IIC_IDLE;

  endcase

  end

  各個部分實現的詳細代碼,就不列舉出來啦,代碼總計280多行,也不算多。通過本IIC模塊,可以驅動OV5640攝像頭,MPU6050模塊和0.96寸OLED屏幕等等,后續會基于此模塊,來驅動這些外設。

  五. testbeach編寫

  還是按照流程走,編寫完模塊后,進行一下仿真,還真有錯誤,幸虧仿真了,哈哈哈。

  `timescale 1ns/1ps

  module testbench();

  reg  clk;

  reg  rst;

  wire  SDA;

  wire  SCL;

  reg IICWriteReq;

  reg IICReadReq;

  wire IICWriteDone;

  wire IICReadDone;

  always # 50 clk = ~clk;

  initial begin

  clk = 1'b1;

  rst = 1'b1;

  IICWriteReq = 1'b0;

  IICReadReq = 1'b1;

  #100   /*手動復位*/

  rst = 1'b0;

  #100

  rst = 1'b1;

  end

  always@(posedge clk)

  if(IICReadDone == 1'b1)   /*讀完成后,readReq為0,只進行一次讀寫操作*/

  IICReadReq <= 1'b0;

  else

  IICReadReq <= IICReadReq;

  IIC_Driver  IIC_DriverHP(

  .sys_clk            (clk),           /*系統時鐘*/

  .rst_n              (rst),             /*系統復位*/

  .IICSCL             (SCL),            /*IIC 時鐘輸出*/

  .IICSDA             (SDA),             /*IIC 數據線*/

  .IICSlave           ('h1234),

  .IICWriteReq        (IICWriteReq),       /*IIC寫寄存器請求*/

  .IICWriteDone        (IICWriteDone),      /*IIC寫寄存器完成*/

  .IICWriteData        ('h5a), /*IIC發送數據 8bit的從機地址 + 8bit的寄存器地址 + 8bit的數據(讀忽略,后默認為0)*/

  .IICReadReq         (IICReadReq),        /*IIC讀寄存器請求*/

  .IICReadDone        (IICReadDone),       /*IIC讀寄存器完成*/

  .IICReadData        ()/*IIC讀取數據*/

  );

  endmodule

  需要完整代碼的可以關注微信公眾號 FPGA之旅 回復 :FPGA之旅設計99例之第五例


更多信息可以來這里獲取==>>電子技術應用-AET<<

微信圖片_20210517164139.jpg


微信截圖_20220708161426.png

電子技術應用專欄作家  FPGA之旅

原文鏈接:https://mp.weixin.qq.com/s/3qwZRqjHEZzj4V8uMo0T4g

本站內容除特別聲明的原創文章之外,轉載內容只為傳遞更多信息,并不代表本網站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創文章及圖片等內容無法一一聯系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經濟損失。聯系電話:010-82306118;郵箱:[email protected]
主站蜘蛛池模板: 视频精品一区二区三区 | 久久亚洲国产午夜精品理论片 | 国产一区二区三区成人久久片 | 日本一级做人免费视频 | 免费一级成人免费观看 | 步兵精品手机在线观看 | 欧美一级毛片免费看视频 | 一级全免费视频播放 | 国产视频97| 精品成人毛片一区二区视 | 久久香蕉精品成人 | 深夜福利视频网站 | 色碰碰 | 91热成人精品国产免费 | 久久久久久91精品色婷婷 | 亚洲欧洲eeea在线观看 | 美国毛片aa | 国内精品久久久久影院不卡 | 91成人网 | 在线中文字幕亚洲 | 精品自拍视频在线观看 | 亚洲国产剧情在线精品视 | 日韩特黄毛片 | 一区二区三区中文国产亚洲 | 国产午夜小视频 | 97久久免费视频 | 天堂8中文在线 | 一级毛片免费不卡在线 | 99爱在线精品视频网站 | 91亚洲精品国产第一区 | 在线成人免费视频 | a级成人毛片免费视频高清 a级高清观看视频在线看 | 99久久精品免费看国产免费软件 | 美女做爰视频在线观看免费 | 精品视频免费在线观看 | 色综合久久久久久久 | 午夜在线亚洲 | 亚洲成人福利 | 怡红院免费全部视频在线视频 | 男人又粗又硬桶女人免费 | 欧美成视频无需播放器 |