打印

一个电气工程师进入电子行业总结-软件篇

[复制链接]
4676|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
叶春勇|  楼主 | 2019-2-11 20:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
工控电子总结与展望(软件篇)-一个电气工程师进入电子行业的心得
本人以前是个搞自动化维护的,前年误入电子行业,伤痕累累,也收获无数。现在做个总结,希望若干年后能看到自己的成长。
用mcu系统去实现工控系统,我认为需要如下知识:
软件方向专业基础课:
1、高等数学,积分变换,复变函数,信号与系统。
论述:无
2、数字信号处理,自动控制原理。
论述:写pid程序,写软件滤波程序。要用matlab导出系数,至少要懂原理。
3、c语言,c++语言,python语言。
论述:大部分单片机都支持c语言,avr,stm32,支持c++,python语言软件库多,写个上位机界面也快。
有一定基础后,看
公开课程:
(1)计算机程序构造与解释(SICP),麻省理工。这个至少学前两章。
(2)编程范式。斯坦福。讲指针,学完,至少可用c写一些可跨平台移植的软件库。
这两个课程学完以后,在工控领域写程序无敌,并且可写软件库。软件代码可重复使用率越高。代码越写越轻松。看看开源代码,基本没问题。
不然工控系统,io点到达100个以上,代码越多,你的bug搞死你。也没法写很复杂的gui,本人曾写过一个按钮的可调节参数液晶gui(你自己试试)。没法体验编程的乐趣。
4、数据结构,编译原理,计算机图形学,操作系统,数据库原理。
论述:数据结构,必学,不然软件代码很垃圾不能看。也看不懂开源软件库,消化吸收为己使用。
编译原理,状态机部分,必学,对付工控顺控程序,游刃有余。如果能写个解释器,解释类plc堆栈指令更佳。
计算机图形学,了解下,对使用点阵液晶很有帮助。
操作系统,使用一些嵌入操作系统,需要了解一些概念。方便使用rtos或linux(树莓派等嵌入系统)。
数据库原理,如果要实现高级测试系统,进行质量跟踪。必须要学。
5、基于以太网TCPIP协议,基于CAN协议
tcpip:以stm32f407zet6为主的工控系统,推荐学习,实现modbus tcp。用光纤也可实现隔离。
can:可用于板级io扩充。高级协议,如uds通用诊断协议,canopen。通讯隔离使用光隔离或磁隔离。缺点,和pc接驳要用can卡。用于io扩充无此问题。
6、电机学,液压与气动传动。
电机学:了解各种电机,尤其步进电机,永磁三相同步电机,无刷电机。例如三相交流电机,星三角启动等。
液压与气动传动:必学,工控基础。能看懂图纸。
常用工具软件:
1、labview,组态王等。
论述:人机界面要精通一个,labview做测试设备神器。
2、matlab,octave。
论述:matlab,仿真功能强大。其中曲线拟合可用于模拟量校准,数字滤波求系数,电机控制仿真,pid仿真。必学。octave为开源系统弱于matlab。
3、modbus poll,modbus slave,虚拟串口,串口调试器,crc16计算器
论述:modbus调试必用。modbussim,开源工具。
4、arduino-avr,arduino-stm32
论述:mega32,mega2560,软件平台,软件库非常多,搭建小型人机界面神器。
5、mysql及其管理软件。
论述:耐久试验,质量追忆系统,必学。开源系统,学习曲线难,但是技术寿命长。
6、altium designer
论述:能看懂硬件io对应位置。
7、lt-spice,tina-tina
论述:电路仿真,要学。
工控系统:A类(100-1000)
定义:mcu承担控制任务,用按键,数码管,点阵液晶实现简单的人机界面。
论述:从电子层面实现工控系统主要矛盾:
缺点:
1、开发周期,电路板开发与调试,软件开发与调试。相比PLC明显劣势。
2、可调试性差,即使有mcu调试器,用于工艺调试,感觉不好用,尤其顺控系统。
3、除非有积累,电子系统稳定性稍弱。国际大厂plc,电磁兼容性绝无问题。
优点:
1、成本优势。相比国际大厂plc,成本非常低,相比国产plc,如某宝号称国产三菱plc,也有优势。对企业自研发,生产工装或测试工装,单片机预算可以用50元的。
2、可实现,实时性很高的系统。mcu专门优化,实时性比plc快,plc需用某特定中断功能,才能实现。
3、人机界面可以很好,简洁而实用,成本也低。但需精心开发,积累。plc对应此档次的为文本显示器。成本数百元。
基于上述采取如下策略:
1、在工控软件方面,要向软件库较丰富的平台靠拢。
(1)mcs51,各种液晶,led模块(tm1638),按键模块,某宝都共同支持51系统。
(2)stm32平台,号称32位51系统。
(3)arduino平台,这个平台开发工控真心快。但要自己加固外围电路。
2、在调试性方面:(这里说的调试是工艺调试,而非写单片机基础框架的调试)
(1)避免使用无串口,偏向量产的单片机。例如holtek和pic,引脚少的低成本单片机。其实正品pic也不便宜。holtek仿真须专用带v的芯片。
(2)变频器,伺服驱动器,开发难度还是难度很大,使用成品。至少第一版电路不考虑。
单片机平台:
1、MCS51,该内核已无知识产权保护,市场不垄断,多家供货商。
(1)低引脚,选择类2051,插件用dip-20。贴片soic-20,tssop-20。
(2)高引脚,选择8051,插件用dip-40,贴片使用qfp-44。
(3)51其他平台不推荐。兼容性就差,比如64脚,48脚。失去通用核的优势。
2、avr平台,因为为arduino,才学的。国外定期收割,国内定期用汇率炒作,最高可翻4倍价格。
(1)mega8a,mega32,32脚。
(2)mega128a,64-80脚。优点,双串口,8bit接口。差分adc。
(3)mega2560,100脚。同二,端口更多。
(4)缺点:涨价起来吓死人。
3、stm32平台。
1、一部到位,stm32f103z系列。无以太网时使用,开发板多,学习资料多。缺点:3.3V系统。工控5v传感器多。
2、一部到位,stm32f407z系列。需要以太网时使用。开发板多,学习资料多。缺点:3.3V系统。工控5v传感器多。
3、缺点:缺点较少,要说就是硬件相较于8位机复杂的多,手册更厚,但是适用性好。比如串口空闲中断+dma。modbus反应速度超快。可以自己试试。
4、pic平台(包括台湾克隆平台)
论述:risc平台,一个单片机一个手册,累。
此平台用的少,量产成品也用,但是逐渐用stm8af,和mc9s8汽车平台了,低引脚系列不推荐用于工控。如你对此平台熟悉,当我没说。
5、dsp平台:
论述:没用过,低端可用stm32f407z,加定点数,代替。高端,数字信号处理可用fpga+软核代替。如果你对dsp平台比较熟悉,推荐使用。
据我所知,ti的dsp软件很强大的。dsp的成本在企业自研发自用设备,不算什么。可实现非常强大的电机控制,数字信号处理。根据我的观察,arm平台很快追上。例如simd指令集(neo)
我没实践没有发言权。我还是老老实实学好数字信号处理,打好数学基础,优化算法,浮点变整数,整数变字节。
6、risc-v
论述:开源平台,软核应了解。
故此类系统推荐:
1、纯数字量,我一般都用光耦隔离。
都可,推荐stm32,stm32f030f4p6也可。推荐,低引脚的搞一套pcb,多引脚的搞一套板子。模块化的更好。
2、模拟量不隔离。
推荐,51,avr,毕竟5V传感器还是多。简化系统。8位系统还是很好用的。
3、模拟量隔离的
都可。根据系统大小决定。模拟量隔离,我一般采用磁隔离+adc(ad7606),磁隔离+tlv5616。高速光耦也行。
工控系统:B类(1000-10000)
定义:mcu承担控制任务,人机界面通常是触摸屏。io点稍多。
论述:此系统相较于A类,在人机界面方面较复杂。
(1)用点阵液晶实现汉字,图形,较折磨人。从零造车的感觉。如果你有积累,点阵液晶,可极大减低成本。触摸屏升级gui较为方便。
如果是点阵液晶,修改状态机,那就需要一定时间。工厂自研发设备不推荐。目前国产电阻屏触摸屏价格300多,开发速度很快。
(2)可用ps2数字键盘,实现较为友好输入系统。
(3)此系统要实现modbus-rtu或modbus-tcp。modbus-rtu实现很简单,arduino直接有库,不用arduino有freemodbus库。
(4)此类工控系统均不需要很强的存储功能,例如扫二维码,存储测试结果。
(5)属于较为中规中矩的工控系统。但是技术难度跟b类似,对于软件功底强的人来说,还没A类难度大。
(6)初次研发可采用,降低成本向a类靠拢。
学习方向:用嵌入式系统写gui。
工控系统:C类(10000-100000元)
定义:此类系统mcu不承担控制任务或少量实时性任务。io点较多。人机界面以计算机PC为基础。系统较为通用,通过简单更新软件可升级系统功能,而不需要烧写单片机。
论述:我在设计此类系统时,通常用于较为通用的测试设备,例如工厂的产品,有很多型号,分成几大类,做几套系统就搞定。一个新产品通常只是功能少许不一样,在硬件设计留下一定冗余度。仅更新软件。
(1)可以使用数据采集卡,完成高速采集,或用单片机采集暂时存储,然后发给上位机。
(2)硬件设计有冗余度,io模块多,通常有很多单片机,用can组网(io扩充)或以太网。
(3)可用交换机,光纤实现远程io。
(4)用labview数据库组件,实现实时曲线,历史数据。用扫码枪实现产品质量参数进入数据库。
(5)用工业摄像头,labview vison组件,实现视觉识别。
(6)使用串口实现g代码控制xy机器人。
(7)耐久试验数据采集系统。
学习方向:用嵌入式系统代替pc系统。
总结:经过这两年进入电子行业,感觉电子工程师和电气工程师的区别:
(1)电子工程师,一般都有一定的硬件基础,是电子行业的上游。电子工程师,编写过上万io点,(笔者曾参与200MW发电站机组的,软件编写,dcs厂家梯形图+顺控+功能图+指令)
大型软件能力的不多。看过很多电子工程师的代码,写大型工控程序,必死无疑。被很多if+if搞死。
推荐按plc的思维方式,写出没有if语句的工控程序。
调试各种新硬件,各种单片机,消耗了大量精力。例如写顺控程序,定时器复用,计数器复用,上升沿,下降沿。io点一多,中间变量一多,各种全局变量,软件代码没有模块化代码基本很难看懂。
干脆重写,代码直接精简。
所以电子行业做工控,在系统选择上要让自己舒服。写程序舒服,调试舒服。搭建工控基本要素,数字输入,数字输出,定时器和计数器软件框架。
(2)电气工程师做系统集成的,将各家的东西,集成起来。电气工程师需要开拓视野。电气工程师,面向的是集成。没有关注硬件。
基于逻辑的编程方式。用梯形图或指令,这种思维方式编写程序,软件代码质量可控,代码bug容易找到。对电子工程师来说,相对来说没有技术含量。但是电气工程的东西,通用性好,可维护性好。
电气工程师,梯形图顺控逻辑思维,可以带到单片机软件编写中,笔者第一次看到别人写的单片机控制程序,差点吓死,一堆if,一堆标志位。直到有一天我自己能写出,定时器,计数器框架,
数字输入滤波框架,顺控程序很好写,梯形图逻辑思维是一种良好的代码习惯,代码可控,bug好找。很多电子工程师的程序,不能写库,喜欢用全局变量,if套if这种风格不能学习。按钮滤波和工艺代码混在一起。
应该包装一下。







