仿制三菱PLC(Fx2N)并且应用到工业现场
背景
本人从事工业应用开发(PLC,HMI编程等等),一直想开发出一套自己的整套控制系统,先从仿制开始吧!从PLC——》HMI——》伺服——》网络应用等。电脑与PLC通信本来是不能开源,公司开发的产品用到(要低调使用),考滤到后期开发配套系统时可能用到,就开源了。通信用业余时间前前后后,断断续续一直到努力着开发。希望有共同爱好的朋友一起交流。
正巧,借助参加EEworld这个DIY活动正式发布最新的PLC控制单元(FX2n仿制产品)并且应用于到工业场版。之前发布过一些测试版。期望中到RIGOL DS1102U 双通道数字示波器 用来测方式高速计数和高速输出功能是否达到要求(应用中暂时没使用高速功能),感谢各位捧场。
介绍
PLC程序使用三菱GX Developer Version 8。本来要上传上来,文件太大,自行到三菱官网下载。
实际应用例程
主控使用STM32F446,使用标准库(不喜欢HAL库,严重影响PLC扫描时间),很容易移植到别的主控上,开发时特别考虑了快速移植,开发环境IAR。
主要目录
doc 开发过程中所有的资料,备注等
STM32F4xxDSP_StdPeriph_Lib_v1.8.0 标准库(STM32下载)
USER 源代码
MCU 和主控相关的代码
McuConnectPlc PLC核心代码与主控连接代码
PLC PLC核心代码(可以看出特别容易移植到别的主控)
Fx2N IAR项目文件
其它的没什么用
命名EXTI_PA0 IO外部中断,使用PA0引脚相关
NVIC 优先级设置相关
RCC 系统时钟初始化相关
RTC 实时时钟相关
源代码简单介绍
1.MCU启动后,2.进行main,3.接着初始化各个时钟,包括实时时钟(PLC使用到)。4.初始化定时中断,1MS中断一次,给PLC定时器、扫描时间等使用(本MCU使用系统节拍时间,可以用定时器替代)。5中断优先级初始化。6进入PLC核心代码。
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s)
before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file.
*/
RCC_Config();//初始化系统时间到最大180M
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);//使能LIS时种,给实时时钟使用
/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
/* SysTick end of count event each 10ms */
RCC_GetClocksFreq(&RCC_Clocks);//获取主时钟,给系统节拍使用
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);//系统节拍初始化
NVIC_Configuration();//中断优先级初始化
plc_main();
}
void plc_main(void)
{
// uint32 ddddd;
uint8 temp;
RGB_LED_Init();
// LED4(OFF);//绿灯,运行
// LED5(OFF);//红灯,出错
// LED6(OFF);//蓝灯,电池低
PLC_PowerUpReset();
DMA_Uart_Init();
Programme_Serial_Init(0);
rs232_Serial_Init(D8120);
/*
tim1_pwm_init();
tim1_pwm_start(0xffFf,515,0x7FFF);
tim2_ch1_pb8_UD_init();
tim2_ch2_pb9_R_init();
tim3_etr_pd2_UD_Init();
tim8_pwm_init();
tim8_pwm_start(0xffFf,515,0x7FFF);
tim2_ENC_Init();
tim5_ENC_Init();
GetCounter2();
GetCounter5();
GetDir2();
*/
/* RTC Configuration */
RTC_Configuration();
while(1)
{
/*
PLC_RAM32(PLC_R_START_ADD+0x0cdc)=Get_tim2_ch1_pb8_UD_Counter(); //c255
if(PLC_BIT_TEST(0x800)) //m0
tim2_ch1_pb8_UD_Counter_Clear();
PLC_RAM32(PLC_R_START_ADD+0x0cd8)=Get_tim3_etr_pd2_UD_Counter();//c254
if(PLC_BIT_TEST(0x801)) //m1
tim3_etr_pd2_UD_Counter_Clear();
*/
PLC_PROG_RUN();
if(PLC_1MS_BIT>70)
{
wdt();
PLC_1MS_BIT=0;
Receive_Processing(&PLC_UART_BUFFER,&PLC_UART_RECEIVE_CNT,&PLC_UART_T_BUFFER,&PLC_UART_T_CNT);
DMASend();
Receive_Processing(&RS232_R_BUFFER,&RS232_RECEIVE_CNT,&RS232_T_BUFFER,&RS232_T_CNT);
RS232_SEND();
if(D8065)
{
// LED5(ON);//红灯,出错
}
else
{
// LED5(OFF);//红灯,出错
}
if(D8065==0 && PLC_BIT_TEST(M8037)==0)
{
if(PLC_RUN_BIT==0)
{
PLC_RUN_BIT=1;
} //开始运行测试
// LED4(ON);//绿灯,运行
if(PLC_BIT_TEST(M8015) || PLC_BIT_TEST(M8019) || PLC_BIT_TEST(M8018)==0)
{
RCC_RTCCLKCmd(DISABLE);
temp=2;
}
else
{
if(temp==2)
{
RCC_RTCCLKCmd(ENABLE);
temp=1;
D_to_RTC();
}
else
RTC_to_D();
}
#ifndef debug
if(PLC_RUN_BIT==3)
{
wdt_init(D8000);
}
#endif
}
else
{
wdt_clear();
// LED4(OFF);//绿灯,运行
if(PLC_RUN_BIT!=0)
{
PLC_BIT_OFF(M8000);
PLC_RUN_BIT=0;
PLC_BIT_ON(M8037);
}
}
}
#ifndef debug
PLC_RUN_BIT==3;
#endif
}
}
现在PLC执行时间和三菱的一样,有的指令还快很多。
代码需要高手优化,期等高手帮忙,现在使用的MCU有大牛拉小车感觉。
现场使用的时NUCLEO—446RE核心+拆机杂牌PLC扩展使用。
欢迎大家跟帖交流!!!
后期计划
重新设计原理图,出PCB打样,电源定制,需要大电容检测断电保存数据。外壳定制。(本人不熟悉这块)希望有爱好朋友开发这块
本帖最后由 boming 于 2017-12-18 02:01 编辑