您的位置 首页 知识

FPGA基础知识之IIC协议读写解析

FPGA基础知识之IIC协议读写解析-很多数字传感器、数字控制的芯片(DDS、串行ADC、串行DAC)都是通过IIC总线来和控制器通信的。不过IIC协议仍然是一种慢速的通信方式,标准IIC速率为100kbit/s,快速模式速率为400kbit/s。本文致力于讲述如何用计数器控制和分频时钟控制两种方式完成IIC的读写操作。 IIC协议   IIC协议是一种多机通讯,由SDA数据线和SCL时钟线构成串行总线,所有的IIC设备都可以挂载到总线上,但每个设备都有唯一的设备读地址和设备写地址。在使用IIC作为数字接口的芯片

许多数字传感器、数字操控的芯片(DDS、串行ADC、串行DAC)都是经过IIC总线来和操控器通讯的。不过IIC协议仍然是一种慢速的通讯办法,规范IIC速率为100kbit/s,快速形式速率为400kbit/s。本文致力于叙述怎么用计数器操控和分频时钟操控两种办法完结IIC的读写操作。

IIC协议

IIC协议是一种多机通讯,由SDA数据线和SCL时钟线构成串行总线,一切的IIC设备都能够挂载到总线上,但每个设备都有仅有的设备读地址和设备写地址。在运用IIC作为数字接口的芯片datasheet中都能够看到该设备的设备读/写地址状况,并能够查找到相应的读写时序,以及对速率的要求。下图是一个通用的IIC协议时序:

FPGA根底知识之I%&&&&&%协议读写解析

咱们能够总结出五种IIC协议的时序状况:
  1. 闲暇状况,当SDA和SCL两条信号线都处于高电平时总线处于闲暇状况。
  2. 开端信号,SCL为高电平期间SDA信号线上产生了下降沿标志着的一次数据传输的开端。开端信号应当由主机建议。
  3. 数据传输,在SCL同步操控下SDA串行的传送每一位,因而传送8bits的数据需求8个SCL时钟。SCL为高电平时期SDA电平状况有必要安稳;SCL为低电平期间才答应SDA改动状况。
  4. 应对信号,IIC总线上每传送一个8位字节,第9个脉冲期间便会开释总线,由接纳器宣布一个应对信号,反应有没有成功接纳。
  5. 中止信号,在SCL坚持高电平期间,将SDA信号线开释康复到高电平,标志一次数据传输的完毕,IIC总线也从头回到了闲暇状况。

计数器操控IIC读写

  在“FPGA根底规划(三):UART串口通讯”中现已触摸到了运用计数器操控时序的办法,这个办法在操控IIC通讯时相同有用。一次完好的写入操作如下所示:

  case( i )

  0: // iic Start

  begin

  isOut 《= 1; //SDA端口输出

  if( C1 == 0 ) rSCL 《= 1‘b1;

  else if( C1 == 200 ) rSCL 《= 1’b0; //SCL由高变低

  if( C1 == 0 ) rSDA 《= 1‘b1;

  else if( C1 == 100 ) rSDA 《= 1’b0; //SDA先由高变低

  if( C1 == 250 -1) begin C1 《= 9‘d0; i 《= i + 1’b1; end

  else C1 《= C1 + 1‘b1;

  end

  1: // Write Device Addr

  begin rData 《= {4’b1010, 3‘b000, 1’b0}; i 《= 5‘d7; Go 《= i + 1’b1; end

  2: // Wirte Word Addr

  begin rData 《= Addr_Sig; i 《= 5‘d7; Go 《= i + 1’b1; end

  3: // Write Data

  begin rData 《= WrData; i 《= 5‘d7; Go 《= i + 1’b1; end

  4: //iic Stop

  begin

  isOut 《= 1‘b1;

  if( C1 == 0 ) rSCL 《= 1’b0;

  else if( C1 == 50 ) rSCL 《= 1‘b1; //SCL先由低变高

  if( C1 == 0 ) rSDA 《= 1’b0;

  else if( C1 == 150 ) rSDA 《= 1‘b1; //SDA由低变高

  if( C1 == 250 -1 ) begin C1 《= 9’d0; i 《= i + 1‘b1; end

  else C1 《= C1 + 1’b1;

  end

  5:

  begin isDone 《= 1‘b1; i 《= i + 1’b1; end //写I2C 完毕

  6:

  begin isDone 《= 1‘b0; i 《= 5’d0; end

  7,8,9,10,11,12,13,14: //发送Device Addr/Word Addr/Write Data

  begin

  isOut 《= 1‘b1;

  rSDA 《= rData[14-i]; //高位先发送

  if( C1 == 0 ) rSCL 《= 1’b0;

  else if( C1 == 50 ) rSCL 《= 1‘b1;

  else if( C1 == 150 ) rSCL 《= 1’b0;

  if( C1 == F250K -1 ) begin C1 《= 9‘d0; i 《= i + 1’b1; end

  else C1 《= C1 + 1‘b1;

  end

  15: // waiTIng for acknowledge

  begin

  isOut 《= 1’b0; //SDA端口改为输入

  if( C1 == 100 ) isAck 《= SDA;

  if( C1 == 0 ) rSCL 《= 1‘b0;

  else if( C1 == 50 ) rSCL 《= 1’b1;

  else if( C1 == 150 ) rSCL 《= 1‘b0;

  if( C1 == F250K -1 ) begin C1 《= 9’d0; i 《= i + 1‘b1; end

  else C1 《= C1 + 1’b1;

  end

  16:

  if( isAck != 0 ) i 《= 5‘d0;

  else i 《= Go;

  endcase

  向IIC总线写数据时,需求顺次写入待写入的设备写地址、设备中的写地址和待写入的数据共3个8bits字节数据。i代表总线上不同的状况,经过计数器来操控状况之间的跳转。i为0时宣布开端信号;i为7~14时操控8bits数据的发送;i为1、2、3时分别为设备地址、字节地址和数据,顺次调用7-14完结数据的传输;其他还有中止位、应对位、IIC通讯完结置位等状况。

  从器材中读取数据的办法与此相同,只不过一般都需求先向IIC总线写入待读取的设备地址和器材地址,之后再读数据。读数据全体进程比写数据要费事一点,但只需操控好状况之间跳转的进程即可。

  分频时钟操控IIC读写

  由计数器操控通讯时序的办法长处是很灵敏,简直一切的时序办法都能够用这种办法完结;缺陷便是太费事,需求操控好状况之间的跳转,时序越杂乱运用越费事,其实在“FPGA收集-传输-显现体系(二):根据FPGA的温度收集和以太网传输”中,我对DS18B20的时序操控便是选用计数器操控的办法。DS18B20的时序要求较多,因而其间的状况跳转现已适当杂乱。

  其实在操控IIC这种时钟速率固定的串行协议时,还能够在外部分频或PLL生成一个低频的通讯时钟,用这个时钟来操控数据传输进程。如下所示:

  always@(posedge clock_i2c)

  begin

  if(reset_n==1’b0) begin

  tr_end《=0;

  ack1《=1;

  ack2《=1;

  ack3《=1;

  sclk《=1;

  reg_sdat《=1;

  end

  else

  case(cyc_count)

  0:begin ack1《=1;ack2《=1;tr_end《=0;sclk《=1;reg_sdat《=1;end

  1:reg_sdat《=0; //开端传输

  2:sclk《=0;

  3:reg_sdat《=i2c_data[23];

  4:reg_sdat《=i2c_data[22];

  5:reg_sdat《=i2c_data[21];

  6:reg_sdat《=i2c_data[20];

  7:reg_sdat《=i2c_data[19];

  8:reg_sdat《=i2c_data[18];

  9:reg_sdat《=i2c_data[17];

  10:reg_sdat《=i2c_data[16];

  11:reg_sdat《=1; //应对信号

  12:begin reg_sdat《=i2c_data[15];ack1《=i2c_sdat;end

  13:reg_sdat《=i2c_data[14];

  14:reg_sdat《=i2c_data[13];

  15:reg_sdat《=i2c_data[12];

  16:reg_sdat《=i2c_data[11];

  17:reg_sdat《=i2c_data[10];

  18:reg_sdat《=i2c_data[9];

  19:reg_sdat《=i2c_data[8];

  20:reg_sdat《=1; //应对信号

  21:begin reg_sdat《=i2c_data[7];ack2《=i2c_sdat;end

  22:reg_sdat《=i2c_data[6];

  23:reg_sdat《=i2c_data[5];

  24:reg_sdat《=i2c_data[4];

  25:reg_sdat《=i2c_data[3];

  26:reg_sdat《=i2c_data[2];

  27:reg_sdat《=i2c_data[1];

  28:reg_sdat《=i2c_data[0];

  29:reg_sdat《=1; //应对信号

  30:begin ack3《=i2c_sdat;sclk《=0;reg_sdat《=0;end

  31:sclk《=1;

  32:begin reg_sdat《=1;tr_end《=1;end //IIC传输完毕

  endcase

  能够看到这个always块的灵敏方针为分频后的IIC时钟信号clock_i2c,整个传输进程一望而知。这两种操控时序的办法不只适合于IIC协议,还适合于其它的串行协议。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/341106.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部