最新免费av在线观看,亚洲综合一区成人在线,中文字幕精品无码一区二区三区,中文人妻av高清一区二区,中文字幕乱偷无码av先锋

iic通信協(xié)議是什么

出處:網絡整理 發(fā)布于:2024-04-30 17:15:26

  I2C(Inter-Integrated Circuit)是一種串行通信協(xié)議,用于在集成電路之間進行通信。它是由飛利浦(現在的恩智浦半導體)開發(fā)的,并廣泛應用于各種電子設備和系統(tǒng)中。I2C通信協(xié)議具有以下特點:
  雙線制: I2C協(xié)議使用兩根線進行通信,即數據線(SDA)和時鐘線(SCL)。
  主從結構: 在I2C通信中,通常存在一個主設備(Master)和一個或多個從設備(Slave)。主設備負責發(fā)起通信和控制總線,而從設備則被動響應主設備的指令。
  地址機制: 每個從設備都有一個的7位地址,用于主設備識別和選擇特定的從設備進行通信。
  同步傳輸: 通信是同步的,由時鐘線(SCL)上的時鐘信號來驅動數據傳輸。
  起始和停止條件: 通信的起始和停止由主設備發(fā)出的特殊條件來標識,即起始條件(Start)和停止條件(Stop)。

  數據傳輸: 數據傳輸通過數據線(SDA)進行,在時鐘信號的控制下,每個數據字節(jié)都由8位數據和一個確認位(ACK)組成。

  1.開始信號——在SCLK的高電平器件,拉低SDA的信號(由1 變?yōu)?)。
  2.控制字節(jié)——即器件地址,就是你操作那一塊EEPROM。
  3.ACK信號——由從機發(fā)出,主機為接收,所以在此階段,sda_link必須置為0,即為讀取這個應答信號,所以在SCLK的高點平期間。
  4.字節(jié)地址——即某一塊EEPROM里面的哪一個地址。
  5.ACK信號——與上述相同。
  6.數據信號——即你往某個地址里面寫入的8位數據。
  7.ACK信號——上述相同。
  8.結束信號——在SCLK的高電平期間,拉高SDA信號,表示通信結束。
  再來看讀的時序:
  由上圖可看出讀時序的前面處理方式與寫相同,不同的時在第三個ACK信號來了之后,如果是讀,那么會又有一個起始信號,緊接著讀器件地址,然后應答,再然后讀數據,再然后在SCLK的低電平期間發(fā)送一個NO ACK信號,要記住這個信號由主機發(fā)出,然后緊接著一個結束信號。
  由上述讀寫時序我們可知,通信的起始均在SCLK的高電平期間發(fā)生跳變,這就據定了我們其他信號跳變均在SCLK的下降沿,SCLK高電平期間數據穩(wěn)定,適用于讀(即低電平改變數據,高電平采集數據)。
  具體過程如下:
  首先板子上電來個初始化需要來個延時,具體多少用計數器自己搞定。
  代碼如下:
  reg [6:0] hadware_initial_delay;
  wire hadware_initial_delay_done;
  always@(posedge clk or negedge rst_n)
  if(!rst_n)
  hadware_initial_delay《=7’d0;
  else
  if(hadware_initial_delay《=7’d49)
  hadware_initial_delay《=hadware_initial_delay+1;else
  hadware_initial_delay《=hadware_initial_delay;assign hadware_initial_delay_done=(hadware_initial_delay==7’d50)?1’b1:1’b0;OK,我們要知道IIC的速率一般就幾百KH而我們的系統(tǒng)時鐘為50M,所以需要分頻:
  代碼如下:
  reg [8:0] sclk_cnt;
  always@(posedge clk or negedge rst_n)
  if(!rst_n)
  sclk_cnt《=9’d0;
  else
  if(hadware_initial_delay_done)
  begin
  if(sclk_cnt《9’d499)
  sclk_cnt《=sclk_cnt+1;
  else
  sclk_cnt《=0;
  end
  assign sclk=(sclk_cnt《=9’d249)?1’b1:1’b0;OK,我們知道SCLK高電平期間采集數據,低電平期間改變數據,那么當然,這個“期間”肯定時時鐘沿中間啦,畢竟更容易滿足建立時間與保持時間,很穩(wěn)定的。
  具體代碼如下:
  wire sclk_posedge_middle=(sclk_cnt==9’d124)?1’b1:1’b0;wire sclk_negedge_middle=(sclk_cnt==9’d374)?1’b1:1’b0;OK,讀寫定義了那么多個過程,當然需要狀態(tài)機來搞定啦,定義變量如下:
  parameter IDLE = 4’d0 ;
  parameter START1 = 4’d1 ;
  parameter ADD1 = 4’d2 ;
  parameter ACK1 = 4’d3 ;
  parameter ADD2 = 4’d4 ;
  parameter ACK2 = 4’d5 ;
  parameter DATA = 4’d6 ;
  parameter ACK3 = 4’d7 ;
  parameter STOP1 = 4’d8 ;
  parameter START2 = 4’d9 ;
  parameter ADD3 = 4’d10;
  parameter ACK4 = 4’d11;
  parameter DATA_READ = 4’d12;
  parameter NO_ACK = 4’d13;
  parameter STOP2 = 4’d14;
  OK,再來個宏定義,假設寫入是這幾個地址,這幾個數據。
  define DEVICE_READ 8‘b1010_0001
  define DEVICE_WRITE 8’b1010_0000
  define WRITE_DATA 8’b0001_0001
  define BYTE_ADDR 8’b0000_0011
  SDA雙向端口,這個記住,一般這樣搞;
  reg sda_link;
  reg sda_out_r;
  assign sda=sda_link?sda_out_r:1’bz;
  當作為輸出時,對吧,使sda_link拉高,作為輸入時,輸入高阻。
  各過程如下:
  reg [3:0] current_state;
  //reg [3:0] next_state;
  reg [7:0] db_r;
  reg [3:0] num;
  reg [7:0] data_out_reg;
  always@(posedge clk or negedge rst_n)
  if(!rst_n)
  begin
  sda_link《=0;
  db_r《=0;
  num《=0;
  current_state《=IDLE;
  sda_out_r《=0;
  data_out_reg《=8’b0;
  end
  else
  begin
  case(current_state)
  IDLE:begin
  sda_out_r《=1;
  sda_link《=1;
  if(!sw1_r||!sw2_r)
  current_state《=START1;
  else
  current_state《=IDLE;
  end
  START1:if(sclk_posedge_middle)
  begin
  sda_out_r《=0;
  db_r《=`DEVICE_WRITE;
  current_state《=ADD1;
  end
  else
  current_state《=START1;
  ADD1 :
  if(sclk_negedge_middle)
  begin
  if(num==4‘d8)
  begin
  sda_link《=0;
  num《=0;
  current_state《=ACK1;
  sda_out_r《=1;
  end
  else
  begin
  current_state《=ADD1;
  sda_out_r《=db_r[7-num];
  num《=num+1;
  end
  end
  else
  current_state《=ADD1;
  ACK1:
  if(sclk_posedge_middle)
  // begin
  // if(!sda)
  // begin
  begin // */current_state《=ADD2;
  db_r《=`BYTE_ADDR;
  end
  else
  current_state《=ACK1;
  ADD2:begin
  sda_link《=1;
  if(sclk_negedge_middle)begin
  if(num==4’d8)
  begin
  sda_link《=0;
  current_state《=ACK2;
  num《=4‘d0;
  sda_out_r《=1;
  end
  else
  begin
  num《=num+1;
  current_state《=ADD2;
  sda_out_r《=db_r[7-num];
  end
  end
  else
  current_state《=ADD2;
  end
  ACK2:
  if(sclk_posedge_middle)
  ////begin
  //if(!sda)
  begin
  begin
  if(!sw1_r)
  begin
  db_r《=`WRITE_DATA;
  current_state《=DATA;
  end
  else
  if(!sw2_r)
  begin
  current_state《=START2;
  sda_out_r《=1;
  end
  end
  else
  current_state《=ACK2;
  DATA: begin
  sda_link《=1;
  if(sclk_negedge_middle)
  begin
  if(num==4’d8)
  begin
  num《=4‘d0;
  current_state《=ACK3;
  sda_out_r《=1;
  sda_link《=0;
  end
  else
  begin
  num《=num+1;
  current_state《=DATA;
  sda_out_r《=db_r[7-num];
  end
  end
  else
  current_state《=DATA;
  end
  ACK3: if(sclk_posedge_middle)
  // begin
  // if(!sda)
  current_state《=STOP1;
  // end
  STOP1:
  begin
  sda_link《=1;
  sda_out_r《=0;
  if(sclk_posedge_middle)
  begin
  sda_out_r《=1;
  if(sw1_r)
  // 你要是不等它松開才恢復初始狀態(tài),那么你一旦恢復初始狀態(tài)SW1_r就為低電平,他又開始寫了,所以為了避免重復寫入數據。
  current_state《=IDLE;
  else
  current_state《=STOP1;
  end
  else
  current_state《=STOP1;
  end
  START2:begin
  sda_link《=1;
  if(sclk_posedge_middle)
  begin
  sda_out_r《=0;
  sda_link《=1;
  db_r《=`DEVICE_READ;
  current_state《=ADD3 ;
  end
  end
  ADD3: begin
  if(sclk_negedge_middle)
  begin
  if(num==4’d8)
  begin
  num《=0;
  sda_link《=0;
  sda_out_r《=1;
  current_state《=ACK4;
  end
  else
  begin
  num《=num+1;
  sda_out_r《=db_r[7-num];
  current_state《=ADD3;
  end
  end
  else
  current_state《=ADD3;
  end
  ACK4:
  if(sclk_posedge_middle)
  // begin
  // if(!sda)
  current_state《=DATA_READ;
  else
  current_state《=ACK4;
  // end
  DATA_READ:
  begin
  sda_link《=0;
  if(sclk_posedge_middle)
  begin
  if(num==4‘d8)
  begin
  sda_link《=1;
  sda_out_r《=1;
  current_state《=NO_ACK;
  num《=4’d0;
  end
  else
  begin
  num《=num+1;
  current_state《=DATA_READ;
  data_out_reg[7-num]《=sda;
  end
  end
  end
  NO_ACK:
  if(sclk_negedge_middle)
  begin
  sda_out_r《=1;
  current_state《=STOP2;
  end
  else
  current_state《=NO_ACK;
  STOP2:begin
  sda_out_r《=0;
  sda_link《=1;
  if(sclk_posedge_middle)
  begin
  sda_out_r《=1;
  current_state《=IDLE;
  end
  else
  current_state《=STOP2;
  end
  default:current_state《=IDLE;
  endcase
  end
  assign data_out=data_out_reg;
  endmodule
  仿真結果如下:

關鍵詞:通信

版權與免責聲明

凡本網注明“出處:維庫電子市場網”的所有作品,版權均屬于維庫電子市場網,轉載請必須注明維庫電子市場網,http://udpf.com.cn,違反者本網將追究相關法律責任。

本網轉載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網贊同其觀點或證實其內容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網站或個人從本網轉載時,必須保留本網注明的作品出處,并自負版權等法律責任。

如涉及作品內容、版權等問題,請在作品發(fā)表之日起一周內與本網聯系,否則視為放棄相關權利。

OEM清單文件: OEM清單文件
*公司名:
*聯系人:
*手機號碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務:
賣家服務:
技術客服:

0571-85317607

網站技術支持

13606545031

客服在線時間周一至周五
9:00-17:30

關注官方微信號,
第一時間獲取資訊。

建議反饋

聯系人:

聯系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務的動力!意見一經采納,將有感恩紅包奉上哦!