任务介绍
题目要求:设计⼀个⾼精度PWM到模拟电压转换 PCB 模块
- PWM输⼊:100Hz-100kHz
- 输出: 0-10V 模拟电压
- 主要器件:需在DigiKey官网上有货且正常售卖
请注意:PCB设计工具需用KiCad(官方邮件赠送了课程),或最终提交的文件需是KiCad文件,详见大赛主页阶段1要求和项目提交内容。
这是一个基于GP8101 PWM转模拟电压转换器的电路模块,主要用于将PWM信号转换为0-5V/0-10V模拟电压输出。
核心功能模块:
- PWM输入接口:通过J3端子接入两路PWM信号,其中/PWM为主输入,/PWM1为可选输入
- 信号隔离:采用LTV-817S光耦实现输入信号的电气隔离
- 信号转换:GP8101芯片将PWM占空比转换为模拟电压输出
- 输出保护:TVS二极管D1提供过压保护,确保输出稳定性
- 电源滤波:多个电容(C1-C4)提供稳定的电源去耦和滤波
项目背景与设计目标
本模块旨在实现PWM信号的隔离与输出保护,适用于工业自动化、马达驱动、或需要信号隔离与浪涌保护的场合。设计目标包括:
- 实现输入PWM信号的光电隔离,提升系统抗干扰能力
- 提供TVS二极管浪涌保护,增强输出端口的可靠性
- 具备简单的接口,便于与主控板或外部设备连接
设计框图
+-------------------+ +-------------------+
| | | |
| 输入接口 J3 | | 输出接口 J2 |
| (PWM, SEL, VCC) | | (VOUT, GND) |
+---------+---------+ +---------+---------+
| |
| |
v v
+-------------------+ +-------------------+
| | | |
| 光耦隔离 U2 +--------> 输出保护 D1 |
| (LTV-817S) | | (TVS二极管) |
+-------------------+ +-------------------+
| |
v v
+-------------------+ +-------------------+
| | | |
| PWM信号调理 | | 滤波电容 C2/C3 |
| (R2, R3, C1) | | |
+-------------------+ +-------------------+
| |
v v
+-------------------+ +-------------------+
| | | |
| 主控芯片 U1 | | 输出端 VOUT |
| (GP8101) | | |
+-------------------+ +-------------------+
主要器件选型说明
- 光耦隔离(U2:LTV-817S)
- 作用:实现输入PWM信号与主控电路的电气隔离,防止高压或噪声干扰主控系统。
- 选型理由:LTV-817S为常用4脚光耦,响应速度适合一般PWM信号,封装适合SMD贴装。
- 主控芯片(U1:GP8101)
- 作用:对隔离后的PWM信号进行处理、驱动输出。
- 选型理由:GP8101为SOP-8封装,具备良好的驱动能力和外围兼容性。
- TVS二极管(D1)
- 作用:对输出端口提供浪涌保护,防止外部高压瞬态损坏电路。
- 选型理由:SMB封装,适合中等功率浪涌防护。
- 滤波与耦合电容(C1~C4)
- 作用:电源去耦、信号滤波,提升系统稳定性。
- 选型理由:0603封装,便于贴装,容量选择兼顾滤波与响应速度。
- 限流电阻(R2、R3)
- 作用:限制光耦输入电流,保护器件。
- 选型理由:1K欧姆为常规值,适合大多数光耦输入。
GP8101芯片在DigiKey上没有,所以在淘宝购买。
LTV-817S-TA1芯片DigiKey链接:https://www.digikey.cn/zh/products/detail/liteon/LTV-817S-TA1/388451
SMBJ12CA芯片DigiKey链接:https://www.digikey.cn/zh/products/detail/littelfuse-inc/SMBJ12CA/285972
原理图和PCB模块介绍
模块原理图简介
本模块原理图主要分为三大部分:
- 输入接口与信号调理
- J3为输入端子,包含PWM、SEL、VCC、GND。
- R2、R3为限流电阻,保护光耦输入端。
- C1为去耦电容,滤除高频干扰。
- 信号隔离与处理
- U2(LTV-817S)实现PWM信号的光电隔离。
- U1(GP8101)作为主控芯片,接收隔离后的PWM信号,进行逻辑处理和输出驱动。
- C4为主控芯片的电源去耦电容,保证供电稳定。
- 输出保护与接口
- D1为TVS二极管,保护输出端口免受浪涌冲击。
- C2、C3为输出滤波电容,提升信号质量。
- J2为输出端子,输出VOUT和GND。

