STM32F系列兼容西门子S7 200PLC源码 CPU:STM32F103RCT6(或其他S...
STM32F系列兼容西门子S7 200PLC源码 CPUSTM32F103RCT6(或其他STM32F103系列大容量芯片) 开发平台keilMDK5 PLC型号CPU224XP或226最近在搞嵌入式PLC开发的朋友肯定对STM32F103系列不陌生这货简直就是工控领域的万金油。今天咱们就聊聊怎么用这颗芯片跑起西门子S7-200的PLC程序直接拿STM32硬刚西门子祖传架构这事儿听着刺激吧先扔个硬件配置镇楼主控芯片STM32F103RCT6Flash容量256KSRAM 48K带USB/CAN开发环境Keil MDK5经典到掉牙的ARM开发环境目标型号CPU224XP数字量14入/10出模拟量2入/1出!STM32F103RCT6引脚图重点来了——IO映射这块得玩明白。西门子PLC的IO地址是固定编码的咱们得在STM32里模拟这套寻址规则。看这段GPIO初始化的骚操作// 数字量输入配置 void DI_Config(void) { GPIO_InitTypeDef gpio; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); gpio.GPIO_Pin 0x00FF; // PA0-PA7对应I0.0-I0.7 gpio.GPIO_Mode GPIO_Mode_IPU; GPIO_Init(GPIOA, gpio); // 扩展输入用PC0-PC3 gpio.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_Init(GPIOC, gpio); }这段代码把PA0-PA7映射成PLC的I0.0-I0.7输入点IPU模式内部上拉是重点工业现场干扰大上拉比浮空稳定得多。当年在产线调试时发现不加这个上拉电阻传感器信号能给你抖出迪斯科节奏...STM32F系列兼容西门子S7 200PLC源码 CPUSTM32F103RCT6(或其他STM32F103系列大容量芯片) 开发平台keilMDK5 PLC型号CPU224XP或226定时器才是PLC的心脏西门子那个1ms的扫描周期不是盖的。用STM32的TIM2实现时间基准void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update)) { static uint16_t scan_cycle 0; scan_cycle; if(scan_cycle 1000) { // 1ms*10001s WatchDog_Feed(); // 喂狗操作 scan_cycle 0; } PLC_Runtime; // 全局运行时长计数 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } }这个中断服务程序实现了两个关键功能1ms级别的扫描周期累计和看门狗喂狗。注意那个PLC_Runtime变量这玩意儿在梯形图程序里对应SM0.4/SM0.5这些特殊寄存器搞过STEP7的都懂。说到通讯协议PPI协议是绕不过的坎。虽然官方没公开协议细节但咱们可以抓包逆向。关键帧结构解析代码长这样uint8_t PPI_Frame_Analysis(uint8_t *buf) { if(buf[0] ! 0x68) return 0; // 帧头校验 uint8_t len buf[1]; if(len 240) return 0; // 长度异常 // 校验和计算 uint8_t checksum 0; for(uint8_t i0; ilen2; i){ checksum buf[i]; } if(checksum ! buf[len2]) return 0; // 提取有效数据 memcpy(PPI_RxBuffer, buf[4], len-2); return len-2; }这个校验算法当年可是用示波器抓了三天三夜的串口波形才摸清楚的。注意那个0x68帧头西门子的设备在通讯启动时会先发这个魔数跟TCP三次握手似的。最后说下抗干扰处理工业现场没你想的那么干净。在数字量输入部分加个软件滤波#define FILTER_DEPTH 5 // 5次采样表决 uint8_t DI_Filter(uint8_t channel) { static uint8_t history[8][FILTER_DEPTH] {0}; static uint8_t index 0; uint8_t current_state GPIO_ReadInputDataBit(di_port[channel], di_pin[channel]); history[channel][index] current_state; // 多数表决算法 uint8_t count 0; for(uint8_t i0; iFILTER_DEPTH; i){ if(history[channel][i]) count; } index (index1)%FILTER_DEPTH; return (count FILTER_DEPTH/2) ? 1 : 0; }这个滤波算法能有效消除触点抖动原理类似移动平均滤波。之前在变频器旁边测试时不加滤波的误动作率高达30%加上之后直接归零。移植过程中最坑的是保持寄存器的掉电保存STM32的Flash写入次数有限直接照搬西门子的存储策略会快速写废芯片。后来改用EEPROM模拟算法把写入操作分散到不同扇区这才解决寿命问题。具体实现有空再展开说。