当前位置: 首页 > article >正文

沁恒CH32V307使用记录:使用TIM输出PWM信号

文章目录

  • 目的
  • 基础说明
  • 使用例程
  • 总结

目的

使用TIM输出PWM信号是单片机中比较常用的一个功能。这篇文章将对CH32V307中相关内容进行说明。

本文使用沁恒官方的开发板 (CH32V307-EVT-R1沁恒RISC-V模块MCU赤兔评估板) 进行演示。

基础说明

CH32V307拥有多个定时器,只有通用定时器和高级定时器支持PWM输出功能,需要注意的是不同的定时器默认可用时钟源是不同的:
在这里插入图片描述

使用TIM输出PWM信号总的来说操作上分为下面几个部分:

  • 初始化TIM和输出PWM信号的GPIO口的时钟;
  • 配置输出PWM信号的GPIO口为复用输出模式;
  • 配置TIM基本定时参数;
  • 配置PWM输出的通道与参数;

沁恒官方提供了库函数用于操作TIM,主要是 ch32v30x_tim.hch32v30x_tim.c 两个文件,前者中声明了提供给用户调用的函数以及相关的枚举和宏定义类型等。

使用TIM输出PWM信号使用中涉及的原理可以参考下面文章中的基础说明部分:
《使用HAL库开发STM32:Timer基础说明与定时功能使用》
《使用HAL库开发STM32:使用Timer输出PWM信号》

使用例程

CH32V307官方的PWM例程中使用的是TIM1,我这里使用TIM4进行演示,两者使用方式基本上是差不多的,下面是测试代码:

#include "debug.h"

// 初始化GPIO、TIM、PWM,使用见下面main函数
void TIM4_PWMOut_Init(u16 psc, u16 arr, u16 ccp) {
    // 初始化时钟
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM4, ENABLE);

    // 初始化 TIM4_CH1引脚 (PB6)
    GPIO_InitTypeDef GPIO_InitStructure = { 0 };
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOB, &GPIO_InitStructure);

    // 初始化 TIM4
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = { 0 };
    TIM_TimeBaseInitStructure.TIM_Period = arr;         // 计数周期(以TIM时钟分频后的时钟最为计数源)
                                                        // 该值为9表示计数10次为一个周期,49表示计数50次为一个周期,依此类推
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;      // 分频系数(对TIM时钟进行分频)
                                                        // 该值为0表示不分频,1表示2分频,2表示3分频,依此类推
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit( TIM4, &TIM_TimeBaseInitStructure);

    TIM_ARRPreloadConfig( TIM4, ENABLE);                // 使能arr预装载,如果需要TIM启用的情况下修改计数周期,那么通常使能预装载会比较安全

    // 初始化 TIM4_CH1 PWM
    TIM_OCInitTypeDef TIM_OCInitStructure = { 0 };
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = ccp;                // 比较参数,计数值与该值比较,来改变PWM通道输出电平
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init( TIM4, &TIM_OCInitStructure);

    // TIM_CtrlPWMOutputs(TIM4, ENABLE);                // 高级定时器需要将这个使能才能输出PWM

    TIM_OC1PreloadConfig( TIM4, TIM_OCPreload_Disable); // 使能ccr1预装载,如果需要PWM启用的情况下修改比较参数,那么通常使能预装载会比较安全


    TIM_Cmd( TIM4, ENABLE);                             // 使能定时器
}

int main(void) {
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
    printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID());
    TIM4_PWMOut_Init(96 - 1, 1000 - 1, 800);            // 默认配置下时钟为96MHz,对时钟源96分频,即TIM计数时钟为1MHz
                                                        // 计数周期设置为1000,结合上条每次计数为1ms,相当于频率为1000Hz
                                                        // 根据比较模式和PWM模式设置,以及上面的参数设置,这里输出的PWM信号的占空比为80%

    while(1) {
        Delay_Ms(2500);
        TIM_SetCompare1( TIM4, 500);                    // 修改CCR1的值,此处修改后ARR为1000 - 1, 频率为1kHz,CCR1为500,占空比为50%
        Delay_Ms(2500);
        TIM_SetCompare1( TIM4, 200);                    // 修改CCR1的值,此处修改后ARR为1000 - 1,频率为1kHz, CCR1为200,占空比为20%
        Delay_Ms(2500);
        TIM_SetAutoreload( TIM4, 300 - 1);              // 修改ARR的值,此处修改后ARR为300 - 1, 频率为3.33kHz,CCR1为200,占空比为66.67%
        Delay_Ms(2500);
        TIM_SetAutoreload( TIM4, 1000 - 1);             // ARR设置为初始值
        TIM_SetCompare1( TIM4, 800);                    // CCR1设置为初始值
    }
}

上面代码演示如下,注意观察示波器波形下面的 频率、周期和占空比 :
在这里插入图片描述

总结

使用TIM输出PWM信号操作比较简单,只要了解相关原理基本上就能立马上手使用。


http://www.kler.cn/a/2071.html

相关文章:

  • 【WPS安装】WPS编译错误总结:WPS编译失败+仅编译成功ungrib等
  • 任务三数据库加固
  • 数据结构_平衡二叉树
  • ChatGPT与领域特定语言的集成
  • 【集合】Java 8 - Stream API 17种常用操作与案例详解
  • 如何使用 WebAssembly 扩展后端应用
  • C++笔记——第六篇 list的简介和使用
  • 多线程 (六) 单例模式
  • 蓝桥杯备赛经验 pythonA组(非科班选手)
  • 拯救会议纪要!快用这三个音频转文字方法,让领导对你刮目相看
  • FLEXPART拉格朗日粒子扩散模式建模技术及研究大气污染物源-汇关系中的实践经验
  • 【Java】i++和++i的实现原理
  • 函数(上)——“Python”
  • 金三银四Java面试题及答案整理(2023最新版) 持续更新
  • 知识点16--k8s资源配置清单入门
  • 使用sqlalchemy-gbasedbt连接GBase 8s数据库
  • 使用旧电脑玩Linux
  • spring2
  • CSDN 周赛38期题解
  • 【性能分析】分析JVM出现的内存泄漏的性能故障
  • 基于数据安全的沙盘推演体系
  • 自动标注工具 Autolabelimg
  • java HashSet 源码分析(深度讲解)
  • Vue实战【常用的Vue小魔法】
  • inode和软硬链接
  • Python遥感图像处理应用篇(三十一):Python+GDAL实现遥感图像平移、旋转