《電子技術應用》
您所在的位置:首頁 > 可編程邏輯 > 其他 > 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;郵箱:aet@chinaaet.com。
主站蜘蛛池模板: 国产亚洲精品美女久久久久| 夜来香免费观看视频在线| 国产在线视频一区二区三区| 97视频免费观看2区| 女律师的堕落高清hd| 中国一级特黄高清免费的大片中国一级黄色片 | 色猫咪av在线网址| 女大学生的沙龙室| 中文字幕日韩一区二区三区不| 日韩免费观看的一级毛片| 亚洲一级免费视频| 欧美成人免费观看的| 亚洲精品国产啊女成拍色拍| 男女免费观看在线爽爽爽视频 | 欧美白人最猛性xxxxx| 亚洲美女视频网站| 男人插女人免费| 免费无码午夜福利片69| 精品无人区一区二区三区a| 国产精品100页| 一区二区三区欧美在线| 成年男人的天堂| 久久一区二区三区精品| 日本爱恋电影在线观看视频| 久久精品无码专区免费| 澳门特级毛片免费观看| 免费一级肉体全黄毛片| 精品伊人久久香线蕉| 午夜无码伦费影视在线观看| 美女张开腿让男人桶| 四虎成人免费影院网址| 色哟哟www网站| 国产永久免费观看的黄网站| 伊人色综合久久天天人守人婷 | 亚洲精品伊人久久久久| 激情欧美日韩一区二区| 人妖系列精品视频在线观看| 狠狠色噜噜狠狠狠狠av| 亚洲黄色激情视频| 爱搞网在线观看| 亚洲精品第一国产综合精品|