• LibOpenCM3(五) 基础功能: 系统时钟, GPIO, 定时器


    目录

    LibOpenCM3 时钟, RCC

    LibOpenCM3 提供了快捷方法用于初始化系统时钟

    旧版本的系统时脉初始化

    rcc_clock_setup_in_hse_8mhz_out_72mhz();
    

    方法所在文件lib/stm32/f1/rcc.c, 对应板载晶振为8MHz, 需要设置为72MHz系统频率的应用. 这个文件下还提供了其它的快捷方法

    // 使用内部RC产生64MHz
    void rcc_clock_setup_in_hsi_out_64mhz(void)
    // 使用内部RC产生48MHz
    void rcc_clock_setup_in_hsi_out_48mhz(void)
    // 使用内部RC产生24MHz
    void rcc_clock_setup_in_hsi_out_24mhz(void)
    // 以下是使用外部晶振的方法
    void rcc_clock_setup_in_hse_8mhz_out_24mhz(void)
    void rcc_clock_setup_in_hse_8mhz_out_72mhz(void)
    void rcc_clock_setup_in_hse_12mhz_out_72mhz(void)
    void rcc_clock_setup_in_hse_16mhz_out_72mhz(void)
    void rcc_clock_setup_in_hse_25mhz_out_72mhz(void)
    

    使用时直接调用就可以了, 例如

    int main(void)
    {
        rcc_clock_setup_in_hse_8mhz_out_72mhz();
        gpio_setup();
        tim_setup();
        while (1)
        {
          //...
        }
        return 0;
    }
    

    非常方便

    新版本的系统时脉初始化

    在最新的版本中, 原来的方法还能调用, 但是已经被标为Deprecated了, 编译会产生warning提示. 需要改为下面的调用方式

    rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);
    

    定义的文件位置没变, 对应的频率放到了参数里

    enum rcc_clock_hsi {
    	RCC_CLOCK_HSI_24MHZ,
    	RCC_CLOCK_HSI_48MHZ,
    	RCC_CLOCK_HSI_64MHZ,
    	RCC_CLOCK_HSI_END
    };
    
    enum rcc_clock_hse {
    	RCC_CLOCK_HSE12_72MHZ,
    	RCC_CLOCK_HSE16_72MHZ,
    	RCC_CLOCK_HSE25_72MHZ,
    	RCC_CLOCK_HSE8_24MHZ,
    	RCC_CLOCK_HSE8_72MHZ,
    	RCC_CLOCK_HSE_END
    };
    

    LibOpenCM3 GPIO

    GPIO的设置与SPL/HAL流程是一样的, 只是函数名和常量名有些区别.

    开启GPIO外设时钟

    rcc_periph_clock_enable(RCC_GPIOC);
    

    设置GPIO模式

    gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
    gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO9);
    // 可以简化为
    gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8 | GPIO9);
    

    输入输出模式选项

    • GPIO_MODE_INPUT (default) Digital input
    • GPIO_MODE_OUTPUT Digital output
    • GPIO_MODE_AF Alternate Function (requires defining which alternate function desired)
    • GPIO_MODE_ANALOG Analog (for use with ADC or DAC capable GPIO)

    上下拉电阻选项

    • GPIO_PUPD_NONE (default) No internal pull-up or pull-down resistor
    • GPIO_PUPD_PULLUP Internal pull-up resistor
    • GPIO_PUPD_PULLDOWN Internal pull-down resistor

    输出模式设置

    gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO8);
    gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO9);
    // 可以简化为
    gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO8 | GPIO9);
    

    输出类型

    • GPIO_OTYPER_PP (default) Push-pull “totem pole” output
    • GPIO_OTYPER_OD Open-drain output

    输出速度

    • GPIO_OSPEED_HIGH High output speed
    • GPIO_OSPEED_MED Medium output speed
    • GPIO_OSPEED_LOW (default) Low output speed
    • GPIO_OSPEED_100MHZ Up to 100MHz output speed (equivalent to high)
    • GPIO_OSPEED_50MHZ Up to 50MHz output speed
    • GPIO_OSPEED_25MHZ Up to 25MHz output speed (equivalent to medium)
    • GPIO_OSPEED_2MHZ Up to 2MHz output speed (equivalent to low)

    设置状态

    GPIO 没有开启或者关闭的操作, 开启时钟后GPIO就处于工作状态, 这时候可以设置输出电平

    gpio_set(GPIOC, GPIO8);
    gpio_set(GPIOC, GPIO9);
    // 可以简化为
    gpio_set(GPIOC, GPIO8 | GPIO9);
    

    LibOpenCM3 定时器

    不同MCU型号, 能使用的定时器编号不一样, 需要根据手册确定, 下面以TIM2为例说明定时器的设置流程

    开启TIM2外设时钟

    开启TIM2时钟

    /* Enable TIM2 clock. */
    rcc_periph_clock_enable(RCC_TIM2);
    

    如果需要初始化(重置)

    /* Reset TIM2 peripheral to defaults. */
    rcc_periph_reset_pulse(RST_TIM2);
    

    设置定时器工作模式

    timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
    

    参数一: 分频系数

    /* CKD[1:0]: Clock division */
    #define TIM_CR1_CKD_CK_INT		(0x0 << 8)
    #define TIM_CR1_CKD_CK_INT_MUL_2	(0x1 << 8)
    #define TIM_CR1_CKD_CK_INT_MUL_4	(0x2 << 8)
    #define TIM_CR1_CKD_CK_INT_MASK		(0x3 << 8)
    

    参数二: 对齐方式

    /* CMS[1:0]: Center-aligned mode selection */
    /****************************************************************************/
    /** @defgroup tim_x_cr1_cms TIMx_CR1 CMS[1:0]: Center-aligned Mode Selection
    @{*/
    #define TIM_CR1_CMS_EDGE		(0x0 << 5)
    #define TIM_CR1_CMS_CENTER_1		(0x1 << 5)
    #define TIM_CR1_CMS_CENTER_2		(0x2 << 5)
    #define TIM_CR1_CMS_CENTER_3		(0x3 << 5)
    #define TIM_CR1_CMS_MASK		(0x3 << 5)
    

    参数三: 计数方向

    /* DIR: Direction */
    /****************************************************************************/
    /** @defgroup tim_x_cr1_dir TIMx_CR1 DIR: Direction
    @{*/
    #define TIM_CR1_DIR_UP			(0 << 4)
    #define TIM_CR1_DIR_DOWN		(1 << 4)
    

    设置定时系数

    // 禁用 preload
    timer_disable_preload(TIM2);
    // 循环模式
    timer_continuous_mode(TIM2);
    // 预分频系数, 根据当前所在总线计算分频后的周期
    timer_set_prescaler(TIM2, 36000);
    // 计数周期
    timer_set_period(TIM2, 1000);
    

    如果要设置中断

    /* Enable TIM2 interrupt. */
    nvic_enable_irq(NVIC_TIM2_IRQ);
    /* Enable Channel 1 compare interrupt to recalculate compare values */
    timer_enable_irq(TIM2, TIM_DIER_CC1IE);
    

    启用(使能)TIM2

    /* Counter enable. */
    timer_enable_counter(TIM2);
    

    完整例子

    使用GPIO和定时器外设的例子, 参考 LibOpenCM3(一) Linux下命令行开发环境配置 中的演示示例

  • 相关阅读:
    JAVA基础(JAVA SE)学习笔记(九)异常处理
    【RocketMQ】MQ消息发送
    js中 数组的操作 push(),pop(),shift(),unshift() 简介
    Python数据攻略-Pandas与地理空间数据分析
    KVC原理与数据筛选
    C++多线程编程(第四章 promise和future)
    苍穹外卖—解决前端时间属性显示问题
    java计算机毕业设计流浪狗领养系统源码+系统+mysql数据库+lw文档+部署
    分布式/微服务---第五篇
    Unity的UI面板基类
  • 原文地址:https://www.cnblogs.com/milton/p/15931145.html