沁恒CH32V307使用记录:使用TIM输出PWM信号
创始人
2025-05-31 16:05:24
0

文章目录

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

目的

使用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);// 初始化 TIM4TIM_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 PWMTIM_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);                // 高级定时器需要将这个使能才能输出PWMTIM_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信号操作比较简单,只要了解相关原理基本上就能立马上手使用。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...