Menu Close

I2C 主设备分频器设计

为了适应不同的速率,如100K,400K,1M,3.4M的收发速度,同时又能适应不同的系统时钟频率,因此需要采用配置寄存器以及参数化设计相配合,做到适用性广,方便集成到CPU,DSP,HDMI 等智能器件及接口中。该部分内容与UART的波特率发生器的设计非常类似,可以参照该部分内容进行设计与理解,后面附有I2C时钟代码。

1.I2C 的时钟频率分频器设计

I2C有四种速度匹配,分别为100K,400K,1M,3.4M四种,由于是同步时钟,从机的位捕获直接使用主机时钟,因此这一点与UART等类型的异步通信有较大区别。首先I2C的从设备速度等级表示从机的在速度方面的解码能力,如速度为100K,是指0-100K的速度范围内都可以运行(这一点与SMbus不同)。其次从机直接使用主机时钟,因此从机对时钟的精确度要求不高,如主机设置100K,实际运行时由于时钟晶振误差,分频系数不准确(非整数倍分频)等带来的误差影响不大。

  • 设计要求
    • 参数化设计,假设时钟为可以提供133MHz,100MHz,50MHz,25MHz四种,速度满足3.4M,1M,400K, 100K。
    • 可编程,虽然参数化设计解决了大部分问题,但依然无法满足众多IC的匹配的需求,如某MCU的主时钟66MHz,或80MHz等,这些都不在上面提供的参数化范围之内。因此提供一套可编程接口接波特率寄存器,可以由应用程序计算分频系数并写入分频寄存器中。还有参数化的设计一旦设计综合成硬件之后便不能修改,可编程接口提供好了在线修改的可能。
    • 输出为SCL(I2C时钟)两倍频的系统主时钟脉冲信号。如图2,用于在其它模块中生成SCL时钟。

 

图1

  • 设计代码:


 

上面的程序分为两个部分,第一部分为写分频寄存器,在复位状态下由参数传递提供默认值(DIV_COE),在没有写信号的情况下div_f_r将会一直保持该值。在地址选通,写使能wr_en的驱动下将由应用程序提供的div_in的值写入到分频寄存器div_f_r中。并为后面的分频计数程序产生复位信号rst_r。rst_r的作用防止计数器count_r在计数的某个值后,突然写入一个比count_r小的值,使得计数32位计数器不能及时回归(当然也可以用if(count_r>=div_f_r)替代if(count_r==div_f_r)实现)。


 

第二部分程序提供分频的作用,在分频寄存器的值被修改时,分频程序复位,计数器从0开始计数。clk_en将作为时钟使能使用,每个SCL周期对应两个clk_en时钟脉冲。clk_en_half 作为辅助时钟脉冲, 主要是处理I2C START,STOP, 以及主控制发送数据使能等。 每个SCL对应4个clk_en_half 时钟脉冲。


 

由于分频程序是整体I2C程序实现的一个部分,因此由I2C_engine.v程序实现组装,后续课程将会详细介绍I2C_engine的原理。

2. 测试程序:

本测试程序为了体现测试的通用性,尽量模拟应用程序在时钟频率,通信速率等方面的需求进行多样化测试,在tb_clk_en.v中设置了4种频率,4种速率。通过延时提供了各种频率和速率组合进行测试,同时应注意时钟切换时的异步时钟域的处理。在MCU,DSP等嵌入式处理中,该部分程序可由软件实现。


 

仿真波形如下:

图2

从图2中可以看出,写入不同的分频系数值,clk_en的输出的频率随之变化,也可以追踪到SCL_en.v内部观察rst_r,计数,分频系数的写入等,由于上面已做了较详细的分析,这里不再累述。

 

Posted in FPGA, FPGA 教材教案, Quartus II, Quartus II, Verilog, 教材与教案, 文章, 编程语言