Quartus Prime中如何为I2C生成100kbps工作时钟?
问题根因说明
ALTPLL无法输出100kbps时钟是硬件特性限制,不是配置操作问题:DE10-Lite搭载的MAX10系列FPGA的PLL锁相环要求内部VCO工作在600MHz~1300MHz区间,即使配置最大分频系数,最低输出频率也在数MHz级别,根本无法直接输出100kHz级别的低速时钟。你查到的LVDS模式配置方法是面向高速串行接口相位调整设计的,该选项无法激活是因为当前所选器件的速度等级、封装不支持对应LVDS时钟路径,完全没必要在PLL配置上继续耗时间。
另外先纠正一个核心设计错误:标准I2C协议中SCL就是总线同步时钟,100kbps是标准模式I2C的SCL时钟频率,不存在SCL跑50MHz、SDA单独跑100kbps的配置,这种设计完全不符合I2C时序要求,必然通信失败。
可行实现方案
直接用50MHz系统时钟做逻辑分频生成所需时序,不需要调用任何PLL IP核,资源占用极低且配置灵活,完全适配你这个单从机、短帧传输的课程项目场景:
- 100kHz SCL时钟生成:100kHz时钟周期为10us,对应50MHz时钟下共500个系统时钟周期。写一个模500的计数器,计数到249、499时翻转SCL电平,即可得到占空比50%的标准100kHz SCL时钟。
- 核心分频逻辑参考代码:
-- 50MHz输入时钟下生成100kHz SCL signal clk_cnt : integer range 0 to 499 := 0; signal scl_o : std_logic := '1'; process(sys_clk, rst_n) begin if rst_n = '0' then clk_cnt <= 0; scl_o <= '1'; elsif rising_edge(sys_clk) then if clk_cnt = 499 then clk_cnt <= 0; scl_o <= not scl_o; else clk_cnt <= clk_cnt + 1; end if; end if; end process; scl <= scl_o;
- I2C时序逻辑实现:你这个场景只有1个从机、传输数据仅5位(1位读写+4位数值),不需要实现完整I2C的多从机仲裁、时钟拉伸等复杂功能,只要写三态状态机实现基础时序即可:
- 起始条件:SCL为高电平时,SDA从高拉低
- 数据传输:SCL低电平时翻转SDA电平,SCL高电平时保持SDA稳定,按顺序传输从机地址、读写控制位、4位数值,每传完8位等待从机发应答位
- 停止条件:SCL为高电平时,SDA从低拉高
注意:SDA端口要设置为inout双向口,FPGA端输出低电平时拉低总线,输出高阻态时由外部上拉电阻将总线拉高,不要直接用推挽输出高电平,否则会和从机输出冲突。
内容的提问来源于stack exchange,提问作者Lucca Machado
相关产品推荐
相关产品推荐

