RP2040 C SDK clocks时钟源配置使用

RP2040 C SDK clocks时钟源配置使用


  • 🌿RP2040时钟源API函数文档:https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_clocks

  • 🍁RP2040时钟树:
    在这里插入图片描述

系统时钟源可以来自外部时钟输入(external clocks)、 晶体振荡器(XOSC)或者经过晶体振荡器到USB时钟倍频、或者系统倍频、ROSC(环形振荡器)。

  • ✨RP2040系统默认工作频率是125MHz ,最高是133MHz ,应该是可以超频,但是不建议这么做。

📘PLL倍频介绍

从上面的那张图可以看到系统倍频源可以选择USB PLL和System PLL。

• pll_sys - Used to generate up to a 133MHz system clock
• pll_usb - Used to generate a 48MHz USB reference clock

  • 倍频内部转换结构图:
    在这里插入图片描述
    注解:在两个PLLs上,FREF(参考)输入连接到晶体振荡器的XI输入。PLL包含一个VCO,它通过反馈回路(相位频率检测器和环路滤波器)锁定到参考时钟的恒定比率。这可以合成非常高的频率,它可以被后分频器所划分。
  • 🔖PLL的最终输出频率计算公式: FOUTPOSTDIV = (FREF / REFDIV) × FBDIV / (POSTDIV1 × POSTDIV2).
  • 🌿PLL设计时,需要注意以下约束条件来选择PLL参数:
  • 最小参考频率(FREF / REFDIV)是5MHz
  • 振荡器频率(FOUTVCO))必须在750兆赫→1600MHz
  • 反馈分配器(FBDIV)必须在16→320
  • 后分配器POSTDIV1和POSTDIV2必须在1→7
  • 最大输入频率(FREF/REFDIV)VCO频率除以16,由于最小反馈除数
    此外,必须遵守芯片时钟发生器(连接到输出)的最大频率。对于系统PLL,这是133MHz,而对于USB PLL,这是48MHz。
  • 🔖数据手册原文(第229页):
    • Minimum reference frequency (FREF / REFDIV) is 5MHz
    • Oscillator frequency (FOUTVCO) must be in the range 750MHz → 1600MHz
    • Feedback divider (FBDIV) must be in the range 16 → 320
    • The post dividers POSTDIV1 and POSTDIV2 must be in the range 1 → 7
    • Maximum input frequency (FREF / REFDIV) is VCO frequency divided by 16, due to minimum feedback divisor
    Additionally, the maximum frequencies of the chip’s clock generators (attached to FOUTPOSTDIV) must be respected. For the system PLL this is 133MHz, and for the USB PLL, 48MHz.
  • ✨在硬件设计上,选择外部晶体振荡器是,时钟频率参数:5- 15MHz
  • 👉当POSTDIV1和POSTDIV2需要两个不同的值时,最好将较高的值分配给POSTDIV1,以获得较低的功耗。
  • 将12MHz晶体连接到晶体振荡器,这意味着最小可实现和合法的VCO频率是12MHz×63 = 756MHz,最大VCO是12MHz×133 = 1596MHz,所以FBDIV必须保持在63→133范围内。例如,将FBDIV设置为100将合成一个1200MHz的VCO频率。一个POSTDIV1值为6,一个POSTDIV2值为2,将总共除以12,在PLL的最终输出处产生一个干净的100MHz。
  • 📐官方在PICO SDK资料包,中提供了一个换算PLL参数的.py文件:"\Pico SDK v1.5.1\pico-sdk\src\rp2_common\hardware_clocks\scripts\vcocalc.py",输入最终频率,即可获得各PLL参数。
    在这里插入图片描述
  • 🔖其中的PD1对应的是POSTDIV1,PD2对应POSTDIV2
  • 🌿通过vcocalc.py计算获得的参数,软件代码配置函数:
void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2)
  • 📑配置频率方法:

✨调整PLL_SYS时,需要先让系统时钟切换到PLL_USB,不然系统就进入锁死状态(RESUS).


// Change clk_sys to be 48MHz. The simplest way is to take this from PLL_USB
    // which has a source frequency of 48MHz
    clock_configure(clk_sys,
                    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
                    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
                    48 * MHZ,
                    48 * MHZ);
// Turn off PLL sys for good measure
    pll_deinit(pll_sys);