评论
LED2013 2020-8-30 11:02 回复TA
要全部掌握真不容易 
hotus 2019-6-28 08:54 回复TA
太棒了 
评分
参与人数 1威望 +20 收起 理由
congfenglong + 20 很给力!

相关帖子

沙发
hobbye501| | 2019-2-12 08:14 | 只看该作者
这些要素都会了 那可真是神人了

使用特权

评论回复
板凳
tom_xu| | 2019-2-12 10:45 | 只看该作者
楼主,你要会其中一项,就够你吃一辈子了。

使用特权

评论回复
地板
rankey| | 2019-2-12 11:13 | 只看该作者
电气工程师转电子工程师(软硬都能搞定的那种),那是我一辈子的梦想

使用特权

评论回复
5
tao180539| | 2019-2-12 17:15 | 只看该作者
rankey 发表于 2019-2-12 11:13
电气工程师转电子工程师(软硬都能搞定的那种),那是我一辈子的梦想

不赚钱,不用转

使用特权

评论回复
6
叶春勇|  楼主 | 2019-2-14 19:36 | 只看该作者
跟随着硬件篇的脚步,开始回顾我进入电子行业软件方面的心得。
数字输入:
1、数字输入不隔离。
笔者,刚进入电子领域,设计工控板,未使用隔离的方案。
在接入外部接线直接接入按钮。
曾经手摸按钮的接线端子,单片机居然接受指令。气缸动作。非常危险。
当时,采取的策略就是采用软件防抖。类似代码如下:
第一版本:
#define DI_FILTER_TIME 10
if(PINA.4)
{
l_acc=0;
if(++h_acc>DI_FILTER_TIME ) button=1;
}
else
{
h_acc=0;
if(++l_acc>DI_FILTER_TIME ) button=0;
}
其中防抖时间10,可修改DI_FILTER_TIME;
如果包装起来就是如下写法:
翻了翻以前的代码,这应该是第二版本。

