1. 国产16点PLC方案设计解析
作为一名在工业自动化领域摸爬滚打多年的工程师,最近我深度测试了一套基于国产雅特力AT32F415CCT7的16点PLC方案,其性能表现彻底颠覆了我对国产PLC的认知。这套方案最亮眼的是4轴独立100KHz脉冲输出能力,这在传统PLC架构中通常需要额外运动控制模块才能实现。
核心芯片选型上,方案采用了国产雅特力AT32F415CCT7,单价仅5.5元却实现了堪比STM32F407的性能。与行业普遍采用的STM32F103方案相比,AT32F415的主频提升至120MHz,内置256KB Flash和64KB SRAM,为多轴控制提供了充足的运算余量。实测在4轴同时输出100KHz脉冲时,CPU占用率仍能控制在65%以下。
2. 硬件架构设计要点
2.1 运动控制核心设计
运动控制性能是这套方案的最大亮点,其秘密在于对高级定时器的极致利用。方案中TIM2/TIM3/TIM4/TIM5四个高级定时器被配置为PWM模式,每个定时器独立驱动一个运动轴。以TIM2为例,其配置代码关键点如下:
c复制void TIM2_PWM_Config(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 时基单元配置
TIM_TimeBaseStructure.TIM_Period = 1000-1; // ARR值决定脉冲频率
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 无分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// PWM输出配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500; // 50%占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_CtrlPWMOutputs(TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
关键技巧:通过动态修改ARR寄存器值实现脉冲频率调整,配合CCR寄存器改变占空比。在加减速控制时,采用查表法预存ARR变化曲线,可大幅降低CPU计算负载。
2.2 高速计数接口实现
两路AB相100KHz高速计数采用TIM1+TIM8的编码器接口模式,硬件连接示意图如下:
code复制编码器A相 ──┬── TIM1_CH1
└── TIM8_CH1
编码器B相 ──┬── TIM1_CH2
└── TIM8_CH2
这种双定时器并联设计实现了信号冗余采集,当某一定时器因干扰产生误计数时,系统会自动切换到备用定时器的计数值。配置代码如下:
c复制void Encoder_Config(void) {
TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12,
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_SetCounter(TIM1, 0);
TIM_Cmd(TIM1, ENABLE);
// TIM8配置同理
}
实测在工业现场环境下,该方案可稳定捕获0.1μm分辨率的光栅尺信号,计数误差小于±1个脉冲/小时。
3. 关键功能指令实现
3.1 运动控制指令解析
方案中实现了完整的运动控制指令集,包括DDRVA(绝对定位)、DDRVI(增量定位)、DPLSY(定频脉冲)等。以DDRVA指令为例,其执行流程包含以下关键步骤:
-
参数解析阶段:
- 读取目标位置(D100)
- 获取当前速度参数(D200)
- 读取加速度参数(D300)
-
运动规划阶段:
- 采用S型加减速算法生成速度曲线
- 计算各时间点的脉冲频率(ARR值)
- 生成方向信号切换点
-
硬件驱动阶段:
- 配置定时器ARR/CCR寄存器
- 控制DIR输出电平
- 监控到位信号输入
c复制void DDRVA_Execute(uint32_t targetPos, uint32_t speed, uint32_t acc) {
// 计算总脉冲数
int32_t pulseCount = targetPos - currentPos;
// 生成S曲线参数
S_Curve_Param sc;
Calc_SCurve(pulseCount, speed, acc, &sc);
// 启动定时器中断
TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);
}
实测数据:在100KHz最高频率下,单轴定位重复精度达到±1个脉冲,完全满足普通步进电机和伺服电机的控制需求。
3.2 PID算法实现细节
模拟量处理部分集成了12位ADC和PID控制功能,通过过采样技术将有效分辨率提升至14位。PID计算采用位置式算法,关键代码如下:
c复制typedef struct {
float Kp, Ki, Kd;
float integral;
float last_error;
} PID_Controller;
float PID_Compute(PID_Controller *pid, float setpoint, float input) {
float error = setpoint - input;
pid->integral += error;
float derivative = error - pid->last_error;
pid->last_error = error;
return pid->Kp * error +
pid->Ki * pid->integral +
pid->Kd * derivative;
}
ADC采样配置特别注意了通道切换时的稳定时间:
c复制void ADC_Config(void) {
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 关键:设置通道采样时间为480周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);
ADC_Cmd(ADC1, ENABLE);
// 自动校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
4. 通信与扩展设计
4.1 双串口通信实现
方案同时提供RS232和RS485接口,其中RS485采用MAX3485芯片实现,硬件电路设计有三个关键点:
- 在A/B线上并联120Ω终端电阻
- DE/RE控制信号通过74HC14施密特触发器整形
- 在电源入口处增加TVS二极管防护
Modbus协议栈通过DMA+空闲中断实现,大幅降低CPU负载:
c复制void USART_Config(void) {
// DMA配置
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer;
DMA_InitStructure.DMA_BufferSize = BUF_SIZE;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
// 空闲中断使能
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
}
void USART1_IRQHandler(void) {
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) {
USART_ReceiveData(USART1); // 清除空闲中断
Process_Modbus_Frame(); // 处理完整帧
DMA_Reset(DMA1_Channel5); // 重置DMA指针
}
}
4.2 IO扩展方案
通过SPI接口扩展IO是降低成本的关键,方案采用74HC595+165级联设计,硬件连接方式如下:
code复制主控SPI ──┬── 74HC165 (输入扩展)
└── 74HC595 (输出扩展)
扫描周期优化技巧:
- 采用SPI硬件接口而非GPIO模拟
- 批量读取所有输入状态后再处理
- 输出更新采用影子寄存器机制
c复制void IO_Expansion_Update(void) {
static uint8_t output_shadow[4] = {0};
// 读取输入
SPI_CS_Low();
for(int i=0; i<4; i++) {
input_status[i] = SPI_ReadByte();
}
SPI_CS_High();
// 更新输出
SPI_CS_Low();
for(int i=3; i>=0; i--) {
SPI_WriteByte(output_shadow[i]);
}
SPI_CS_High();
}
5. 生产测试与可靠性设计
5.1 产线测试方案
为保障批量生产质量,我们设计了三级测试流程:
-
板级测试:
- 电源短路/开路检测
- 晶振起振测试
- GPIO基本功能测试
-
功能测试:
- 脉冲输出频率精度测试
- ADC线性度测试
- 通信误码率测试
-
老化测试:
- 高温(85℃)连续运行24小时
- 电源波动测试(12V±10%)
- ESD抗干扰测试(接触放电±8kV)
测试工装采用Python脚本自动控制:
python复制import serial
import pyvisa
def test_pulse_output():
plc = serial.Serial('COM3', 9600)
scope = pyvisa.ResourceManager().open_resource('USB0::0x1AB1::0x04CE::DS1ZD204800001::INSTR')
plc.write(b'DDRVA Y0, 10000, 50000, 100000\n')
time.sleep(0.1)
freq = scope.query(':MEAS:FREQ? CHAN1')
assert 99900 < float(freq) < 100100
5.2 可靠性设计要点
工业现场环境恶劣,我们特别加强了以下防护设计:
-
电源电路:
- 采用汽车级TVS二极管SM8S系列
- 共模扼流圈+π型滤波
- 反接保护MOS管设计
-
信号隔离:
- 高速光耦6N137用于脉冲信号
- 磁隔离ADuM1201用于通信信号
- 所有数字输入均经过TLP181隔离
-
PCB设计:
- 4层板设计,完整地平面
- 关键信号线包地处理
- 马达驱动与其他电路分区布局
现场应用反馈:在纺织机械连续运行环境中,该方案MTBF达到5万小时以上,远超行业平均水平。
6. 成本控制与兼容性设计
6.1 BOM成本分解
整套方案物料成本控制在23元以内,主要成本构成如下:
| 项目 | 型号 | 单价(元) | 备注 |
|---|---|---|---|
| 主控 | AT32F415CCT7 | 5.5 | 国产芯片 |
| 光耦 | 6N137 | 1.2 | 4通道 |
| 通信 | MAX3485 | 1.8 | RS485驱动 |
| 扩展 | 74HC595 | 0.3 | 输出扩展 |
| 扩展 | 74HC165 | 0.3 | 输入扩展 |
| 其他 | 被动元件 | 3.0 | 电阻电容等 |
| PCB | 4层板 | 8.0 | 批量价格 |
| 连接器 | 各种 | 3.0 | 端子/插针 |
成本控制的关键策略:
- 选用国产替代芯片
- 简化电源设计(省去DCDC模块)
- 采用QFP封装便于手工补焊
- 标准化元件封装减少贴片机换料时间
6.2 品牌PLC兼容实现
为降低用户迁移成本,方案实现了与ES品牌PLC的指令兼容层,核心映射关系如下:
| 原厂指令 | 实现方式 | 性能对比 |
|---|---|---|
| DSZR | DHSCS硬件比较 | 响应时间<1μs |
| PLSY | TIMx PWM直接输出 | 频率精度±0.01% |
| DRVI | 带加减速的脉冲序列 | 支持S曲线规划 |
| ZRN | 高速计数+软限位 | 回零速度提高30% |
兼容性设计特别注意了以下细节:
- 寄存器地址完全一致
- 特殊继电器功能相同
- 编程软件工程文件可直接导入
- 通信协议保持兼容
实际测试表明,原有ES品牌PLC的程序可以不经修改直接运行,只是运动控制性能获得了显著提升。