pll_init(pll_sys, 1, 1596 * MHZ, 6, 2);
clock_configure(clk_sys,//设置系统时钟,设置源为PLL_SYS,辅助源为CLK_SYS_AUX,目标频率为133MHz
                    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
                    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
                    133 * MHZ,//辅助源频率
                    133 * MHZ);//目标频率
  • 主时钟源:
    在这里插入图片描述
  • 辅助时钟源
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

📒Resus状态

有可能编写出无意中阻止clk_sys的软件。这通常会导致内核和片上调试器的不可恢复的锁定,从而使用户无法跟踪该问题。为了缓解这种情况,提供了一个自动复苏电路,如果在用户定义的间隔内没有检测到边缘,该电路将clk_sys切换到已知的良好时钟源。已知的良好源是clk_ref,它可以从XOSC、ROSC或外部源驱动。(手册189页)

  • 👉一旦芯片进入Resus状态,则需要按住Boot按键,接入USB口,让芯片进入DFU模式,才能正常通过CMSIS-DAP重新烧写程序。

  • 🌿或者使用下面的函数,直接自动配置:

set_sys_clock_khz(133000, true);

🌟请注意,并非所有时钟频率都是可能的;
Note that not all clock frequencies are possible;
最好是你it is preferred that you
*使用src/rp2_common/hardware_clocks/scripts/vcocalc.py计算参数
*use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters
*用于set_sys_clock_pll
*for use with set_sys_clock_pll

📗clock API有关函数
bool clock_configure (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq)
Configure the specified clock.

void clock_configure_undivided (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq)
Configure the specified clock to use the undividded input source.

void clock_configure_int_divider (clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t int_divider)
Configure the specified clock to use the undividded input source.

void clock_stop (clock_handle_t clock)
Stop the specified clock.

uint32_t clock_get_hz (clock_handle_t clock)
Get the current frequency of the specified clock.

uint32_t frequency_count_khz (uint src)
Measure a clocks frequency using the Frequency counter.

void clock_set_reported_hz (clock_handle_t clock, uint hz)
Set the "current frequency" of the clock as reported by clock_get_hz without actually changing the clock.

void clocks_enable_resus (resus_callback_t resus_callback)
Enable the resus function. Restarts clk_sys if it is accidentally stopped.

void clock_gpio_init_int_frac (uint gpio, uint src, uint32_t div_int, uint8_t div_frac)
Output an optionally divided clock to the specified gpio pin.

static void clock_gpio_init (uint gpio, uint src, float div)
Output an optionally divided clock to the specified gpio pin.

bool clock_configure_gpin (clock_handle_t clock, uint gpio, uint32_t src_freq, uint32_t freq)
Configure a clock to come from a gpio input.
🛠使用时钟配置相关函数,CMakeLists.txt,需要包含hardware_clocks
# Add the standard library to the build
target_link_libraries(RP2040_CLOCK
        pico_stdlib
        hardware_clocks)

📝测试例程

// This code is used to test the clocks of the RP2040 chip.
/*
时钟倍频参数计算:"\Pico SDK v1.5.1\pico-sdk\src\rp2_common\hardware_clocks\scripts\vcocalc.py"
计算方法:vcocalc.py 133

  CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_CLOCK.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_RTC.elf verify reset exit"


 */
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/clocks.h"
#include "hardware/pll.h"
#include "hardware/clocks.h"
#include "hardware/structs/pll.h"
#include "hardware/structs/clocks.h"

#define BUILTIN_LED PICO_DEFAULT_LED_PIN    // LED is on the same pin as the default LED 25

void measure_freqs(void) {
    uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);
    uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);
    uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);
    uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
    uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);
    uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);
    uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);
    uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);

    printf("pll_sys  = %dkHz\n", f_pll_sys);
    printf("pll_usb  = %dkHz\n", f_pll_usb);
    printf("rosc     = %dkHz\n", f_rosc);
    printf("clk_sys  = %dkHz\n", f_clk_sys);
    printf("clk_peri = %dkHz\n", f_clk_peri);
    printf("clk_usb  = %dkHz\n", f_clk_usb);
    printf("clk_adc  = %dkHz\n", f_clk_adc);
    printf("clk_rtc  = %dkHz\n", f_clk_rtc);

    // Can't measure clk_ref / xosc as it is the ref
}