typedef {
        unsigned input:1;
        unsigned output:1;
        unsigned char h_acc;
        unsigned char l_acc;
}DI_TYPEDEF;

void scan_di(DI_TYPEDEF *pdi)
{
        if(pdi->input)
        {
                pdi->l_acc=0;
                if(++(pdi->h_acc)>DI_FILTER_TIME) pdi->output=1;
        }
        else
        {
                pdi->h_acc=0;
                if(++(pdi->l_acc)>DI_FILTER_TIME) pdi->output=0;
        }
}

void bind_io_to_di(unsigned char value,DI_TYPEDEF *pdi)
{
        pdi->input=value;
}

使用方法:
例如avr单片机,使用pa4
DI_TYPEDEF DI[8];

while(1)
{
bind_io_to_di(PINA.4,&DI[0]);//绑定io口到虚拟数字输入上。
scan_di(&DI[0]);//扫描虚拟数字输入,也可放在定时器中断,但不能搞太多。一个数字对应一个io,一个虚拟数字输入。
if(DI[0].output)
{
        //工艺代码。
}
}

翻了翻以前的代码,这就是第二版本。
由于以前的电子工程师,底层处理代码跟工艺代码混在一起,代码可阅读性不强。所以将数字输入包装起来。不跟工艺代码混在一起。


