
大家好,我是良许。
在嵌入式系统开发中,PCB(Printed Circuit Board,印刷电路板)设计和布局是将电路原理图转化为实际可制造产品的关键环节。
一个优秀的PCB设计不仅能保证电路功能的正常实现,还能提升系统的稳定性、降低电磁干扰、优化散热性能,甚至直接影响产品的成本和可靠性。
今天,我就结合自己多年在嵌入式领域的实践经验,和大家聊聊PCB设计和布局的那些事儿。
PCB是电子产品中电气连接的载体,它通过在绝缘基板上按预定设计形成点间连接及印制元件的印制板。
简单来说,就是把电路原理图中的各个元器件通过铜箔走线连接起来,形成一个可以实际焊接元器件的板子。
在我早期做单片机开发的时候,经常需要自己画PCB板。
记得有一次做一个STM32的项目,因为PCB布局不合理,导致ADC采集到的信号噪声特别大,后来重新调整了模拟地和数字地的布局,问题才得以解决。
这让我深刻体会到,PCB设计绝不是简单地把元器件连起来那么简单。
一块标准的PCB通常由以下几层组成:
根据层数不同,PCB可以分为单面板、双面板和多层板。
在汽车电子领域,我们通常使用4层或6层板,以满足复杂的信号完整性和EMC(电磁兼容)要求。
一个完整的PCB设计流程通常包括:
在进行PCB布局时,首先要将整个电路按功能划分为不同的模块,比如电源模块、MCU核心模块、通信接口模块、传感器接口模块等。
每个模块内部的元器件应该紧密放置,模块之间保持适当距离,这样既便于布线,也有利于信号完整性。
举个例子,在我做STM32项目时,通常会这样布局:
布局时要考虑信号的流向,尽量让信号按照从输入到输出的顺序流动,避免信号回流或交叉。
比如在一个数据采集系统中,传感器信号应该先经过信号调理电路,再进入ADC,最后到MCU,这样的布局可以最大程度减少信号干扰。
对于功耗较大的元器件,如电源芯片、功率器件、高速处理器等,布局时要考虑散热问题。这些元器件应该:
在汽车电子项目中,我们经常会遇到高温环境,所以热管理尤为重要。
有一次我们设计的一款车载控制器,因为功率芯片布局不当,导致局部温度过高,最后不得不重新设计PCB,增加了散热铜皮面积。
PCB的外形尺寸、安装孔位置、接口位置等都要与产品的机械结构相匹配。
在布局之前,最好先拿到产品的3D结构图,确保PCB能够正确安装到外壳中,所有接口都能对准外壳开孔。
电源和地线是PCB中最重要的网络,它们的布线质量直接影响整个系统的稳定性。
电源线布线原则:
地线布线原则:
下面是一个STM32的电源去耦电容放置示例代码(虽然这是硬件设计,但我们可以在初始化代码中体现对电源的重视):
// STM32 HAL库初始化代码示例
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 配置电源调节器输出电压
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
// 初始化HSE和PLL
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
// 配置系统时钟
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}在PCB设计中,对应这段代码的硬件布局应该是:HSE晶振紧靠MCU的OSC引脚,电源去耦电容紧靠VDD引脚,这样才能保证时钟和电源的稳定性。
对于高速信号(如时钟信号、高速数据总线),布线时需要特别注意信号完整性问题。
高速信号布线原则:
差分信号(如USB、CAN、以太网)具有良好的抗干扰能力,但布线时需要遵循特定规则:
下面是一个STM32的CAN总线初始化代码示例:
// CAN总线初始化
void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 6; // 时钟分频
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
// 配置CAN过滤器
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
// 启动CAN
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
Error_Handler();
}
}在PCB布线时,CAN_H和CAN_L这两根差分信号线必须紧密平行布线,并且要远离高频干扰源,同时在总线末端要放置120Ω终端电阻。
模拟信号对噪声非常敏感,布线时要格外小心:
电磁干扰是PCB设计中最常见的问题之一。在我做汽车电子项目时,产品必须通过严格的EMC测试,这就要求PCB设计时必须充分考虑EMI抑制。
EMI抑制方法:
信号完整性问题通常表现为信号失真、振铃、串扰等。
改善信号完整性的方法:
在我之前提到的那个车载控制器项目中,热设计问题差点导致项目延期。后来我们采取了以下措施:
市面上有很多优秀的PCB设计工具,各有特点:
我个人最常用的是Altium Designer,它的3D可视化功能和强大的规则检查功能让我受益匪浅。
基于多年的实践经验,我给大家几点建议:
在我的职业生涯中,PCB设计能力的提升是一个循序渐进的过程。
从最初的简单单片机板,到后来的复杂多层板,每一次设计都是一次学习的机会。
记得有一次,我设计的一块板子因为地线布局不合理,导致ADC采样值波动很大,后来通过重新布局地线,问题才得以解决。
这些经验教训都是宝贵的财富。
PCB设计和布局是一门需要理论知识和实践经验相结合的技术。
希望今天的分享能够帮助大家在PCB设计的道路上少走弯路,设计出更加优秀的产品。
如果大家在实际项目中遇到PCB设计方面的问题,欢迎交流讨论!
更多编程学习资源
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。