int main()
{
    stdio_init_all();
    sleep_ms(3500);
    printf("RP204 Clock Test\n");
    measure_freqs();
// Change clk_sys to be 48MHz. The simplest way is to take this from PLL_USB
    // which has a source frequency of 48MHz
    clock_configure(clk_sys,
                    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
                    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
                    48 * MHZ,
                    48 * MHZ);                48 * MHZ);

    // Turn off PLL sys for good measure
    pll_deinit(pll_sys);
 pll_init(pll_sys, 1, 1596 * MHZ, 6, 2);

    clock_configure(clk_sys,//设置系统时钟,设置源为PLL_SYS,辅助源为CLK_SYS_AUX,目标频率为133MHz
                    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
                    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
                    133 * MHZ,//辅助源频率
                    133 * MHZ);//目标频率

    // clock_configure(clk_peri,
    //                 0,
    //                 CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
    //                 125 * MHZ,
    //                 125 * MHZ);
     //set_sys_clock_khz(124000, true); // 346us
  //set_sys_clock_khz(126000, true); // 340us
  //set_sys_clock_khz(128000, true); // 335us
  //set_sys_clock_khz(130000, true); // 330us
  //set_sys_clock_khz(131000, true); // 328us
   // set_sys_clock_khz(133000, true);// 325us

    // GPIO initialisation.
    // We will make this GPIO an input, and pull it up by default
    gpio_init(BUILTIN_LED);
    gpio_set_dir(BUILTIN_LED, 1);
    gpio_pull_up(BUILTIN_LED);

    while(true){

     sleep_ms(1000);
    gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
    measure_freqs();
     __asm volatile ("nop\n");
    }
    return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/874326.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

程序员如何写笔记并整理资料?

整理笔记 word。没错&#xff0c;我也看了网上一大堆软件&#xff0c;还有git管理等等。个人认为如果笔记只是记录个人的经验积累&#xff0c;一个word就够了&#xff0c;那些notepad&#xff0c;laTex个人觉得不够简练。word。 1.word可以插入任何文件附件(目前最大的word 20…

9.9(QT Day 2)

将day1做的登录界面升级优化【资源文件的添加】 在登录界面的登录取消按钮进行以下设置&#xff1a; 使用手动连接&#xff0c;将登录框中的取消按钮使用第2种方式的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt4版本的连接到自定义…

面试题复习(0902-0909)

1. 完全背包问题 和01背包唯一的区别是&#xff0c;每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09; 代码和01唯一的区别在于j的循环是从小到大&#xff0c;不是从大到小。ij谁在外谁在内层区别不大。 #include <bits/stdc.h> using namespace std…

国产化数据库挑战及发展趋势

非国产数据库如Oracle、MySQL和MSSQL等在某些领域占据重要地位&#xff0c;但国产数据库的市场份额正在逐步提升&#xff0c;特别是在政策支持和市场需求的双重推动下&#xff0c;国产数据库的替代进程正在加速。 一、国产数据库市场规模 2024年中国数据库市场规模预计为543.1亿…

【树和二叉树的相关定义】概念

1.回顾与概览 2.什么是树型结构 3.树的&#xff08;递归&#xff09;定义与基本术语 3.1树的定义 注意&#xff1a;除了根结点以外&#xff0c;任何一个结点都有且仅有一个前驱 3.2树的其他表示方式 3.3树的基本术语 结点&#xff1a;数据元素以及指向子树的分支根结点:非空…

AI基础 L16 Logic Agents I

What is an Agent? • The main point about agents is they are autonomous: capable of acting independently, exhibiting control over their internal state • Thus: an agent is a computer system capable of autonomous action in some environment in order to mee…

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端&#xff0c;一般来说需要版本检测和自动更新功能&#xff0c;这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤&#xff1a; 读取本地应用版本拉取远程版本并比较两个版本如果需要升级&…

手机TF卡格式化后数据恢复:方法、挑战与预防措施

在现代生活中&#xff0c;‌手机已经成为我们不可或缺的一部分&#xff0c;‌而TF卡&#xff08;‌即MicroSD卡&#xff09;‌作为手机存储的扩展&#xff0c;‌更是承载了我们大量的重要数据。‌然而&#xff0c;‌不慎的格式化操作往往导致数据丢失&#xff0c;‌给用户带来不…

【重学 MySQL】五、MySQL 的卸载