后来由于以前在plc编程中,有数字输入的,上升沿,下降沿。
在plc编程的时候,按钮通常使用上升沿,或下降沿。
于是升级到第三版本。待续。




使用特权

评论回复
7
congfenglong| | 2019-6-3 08:15 | 只看该作者
这么多专业课都精通也是厉害,顺便说一下我的看法,数学基本的高数和线代是必须的,其他的傅里叶和拉不拉屎变换会了可干很多事情,具体的就是数据处理的问题了,就得一个一个找工具书了

使用特权

评论回复
8
叶春勇|  楼主 | 2019-6-3 10:56 | 只看该作者
congfenglong 发表于 2019-6-3 08:15
这么多专业课都精通也是厉害,顺便说一下我的看法,数学基本的高数和线代是必须的,其他的傅里叶和拉不拉屎 ...

线性代数,只拿来求2元一次方程。
不知,你对线性代数应用有什么高见。

使用特权

评论回复
评论
congfenglong 2019-6-28 11:57 回复TA
@renxiaolin :是的,工程数学都是矩阵求解,用到很多线代知识 
congfenglong 2019-6-3 13:12 回复TA
并不是二元一次方程这么简单,在电机公式里面很有用 
renxiaolin 2019-6-3 11:08 回复TA
线性代数是用来解方程,但会加深你对方程的认识 
9
lfc315| | 2019-6-3 11:57 | 只看该作者
国外定期收割,国内定期用汇率炒作,最高可翻4倍价格。
里面这句是什么鬼?

使用特权

评论回复
10
叶春勇|  楼主 | 2019-6-3 12:08 | 只看该作者
叶春勇 发表于 2019-6-3 10:56
线性代数,只拿来求2元一次方程。
不知,你对线性代数应用有什么高见。 ...

目前所知,机器学习,计算机视觉,数学基础就是线性代数。目前没有深入学习。只是用库。毕竟数学是个无底洞。

使用特权

评论回复
11
叶春勇|  楼主 | 2019-6-3 12:30 | 只看该作者
lfc315 发表于 2019-6-3 11:57
国外定期收割,国内定期用汇率炒作,最高可翻4倍价格。
里面这句是什么鬼? ...

国外的半导体,基本操作。
哄抬价格。好样年报好看点。

使用特权

评论回复
12
blade55| | 2019-6-3 15:38 | 只看该作者
做控制、数据处理、算法软件就必须学通线性代数、矩阵分析、随机信号处理只是入门。
高数就好比小学的四则运算,没它不行光有它没用。

使用特权

评论回复
13
qq779366184| | 2019-6-26 13:06 | 只看该作者
叶工,您好
   我是一名软件开发专业的毕业学生,有c基础,二级c语言等级考试也过了,现在已经在上海某个汽车电子行业的公司实习中,想成为一名电子工程师,只有c语言基础的我,怎么才能入门呢?入门之后,后面该怎么样进阶呢,我看了你的《一个电气工程师进入电子行业总结-软件篇 》之后还是很迷茫,始终找不到方向,找不到突破口,想请教您,给我一个宝贵建议

使用特权