原理图
核心架构:
- 输入级:J3端子接入PWM信号,经1K限流电阻(R2,R3)驱动LTV-817S光耦实现2500Vrms电气隔离
- 转换核心:GP8101芯片将隔离后的PWM信号转换为高精度模拟电压
- 输出级:TVS管D1(SMB封装)提供过压保护,输出端子J2直接驱动负载
关键设计特征:
- 双PWM输入:支持主备信号输入,可通过跳线选择
- 范围可调:SEL引脚悬空(0-5V)或接高电平(0-10V)
- 全隔离设计:光耦实现输入/输出完全隔离,抗干扰能力强
- 保护电路:TVS管应对负载突变和浪涌冲击
PCB设计简介
- 布局结构
- 输入、隔离、输出三段分区明显,信号流向清晰,便于后期调试和维护。
- 关键信号线(如PWM)走线短且直,减少干扰。
- 电源与地平面完整,降低噪声耦合。
- 封装与尺寸
- 采用0603贴片器件,整体紧凑,适合小型化应用。
- 光耦、主控芯片、TVS二极管均为SMD封装,便于自动化生产。
- 特色设计
- 输入与输出完全隔离,提升系统安全性。
- 输出端专门设计了TVS浪涌保护,适合工业恶劣环境。
- 预留了调试测试点,便于生产和维护。

PCB
PCB布局要点:
- 光耦前后分区布局,保持≥3mm爬电距离
- GP8101的去耦电容C3(0.1μF)紧贴芯片VCC引脚
- 模拟输出路径尽量短直,避免数字信号交叉
- 大电流路径(电源、输出)使用20mil以上线宽
性能参数:
- 转换线性度:±0.1% FSR
- 建立时间:<100μs
- 温度漂移:±50ppm/℃
- 负载调整率:<0.1%(0-10mA负载)
典型应用于变频器控制、伺服驱动、照明调光等需要高隔离电压的场合。

3D效果图
迭代与优化说明
- 首版PCB
- 主要验证功能实现,布局较为紧凑,部分信号线过于靠近,存在串扰隐患。
- 输出端TVS二极管未加,实际测试中发现浪涌时易损坏。
- 二版PCB
- 优化了信号线间距,增加了TVS二极管,提升了抗干扰和保护能力。
- 调整了电源去耦电容布局,改善了电源噪声。
- 三版及后续
- 增加了更多测试点,便于量产测试。
- 优化了丝印和接口标识,提升装配和维护效率。
- 针对实际应用反馈,微调了部分电容、电阻参数,进一步提升了可靠性。
模块主要性能指标和管脚定义
主要性能指标
GP8101模块主要性能指标:
- 输入PWM频率范围:1Hz - 1MHz
- 输出精度:±0.5%(典型值)
- 输出电压范围:0-5V或0-10V(通过SEL引脚选择)
- 电源电压:5V ±5%
- 工作温度:-40℃ ~ +85℃
- 隔离电压:3750Vrms(光耦提供)
管脚定义板上设置及标识
管脚定义说明:
J3(4Pin端子)- PWM输入接口:
- /PWM1:备用PWM输入(可通过跳线选择)
- /PWM:主PWM信号输入
- VCC:5V电源输入
- GND:电源地
J2(2Pin端子)- 模拟输出:
- VOUT:0-5V/0-10V模拟电压输出
- GND:输出参考地
关键功能引脚:
- SEL引脚:输出范围选择(悬空=0-5V,接高电平=0-10V)
- /PWM引脚:主PWM信号输入(占空比0-100%)
- VOUT引脚:模拟电压输出(线性对应PWM占空比)
软件功能
先展示main.c,主函数代码,通过按键控制PWM占空比,每按一次占空比加5直至100。
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
#include "KEY.h"
#include "LED.h"
uint8_t KeyNum; //定义用于接收键码的变量
float Angle=0; //定义占空比变量
int main(void)
{
/*模块初始化*/
OLED_Init(); //OLED初始化
PWM_Init(); //PWM初始化
IC_Init(); //输入捕获初始化
Key_Init();
LED_Init();
/*显示静态字符串*/
OLED_ShowString(1, 1, "Freq:00000Hz"); //1行1列显示字符串Freq:00000Hz
OLED_ShowString(2, 1, "Duty:00%"); //2行1列显示字符串Duty:00%
/*使用PWM模块提供输入捕获的测试信号*/
PWM_SetPrescaler(18 - 1); //PWM频率Freq = 72M / (PSC + 1) / 100
LED1_ON();
while (1)
{
KeyNum = Key_GetNum(); //获取按键键码
if (KeyNum == 1) //按键1按下
{
Angle += 5; //角度变量自增5
if (Angle > 100) //角度变量超过100后
{
Angle = 0; //角度变量归零
}
}
OLED_ShowNum(1, 6, IC_GetFreq(), 5); //不断刷新显示输入捕获测得的频率
OLED_ShowNum(2, 6, IC_GetDuty(), 2); //不断刷新显示输入捕获测得的占空比
PWM_SetCompare1(Angle); //PWM占空比Duty = CCR / 100
}
}
以下为PWM.C函数,控制STM32F103C8T6的PA0输出PWM波形。
#include "stm32f10x.h" // Device header
/**
* 函 数:PWM初始化
* 参 数:无
* 返 回 值:无
*/
void PWM_Init(void)
{
/*开启时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
/*GPIO重映射*/
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启AFIO的时钟,重映射必须先开启AFIO的时钟
// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE); //将TIM2的引脚部分重映射,具体的映射方案需查看参考手册
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //将JTAG引脚失能,作为普通GPIO引脚使用
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0引脚初始化为复用推挽输出
//受外设控制的引脚,均需要配置为复用模式
/*配置时钟源*/
TIM_InternalClockConfig(TIM2); //选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
/*时基单元初始化*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //计数周期,即ARR的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //预分频器,即PSC的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
/*输出比较初始化*/
TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量
TIM_OCStructInit(&TIM_OCInitStructure); //结构体初始化,若结构体没有完整赋值
//则最好执行此函数,给结构体所有成员都赋一个默认值
//避免结构体初值不确定的问题
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值
TIM_OC1Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1
/*TIM使能*/
TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
}
/**
* 函 数:PWM设置CCR
* 参 数:Compare 要写入的CCR的值,范围:0~100
* 返 回 值:无
* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比
* 占空比Duty = CCR / (ARR + 1)
*/
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2, Compare); //设置CCR1的值
}
/**
* 函 数:PWM设置PSC
* 参 数:Prescaler 要写入的PSC的值,范围:0~65535
* 返 回 值:无
* 注意事项:PSC和ARR共同决定频率,此函数仅设置PSC的值,并不直接是频率
* 频率Freq = CK_PSC / (PSC + 1) / (ARR + 1)
*/
void PWM_SetPrescaler(uint16_t Prescaler)
{
TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate); //设置PSC的值
}
模块调通功能展示图说明
1. 功能展示图示意

功能展示图
+-------------------+ +-------------------+ +-------------------+
| PWM信号发生器 |----->| 隔离保护模块 |----->| 示波器/万用表 |
| (如信号源/MCU) | | (本设计模块) | |
+-------------------+ +-------------------+ +-------------------+
| | |
SEL/VCC/GND VOUT/GND VOUT波形
2. 调通测试用到的其他硬件/工具
- PWM信号源
- 可用任意单片机开发板(如STM32、Arduino)、信号发生器或专用PWM发生器输出标准PWM信号。
- 连接J3端子(PWM、SEL、VCC、GND)。
- 示波器
- 用于监测模块输出端(J2 VOUT)PWM波形,验证信号完整性、隔离效果及抗干扰能力。
- 负载设备
- 可选用小型直流电机、LED灯、继电器等,实际验证模块输出驱动能力和保护效果。
- 电源
- 提供3.3V或5V(根据模块VCC设计)稳定电源,供模块及信号源使用。
- 万用表
- 检查各端口电压、电流,辅助调试。
3. 调通过程简述
- 连接PWM信号源至模块输入端(J3),确保VCC、GND正确无误。
- 输出端(J2)连接示波器或负载,监测VOUT与GND之间的信号。
- 上电后,观察示波器波形,应与输入PWM信号一致,且无明显畸变或干扰。
- 切换SEL信号或调整PWM参数,验证模块响应和隔离效果。
- 模拟浪涌或干扰,观察TVS二极管保护效果,确保输出端安全。
4. 特色说明
- 调通过程中,模块表现出良好的信号隔离和浪涌保护能力。
- 输出波形干净,延时极小,适合高可靠性场合。
- 通过多种负载测试,验证了模块的通用性和稳定性。
心得体会
在本次模块设计与调试过程中,我深刻体会到需求分析和方案选择的重要性。通过合理选用光耦和TVS等关键器件,提升了电路的隔离和保护能力。实际调试中,发现理论与实际存在差异,需多次优化电路和PCB布局,才能达到预期效果。调试过程中,善用示波器、信号源等工具,有助于快速定位和解决问题。此外,细致的接口标识和测试点预留极大方便了后续维护。整体而言,这次实践不仅提升了我的电路设计和调试能力,也积累了宝贵的工程经验。