【重学 MySQL】五、MySQL 的卸载 停止MySQL服务卸载MySQL程序删除残余文件清理注册表删除环境变量配置重启电脑 MySQL的卸载过程需要仔细操作&#xff0c;以确保彻底卸载并清理所有相关文件和配置。 停止MySQL服务 打开任务管理器&#xff1a;右键点击任务栏空白处&#xff0…

C++笔记---list

1. list的介绍 list其实就是就是我们所熟知的链表&#xff08;双向循环带头结点&#xff09;&#xff0c;但其是作为STL中的一个类模板而存在。 也就是说&#xff0c;list是可以用来存储任意类型数据的顺序表&#xff0c;既可以是内置类型&#xff0c;也可以是自定义类型&…

单词排序C++实现

代码如下&#xff1a; #include<iostream> #include<string> #include<fstream> #include<map> #include<iomanip> #include<algorithm> #include<vector>int read_file(std::map<std::string,int> &map_words) {std::st…

大牛直播SDK最经典的一句

搜索引擎搜大牛直播SDK&#xff0c;居然提示我搜“大牛直播SDK最经典的一句”&#xff0c;闲来无事&#xff0c;点开看看&#xff0c;AI智能问答&#xff0c;给出了答案&#xff1a; ‌大牛直播SDK最经典的一句是&#xff1a;"我们只做最擅长的部分,我们不做的,提供对接接…

[进阶]面向对象之多态(二)

文章目录 多态调用成员的特点多态的优势和弊端 多态调用成员的特点 变量调用:编译看左边,运行也看左边方法调用:编译看左边,运行看右边 多态的优势和弊端 优势&#xff1a; 在多态形式下&#xff0c;右边对象可以实现解耦合&#xff0c;便于扩展和维护定义方法的时候&…

mysql高级sql

文章目录 一&#xff0c;查询1.按关键字排序1.1按关键字排序操作(1)按分数排序查询&#xff08;不加asc默认为升序&#xff09;(2)按分数降序查询&#xff08;DESC&#xff09;(3)使用where进行条件查询(4)使用ORDER BY语句对多个字段排序 1.2使用区间判断查询&#xff08;and/…

ESP32 TCP通信交换数据Mixly Arduino编程

TCP通信交换数据 在ESP32与ESP32或其它局域网络内主机间传输数据时&#xff0c;TCP是很方便的&#xff0c;特别当我们连接互联网后ESPnow不能用&#xff0c;MQTT又不稳定发送大量的数据&#xff0c;同时蓝牙有其它用途时&#xff0c;那么学会TCP通信协议就变得十分重要。 一、…

【开源分享】vsomeip 安装、编译、运行步骤笔记

文章目录 1. 摘要2. 安装、编译2.1 开发环境说明2.2 安装依赖2.3 获取代码2.4 编译代码2.5 安装 3. 测试验证参考 1. 摘要 本文主要描述 vsomeip 的安装、编译与运行步骤。下载源码&#xff0c;安装必要依赖&#xff0c;如Boost和CMake。通过CMake配置编译 vsomeip 库&#xf…

2024年10款好用的图纸加密软件推荐|企业图纸的守护神

在数字化时代&#xff0c;图纸数据的安全性是企业不可忽视的重要任务。随着技术的不断进步&#xff0c;图纸加密软件成为了保护企业知识产权和敏感数据的关键工具。以下是2024年推荐的10款好用的图纸加密软件&#xff0c;它们各具特色&#xff0c;能够满足不同企业的需求。 1.…

Java数组的定义及遍历

数组的声明 长度不能超过定义的长度。超过则会报错通过下标来访问 数组的遍历 最常用最简单的方法是增强for循环。

【解决bug之路】npm install node-sass(^4.14.1)连环报错解决!!!(Windows)

有关node-sass的深入分析可参考&#xff1a;又报gyp ERR&#xff01;为什么有那么多人被node-sass 坑过&#xff1f; 主要有如下三方面错误&#xff0c;请自查&#xff1a; 1.node&#xff0c;npm版本需与node-sass版本匹配&#xff0c;像node-sass&#xff08;^4.14.1&#x…

第三部分:4---进程地址空间

目录 数组的空间分配解析&#xff1a; 物理地址和虚拟地址&#xff1a; 虚拟地址空间&#xff1a; 进程地址空间的本质&#xff1a; 为什么要有进程地址空间&#xff1f; 页表对进程访问内存的检查&#xff1a; 进程地址空间和页表如何关联起来&#xff1f; 进程的独立…