评论回复
评论
叶春勇 2019-6-26 13:21 回复TA
已回帖 
14
dsyq| | 2019-6-26 16:18 | 只看该作者
干货!学习,致敬!

使用特权

评论回复
15
叶春勇|  楼主 | 2019-7-6 21:10 | 只看该作者
工控数字输入,定时器,计数器,代码库
plc.h
typedef struct{
    unsigned char coil:1;
    unsigned char contact:1;
    unsigned int acc;
    unsigned int set;
}TIME_RELAY;

typedef struct{
    unsigned char coil:1;
    unsigned char coil_old:1;
    unsigned char contact:1;
    unsigned char overflow:1;
    unsigned int acc;
    unsigned int set;   
}COUNTER;

typedef struct {
    unsigned char in:1;
    unsigned char out:1;
    unsigned char out_old:1;
    unsigned char rise:1;
    unsigned char fall:1;
    unsigned char high_acc:8;        
    unsigned char low_acc:8;
    unsigned char confirm_time;
}DI_FILTER;

void init_time_relay(TIME_RELAY *time_relay);
void scan_time_relay(TIME_RELAY *time_relay);
void init_counter(COUNTER *cu);
void scan_counter(COUNTER *cu);
void init_digital_input(DI_FILTER *di);
void scan_digital_input(DI_FILTER *di);
void init_plc(void);
void scan_plc(void);
unsigned char is_fall(unsigned char new,unsigned char *old);
unsigned char is_rise(unsigned char new,unsigned char *old);

plc.c
#ifndef __PLC__H__
#include "plc.h"
#define __PLC__H__
#endif
TIME_RELAY T[16];
COUNTER C[16];
DI_FILTER DI[16];
void init_time_relay(TIME_RELAY *time_relay)
{
      time_relay->coil=0;
      time_relay->contact=0;
      time_relay->acc=0;
      time_relay->set=100;
}

void scan_time_relay(TIME_RELAY *time_relay)
{
    if(time_relay->coil)
    {
        time_relay->acc++;
        if(time_relay->acc>time_relay->set) time_relay->contact=1;
    }
    else
    {
          time_relay->acc=0;
          time_relay->contact=0;
    }
}

void init_counter(COUNTER *cu)
{
    cu->coil=0;
    cu->coil_old=1;
    cu->contact=0;
    cu->acc=0;
    cu->set=0;
}
//上升沿计数器
void scan_counter_ctu(COUNTER *cu)
{
   
    if(cu->coil==1 && cu->coil_old==0) cu->acc++;
    cu->coil_old=cu->coil;
    if(cu->acc>cu->set) cu->contact=1;
}
//下降沿计数器
void scan_counter_ctd(COUNTER *cu)
{
    if(cu->coil==0 && cu->coil_old==1) cu->acc++;
    cu->coil_old=cu->coil;
    if(cu->acc>cu->set) cu->contact=1;
}

void init_digital_input(DI_FILTER *di)
{
    di->in=0;
    di->out=0;
    di->high_acc=0;
    di->low_acc=0;
    di->out_old=0;
    di->confirm_time=10;
}

void scan_digital_input(DI_FILTER *di)
{
    if(di->in)
    {
        di->high_acc++;
        if(di->high_acc>di->confirm_time) di->out=1;
        di->low_acc=0;
    }
    else
    {
        di->low_acc++;
        if(di->low_acc>di->confirm_time) di->out=0;
        di->high_acc=0;
    }
    di->rise=(di->out_old==0 && di->out==1);
    di->fall=(di->out_old==1 && di->out==0);
    di->out_old=di->out;   
}

void init_plc(void)
{
    unsigned char j=0;
    for(j=0;j<16;j++) {
        init_time_relay(&T[j]);
        init_counter(&C[j]);
        init_digital_input(&DI[j]);
    }
}

void scan_plc(void)
{
    unsigned char j=0;
    for(j=0;j<16;j++) {
        scan_time_relay(&T[j]);
    }
    for(j=0;j<4;j++) {
        scan_counter_ctu(&C[j]);
    }
    for(j=4;j<8;j++) {
        scan_counter_ctd(&C[j]);
    }
    for(j=0;j<7;j++) {
        scan_digital_input(&DI[j]);
    }
}




使用特权

评论回复
16
取个昵称好难| | 2019-8-15 18:00 | 只看该作者
rankey 发表于 2019-2-12 11:13
电气工程师转电子工程师(软硬都能搞定的那种),那是我一辈子的梦想

加油

使用特权

评论回复
17
chenyelong| | 2020-8-31 11:20 | 只看该作者
精通其中一项就是神人了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

151

主题

4800

帖子

49

粉丝