CH32V103C8T6引脚和STM32F103C8T6完全兼容,市场上销售的最小系统板采用公版设计,价格不到10元。但CH32V103需要WCH-Link开发,好在便宜,还自带一个串口,性价比还是不错的。


电路图如下:

仍以点灯为例:
MounRiver Studio+WCH-Link调通CH32V103C-CSDN博客
由于其LED所接的引脚为PC13,需要进行适当调整,完整代码如下:
#include "debug.h"
void GPIO_Toggle_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
int main(void)
{
u8 i = 0;
SystemCoreClockUpdate();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n", SystemCoreClock);
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
printf("GPIO Toggle TEST\r\n");
GPIO_Toggle_INIT();
while(1)
{
Delay_Ms(1000);
GPIO_WriteBit(GPIOC, GPIO_Pin_13, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
}
}
打开User->system_ch32v10x.c文件,找到以下部分,根据提示进行修改
#define SYSCLK_FREQ_HSE HSE_VALUE //使用外部时钟,默认是8M
//#define SYSCLK_FREQ_48MHz_HSE 48000000 //使用外部时钟,经锁相环PLL倍频成48M
//#define SYSCLK_FREQ_56MHz_HSE 56000000 //使用外部时钟,经锁相环PLL倍频成56M
//#define SYSCLK_FREQ_72MHz_HSE 72000000 //使用外部时钟,经锁相环PLL倍频成72M
//#define SYSCLK_FREQ_HSI HSI_VALUE //使用内部时钟,默认是8M
//#define SYSCLK_FREQ_48MHz_HSI 48000000 //使用内部时钟,经锁相环PLL倍频成48M
//#define SYSCLK_FREQ_56MHz_HSI 56000000 //使用内部时钟,经锁相环PLL倍频成56M
//#define SYSCLK_FREQ_72MHz_HSI 72000000 //使用内部时钟,经锁相环PLL倍频成72M
其中,HSE_VALUE和HSI_VALUE都可以在
Peripheral->inc->ch32v10x.h文件内进行修改
选用12.288M外部晶振,常用的uart通信速率并经测试成功,充分利用WCH-Link的自带串口,将其上的RX接开发板的A9引脚,参考如下:
38400,19200,9600
define SYSCLK_FREQ_48MHz_HSE 48000000后面的48000000,改为73728000,此时选用73.728M时钟,常用的uart通信速率并测试成功,参考如下:
921600(*),460800(*),230400,115200,57600,38400,19200,9600
*921600和460800会出现乱码,是因为受制于WCH-Link串口的硬件限制,改为FT232或CH340等将工作正常。
输出一个2.048M的方波以及8KHz的正脉冲,其脉冲宽度在1us左右,全部代码(AI辅助完成)如下:
#include "debug.h"
#include "ch32v10x_tim.h"
/* ================= 引脚定义 ================= */
// 2.048MHz 方波输出 (TIM2_CH1, PA0)
#define PIN_2M_GPIO GPIOA
#define PIN_2M_PIN GPIO_Pin_0
#define PIN_2M_TIM TIM2
#define PIN_2M_CHANNEL 1
// 8kHz 976ns 正脉冲输出 (TIM4_CH1, PB6)
#define PIN_8K_GPIO GPIOB
#define PIN_8K_PIN GPIO_Pin_6
#define PIN_8K_TIM TIM4
#define PIN_8K_CHANNEL 1
/* ================= 时钟参数 ================= */
#define SYSCLK_HZ 73728000UL // 系统时钟 73.728 MHz
#define T_SYSCLK_NS 13.56f // 单个系统时钟周期 ≈ 13.56 ns
/* ================= 2.048MHz 方波参数 ================= */
// 2.048MHz 周期 = 73.728MHz / 2.048MHz = 36 个系统时钟
#define ARR_2M 35 // 自动重载值 = 36 - 1
#define CCR_2M 17 // 比较值 = 17 → 高电平持续 18 个时钟 (占空比 50%)
/* ================= 8kHz 976ns 脉冲参数 ================= */
// 8kHz 周期 = 125 μs = 73.728MHz / 8000 = 9216 个系统时钟
#define ARR_8K 9215 // 自动重载值 = 9216 - 1
// 976ns 脉宽 = 976ns / 13.56ns ≈ 72 个系统时钟 → 比较值设为 71 (高电平持续 72 个时钟)
#define CCR_8K 71 // 高电平持续 72 个时钟 → 实际脉宽 = 72 × 13.56ns = 976.3ns
/* ================= 函数声明 ================= */
void PWM_2M_Init(void);
void PWM_8K_Init(void);
void GPIO_Toggle_INIT(void);
/* 初始化 2.048MHz 方波 (PA0, TIM2_CH1) */
void PWM_2M_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 配置 PA0 为复用推挽输出
GPIO_InitStructure.GPIO_Pin = PIN_2M_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PIN_2M_GPIO, &GPIO_InitStructure);
// 定时器 TIM2 时基配置
TIM_TimeBaseStructure.TIM_Period = ARR_2M;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(PIN_2M_TIM, &TIM_TimeBaseStructure);
// PWM1 模式,高电平有效
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR_2M;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(PIN_2M_TIM, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(PIN_2M_TIM, TIM_OCPreload_Enable);
// 使能自动重装载和定时器
TIM_ARRPreloadConfig(PIN_2M_TIM, ENABLE);
TIM_Cmd(PIN_2M_TIM, ENABLE);
}
/* 初始化 8kHz 976ns 正脉冲 (PB6, TIM4_CH1) */
void PWM_8K_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // 使能 TIM4 时钟
// 配置 PB6 为复用推挽输出
GPIO_InitStructure.GPIO_Pin = PIN_8K_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PIN_8K_GPIO, &GPIO_InitStructure);
// 定时器 TIM4 时基配置:周期 8kHz
TIM_TimeBaseStructure.TIM_Period = ARR_8K;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(PIN_8K_TIM, &TIM_TimeBaseStructure);
// PWM1 模式,高电平有效,脉宽 = (CCR_8K+1) 个系统时钟
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR_8K;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(PIN_8K_TIM, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(PIN_8K_TIM, TIM_OCPreload_Enable);
// 使能自动重装载和定时器
TIM_ARRPreloadConfig(PIN_8K_TIM, ENABLE);
TIM_Cmd(PIN_8K_TIM, ENABLE);
}
/* 初始化 PC13 翻转(用于指示程序运行状态) */
void GPIO_Toggle_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
int main(void)
{
u8 i = 0;
SystemCoreClockUpdate();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
Delay_Init();
USART_Printf_Init(115200);
// 打印系统信息
printf("SystemClk: %d Hz\r\n", SystemCoreClock);
printf("ChipID: %08x\r\n", DBGMCU_GetCHIPID());
printf("GPIO Toggle TEST\r\n");
// 初始化 PA0 输出 2.048MHz 方波
PWM_2M_Init();
printf("2.048MHz square wave output on PA0 (TIM2_CH1)\r\n");
// 初始化 PB6 输出 8kHz 976ns 正脉冲
PWM_8K_Init();
printf("8kHz positive pulse (width 976ns) output on PB6 (TIM4_CH1)\r\n");
printf(" -> Pulse width = 976ns (2 BCLK cycles @ 2.048MHz)\r\n");
printf(" -> Compatible with TP3057 Short-Frame mode (1-2 BCLK cycles)\r\n");
// 初始化 PC13 翻转
GPIO_Toggle_INIT();
printf("PC13 toggles every 1 second (period 2s)\r\n");
while(1)
{
Delay_Ms(1000);
// 每秒钟翻转一次 PC13
GPIO_WriteBit(GPIOC, GPIO_Pin_13, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
}
}
以上代码,用作TIM1、TIM3输出可能失败。