历经大概半个月的修修改改,期间出现了不少事情,比如电脑进水报废,考试周等影响,今天总算有了点进展。
给出下我实现的复杂的双机通讯任务需求吧,课设的任务。
这里先给出成功实现之后的图片吧。
仿真:
再给出实际的电路(这里加上了RS485,否则杜邦线直连也是可以的,只不过这样单片机得挨着,杜邦线短,另外两个单片机还得共地)搭建:
这里的门道好长,目前为止我也还只是一知半解。
一点需要明白的就是两个单片机的通讯,找到的TXD、RXD引脚与RXD、TXD杜邦线连接即可,(两个单片机紧挨着,没那么长的杜邦线)即能进行双机通讯。
另一点,有关于RS485的通讯,我现在的理解不过是为了满足工业上的需求,长距离传输(重点!),TXD、RXD的引脚加一个TTL电平转RS485模块,然后模块间用铜线相连。并且RS485是半双工通信的,所以程序需要保证主机和从机不要同时发送或者接受数据即可,其余不需要进行任何改动,就跟普通的串口异步通信一样,代码都没什么高大上的区别的。
(工业上用双绞屏蔽线,价格昂贵,只是学习用用RS485便没必要,所以随便剪了家里没用的网线,里面有两根铜线那种,或者有三根也是可以的,因为这个模块有A+、B-、接大地)
这个电路模块是成对的,双机通讯,需要两个,每个单片机配备一个。
以后还要做做多机通讯,得交给软件敲代码实现了,那么就还需要去淘宝上买一个。
在淘宝上遇到的坑挺多的,首先买到的只是个半成品,当初还不知道有个叫接线端子的东西,误以为要将铜线直接焊接到焊盘上,或者说接排针,焊盘孔径又比普通的排针孔大一圈,当时就很纠结,也是自己看到买来的单片机开发板有这么一个东西,螺丝刀拧开发现能将线固定在里面,才发觉这个好玩意,心酸。
(网页淘宝打开发现有些店家直接卖了有卖成品,省去焊接的步骤)。
以下为半成品。
(淘宝上的图片看着大,实际拿到手特别小的东西)
综上实际里用到的RS485搭建就是这样,后续得加入主机对两台从机的多机通讯。
放张使用485模块的连接图:
至于说实际中用到的各种CRC校验,ModBus协议在这里派不上用场,
另外网上的介绍也有点照本宣科,纸上谈兵的意味,看不明白,还得靠自己积累理解。
至于为什么我的硬件连接,LCD屏的位置和矩阵键盘都外接,是由于从老师那里拿来的开发板过于古老,矩阵键盘按键老化,个别按键不灵敏,并且加入矩阵键盘,原来开发板上的引脚已经通过PCB固定和LCD接口相连,只能挪出去方便给外接的矩阵键盘让路,自己再接LCD显示屏(这里的显示屏电路承接之前的博客,还是有所方便的。)
实际调试过程中,还可以用TTL转USB接口,用于单个单片机与电脑的串口通信。从老师那里拿到CP2102的USB转TTL进行调试,还是挺方便的。同时引脚上的5V和GND可以给单片机供电,只有一个外接的电源接口,另外一个单片机只能用它进行供电了。
同时串口异步通信最重要的是大局观吧,首先得知道TXD、RXD引脚很方便地可以给发送寄存器赋值TXREG=‘a(or 1)’等其他ASCII码(51单片机后续可以考虑加入多机通讯来做,TXD、RXD都相同,只是寄存器名字不同),然后TXD引脚可以发送,而不需要人为八位输出高低电平来携带信息,也就是说发送和接受已经有专门的硬件替你做了,省事,这点得知道。当然输出高低电平模拟信息发送更为底层也需要去做,这样也就更深刻,所以待探索,学这些更多的只是追求深度,而不是看看书,实际里的门道多了去,我想进一步研究有关各种ModBus协议,并加以应用,这才是将来从事电子这一行业必备的素养。
学习这回事你得知道,其实用用芯片,搭建电路这些靠经验积累,到一定阶段你会发现这些会用就可以了,难的更难,复杂的诸如芯片制造,硬件接口这些都是前人做好的,还是很方便的,不要怕难,不要怕没资源,总能自己摸索出一条道路的,毕竟还只是停留在应用层的上端,而不是底层。同时硬件跟仿真不一样的时候,95%是程序问题,而不应该责怪硬件出问题,成熟的芯片一定是经过千锤百炼的,所以态度,大局观得奠定,是最为重要的。
综上这么一堆废话,其实是对成果的一个总结,实际的代码,后续再更,如果有需要的话,可以留言我发你呀。
讲下未来的规划,首先得对串口助手里的校验各种方式要有所了解,然后进行多机通讯。
必要的话,还可以学会看看USB转TTL电平芯片手册和RS485的芯片手册,以及研究RS485模块。
2019.1.26:
更新一波关于PIC18F452与stc89c52单片机的通讯,其实也就是将之前PIC单片机作为从机的部分依葫芦画瓢移植到51里面即可,但是区别有所不同。
对于51而言,串口中断UART,发送完一个字节和接受完一个字节(在打开ES串口中断的情况下)都会进入中断,而不是能像PIC单个控制,PIC里我只打开了接受的中断,故这里面有点讲究。
与此同时区别于PIC的TXREG、RCREG的发送和接受寄存器,
和PIC类似的是,SBUF如果当接收寄存器用的话,并不能在程序里将SBUF里的内容清零,例如SBUF = 0;是不可取的,这相当于给发送寄存器赋值0x00而不是将接收寄存器里的内容清零。
PIC: RCREG = 0;这条语句让接收寄存器(ReCeive REGister)里的内容清零同样不可取
我采用覆盖的方法,即如果要只发送一个字节例如‘*’给从机,从机接受到并在while(1)判断的话,
if(RCREG == '*'){};如果没有覆盖的话,这条if语句里的内容将不断被执行,如果一次性发送两个字节,比如‘*’‘ #’那么在while(1)的循环里,if语句成立就只执行一次,下一次RCREG里为‘#“,就不会一直执行if成立后里的内容了。
区别PIC,51里的SBUF接收,我没开启中断的话,要想能在接收寄存器里装载内容,看了手册,发现每次需要让RI = 0;
再赋个实际图: