当前位置:   article > 正文

基于FPGA的IIC总线协议的实现(代码精简)_基于 fpga 的 i2c 通信协议设计与实现

基于 fpga 的 i2c 通信协议设计与实现

I2C(Inter-Integrated Circuit)中文名称“集成电路总线”,是一种串行同步半双工总线。

I2C总线是由Philips公司开发的一种简单,双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传达信息,一根是数据线(SDA),一根是时钟线(SCL)。

I2C总线可实现多主机,多从机之间的互联,具有低功耗,抗干扰,电源电压范围宽,工作温度范围广的特点。其通讯速率为:标准模式0-100kbit/s,快速模式0-400kbit/s,和高速模式0-3.4Mbit/s。可连接很多设备,总电容在400pF。

I2C结构:1,  设备之间互联只需要两根线(SDA,SCL)

         2,  I2C总线支持任何IC生产过程(NMOS  CMOS双极性)

         3,  SDA双向数据线

         4,  SCL双向时钟线

         5,  每个设备有且只有一个设备地址

         6,  设备分为主机(master)和从机,主机允许输出时钟信号

         7,  主机发送信号时,发送时钟和数据,当主机发送结束后,数据线高阻,主机继续发送时钟,从机发送数据给主机

 

I2C硬件连接:1, I2C只使用两条漏极开路(Open Drain)SDA及SCL并利用电阻将电平上拉。

                     2, VDD通常为+5V或者是+3.3V

                     3, 逻辑0 = 低电平

                     4, 逻辑1 = 高点平

 

 

I2C总线协议:

写格式:1,主机发start位

              2,主机发从机地址和写命令

              3,从机回ack

              4,主机发寄存器地址

              5,从机回ack

             6,主机发数据

             7,从机回ack

             8,主机发stop位

 

 

 

读格式:1,主机发atart位                                    

              2,主机发从机地址和写命令

              3,从机回ack

              4,主机发寄存器地址

              5,从机回ack

              6,主机发restart位

              7,主机发从机地址和读命令

              8,从机回ack

              9,从机回数据

            10,主机发nack

            11,主机发stop位

 

 

I2C驱动模块:

  1. `define IIC_FREQ100K 500 //频率100k
  2. `define IIC_FREQ400K 125 //频率400k
  3. module i2c_driver #(
  4. parameter IIC_CNTMAX = `IIC_FREQ100K
  5. )
  6. (
  7. input clk,
  8. input rst_n,
  9. input wire [1:0] cmd, //2'b00-无操作 2'b01-写操作 2'b10-读操作
  10. input wire [6:0] device_addr, //从机地址
  11. input wire [7:0] reg_addr, //寄存器地址
  12. input wire [7:0] wr_data, //写入的数据
  13. output reg [7:0] rd_data, //读出的数据
  14. output reg done, //结束脉冲
  15. output reg err, //报错信号
  16. output reg scl, //时钟线
  17. inout sda //数据线
  18. );
  19. reg sda_sel;
  20. reg sda_reg;
  21. assign sda = sda_sel ? sda_reg : 1'bz;
  22. localparam IIC_CNTMAX_4_1 = IIC_CNTMAX/4-1,
  23. IIC_CNTMAX_4_2 = IIC_CNTMAX/2-1,
  24. IIC_CNTMAX_4_3 = (IIC_CNTMAX/4)*3-1,
  25. IIC_CNTMAX_4_4 = IIC_CNTMAX-1;
  26. reg [25:0] cnt; //时钟计数器
  27. reg [25:0] delay_cnt; //延迟计数器
  28. reg ack; //寄存一个从机回的ack信号
  29. reg [7:0] data_reg; //定义一个八位的数据寄存器
  30. reg [3:0] num; //定义个计数num
  31. reg [3:0] state;
  32. reg [3:0] back_state;
  33. localparam FSM_START = 0, //主机发start
  34. FSM_DEVICE_ADDR_WR_RD = 1, //主机发从机地址和写命令
  35. FSM_ACK = 2, //从机回ack
  36. FSM_WR_REG_ADDR = 3, //主机发寄存器地址
  37. FSM_WR_DATA = 4, //主机发数据
  38. FSM_RESTART = 5, //主机发restart位
  39. FSM_RD_DATA = 6, //从机回数据
  40. FSM_NACK = 7, //主机发nack
  41. FSM_STOP = 8, //主机发stop
  42. FSM_DELAY = 9; //延迟20us
  43. reg [1:0] scl_state; //定义个时钟线状态
  44. always @(posedge clk or negedge rst_n)
  45. if (!rst_n)
  46. cnt <= 0;
  47. else if (state == FSM_DELAY)
  48. cnt <= 0;
  49. else if (cmd == 2'b01 || cmd == 2'b10)
  50. begin
  51. if (cnt == IIC_CNTMAX_4_4)
  52. cnt <= 0;
  53. else cnt <= cnt + 1;
  54. end
  55. else cnt <= 0;
  56. always @(posedge clk or negedge rst_n)
  57. if (!rst_n)
  58. begin
  59. scl <= 1;
  60. scl_state <= 0;
  61. end
  62. else if (cmd == 2'b01 || cmd == 2'b10)
  63. case (scl_state)
  64. 0 : if (cnt == 0)
  65. scl <= 1;
  66. else if (cnt == IIC_CNTMAX_4_3)
  67. scl <= 0;
  68. else if (cnt == IIC_CNTMAX_4_4)
  69. scl_state <= 1;
  70. else scl_state <= 0;
  71. 1 : if ((back_state == FSM_STOP && state == FSM_ACK && cnt == IIC_CNTMAX_4_4) || (state == FSM_NACK && cnt == IIC_CNTMAX_4_4))
  72. scl_state <= 2;
  73. else if (cnt == 0)
  74. scl <= 0;
  75. else if (cnt == IIC_CNTMAX_4_1)
  76. scl <= 1;
  77. else if (cnt == IIC_CNTMAX_4_3)
  78. scl <= 0;
  79. else scl_state <= 1;
  80. 2 : if (cnt == 0)
  81. scl <= 0;
  82. else if (cnt == IIC_CNTMAX_4_1)
  83. scl <= 1;
  84. else if (cnt == IIC_CNTMAX_4_4)
  85. scl_state <= 3;
  86. else scl_state <= 2;
  87. 3 : if (delay_cnt == 999)
  88. scl_state <= 0;
  89. else scl_state <= 3;
  90. default : begin scl <= 1; scl_state <= 0; end
  91. endcase
  92. else begin
  93. scl <= 1;
  94. scl_state <= 0;
  95. end
  96. always @(posedge clk or negedge rst_n)
  97. if (!rst_n)
  98. begin
  99. state <= FSM_START;
  100. back_state <= 0;
  101. rd_data <= 0;
  102. done <= 0;
  103. sda_sel <= 1;
  104. sda_reg <= 1;
  105. delay_cnt <= 0;
  106. ack <= 1;
  107. data_reg <= 0;
  108. num <= 0;
  109. err <= 0;
  110. end
  111. else if (cmd == 2'b01 || cmd == 2'b10)
  112. case (state)
  113. FSM_START : begin
  114. done <= 0;
  115. sda_sel <= 1;
  116. data_reg <= {device_addr,1'b0};
  117. back_state <= FSM_WR_REG_ADDR;
  118. if (cnt == 0)
  119. sda_reg <= 1;
  120. else if (cnt == IIC_CNTMAX_4_2)
  121. sda_reg <= 0;
  122. if (cnt == IIC_CNTMAX_4_4)
  123. state <= FSM_DEVICE_ADDR_WR_RD;
  124. else state <= FSM_START;
  125. end
  126. FSM_DEVICE_ADDR_WR_RD : begin
  127. sda_sel <= 1;
  128. if (cnt == 0)
  129. sda_reg <= data_reg[7-num];
  130. if (cnt == IIC_CNTMAX_4_4 && num == 7)
  131. begin
  132. num <= 0;
  133. state <= FSM_ACK;
  134. end
  135. else if (cnt == IIC_CNTMAX_4_4)
  136. num <= num + 1;
  137. else state <= FSM_DEVICE_ADDR_WR_RD;
  138. end
  139. FSM_ACK : begin
  140. sda_sel <= 0;
  141. sda_reg <= 1;
  142. if (cnt == IIC_CNTMAX_4_2)
  143. ack <= sda;
  144. if (cnt == IIC_CNTMAX_4_4)
  145. state <= back_state;
  146. else state <= FSM_ACK;
  147. end
  148. FSM_WR_REG_ADDR : begin
  149. if (!ack)
  150. begin
  151. sda_sel <= 1;
  152. if (cmd == 2'b01)
  153. back_state <= FSM_WR_DATA;
  154. else if (cmd == 2'b10)
  155. back_state <= FSM_RESTART;
  156. if (cnt == 0)
  157. sda_reg <= reg_addr[7-num];
  158. if (cnt == IIC_CNTMAX_4_4 && num == 7)
  159. begin
  160. num <= 0;
  161. state <= FSM_ACK;
  162. end
  163. else if (cnt == IIC_CNTMAX_4_4)
  164. num <= num + 1;
  165. else state <= FSM_WR_REG_ADDR;
  166. end
  167. else begin
  168. err <= 1;
  169. state <= FSM_START;
  170. end
  171. end
  172. FSM_WR_DATA : begin
  173. if (!ack)
  174. begin
  175. sda_sel <= 1;
  176. back_state <= FSM_STOP;
  177. if (cnt == 0)
  178. sda_reg <= wr_data[7-num];
  179. if (cnt == IIC_CNTMAX_4_4 && num == 7)
  180. begin
  181. num <= 0;
  182. state <= FSM_ACK;
  183. end
  184. else if (cnt == IIC_CNTMAX_4_4)
  185. num <= num + 1;
  186. else state <= FSM_WR_DATA;
  187. end
  188. else begin
  189. err <= 1;
  190. state <= FSM_START;
  191. end
  192. end
  193. FSM_RESTART : begin
  194. if (!ack)
  195. begin
  196. sda_sel <= 1;
  197. data_reg <= {device_addr,1'b1};
  198. back_state <= FSM_RD_DATA;
  199. if (cnt == 0)
  200. sda_reg <= 1;
  201. else if (cnt == IIC_CNTMAX_4_2)
  202. sda_reg <= 0;
  203. if (cnt == IIC_CNTMAX_4_4)
  204. state <= FSM_DEVICE_ADDR_WR_RD;
  205. else state <= FSM_RESTART;
  206. end
  207. else begin
  208. err <= 1;
  209. state <= FSM_START;
  210. end
  211. end
  212. FSM_RD_DATA : begin
  213. if (!ack)
  214. begin
  215. sda_sel <= 0;
  216. if (cnt == IIC_CNTMAX_4_2)
  217. rd_data[7-num] <= sda;
  218. if (cnt == IIC_CNTMAX_4_4 && num == 7)
  219. begin
  220. num <= 0;
  221. state <= FSM_NACK;
  222. end
  223. else if (cnt == IIC_CNTMAX_4_4)
  224. num <= num + 1;
  225. else state <= FSM_RD_DATA;
  226. end
  227. else begin
  228. err <= 1;
  229. state <= FSM_START;
  230. end
  231. end
  232. FSM_NACK : begin
  233. sda_sel <= 1;
  234. sda_reg <= 1;
  235. if (cnt == IIC_CNTMAX_4_4)
  236. state <= FSM_STOP;
  237. else state <= FSM_NACK;
  238. end
  239. FSM_STOP : begin
  240. sda_sel <= 1;
  241. if (cnt == 0)
  242. sda_reg <= 0;
  243. else if (cnt == IIC_CNTMAX_4_2)
  244. sda_reg <= 1;
  245. if (cnt == IIC_CNTMAX_4_4)
  246. state <= FSM_DELAY;
  247. else state <= FSM_STOP;
  248. end
  249. FSM_DELAY : if (delay_cnt == 999) //延迟20us
  250. begin
  251. delay_cnt <= 0;
  252. done <= 1;
  253. state <= FSM_START;
  254. end
  255. else delay_cnt <= delay_cnt + 1;
  256. default : state <= FSM_START;
  257. endcase
  258. else
  259. begin
  260. state <= FSM_START;
  261. back_state <= 0;
  262. rd_data <= rd_data;
  263. done <= 0;
  264. sda_sel <= 1;
  265. sda_reg <= 1;
  266. delay_cnt <= 0;
  267. ack <= 1;
  268. data_reg <= 0;
  269. num <= 0;
  270. err <= 0;
  271. end
  272. endmodule

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号