基于新塘51单片机的485通信
基于新塘51单片机的485通信
序言
最近有一个项目用新塘的51FB9A单片机做时控开关(上位机控制)控制继电器,但是我原来也没整过485啊,本来以为这玩意很难。没想到才了一些坑之后还觉得挺简单的。这玩意就是串口嘛。没啥难的,485都已经20年了基本上,很多资料都是大把的多。
485介绍
1. Modbus总线协议的一种。相比于232,485有更好的传输速度和更远的传输距离,更好的抗干扰性。
2. 基本上很多的远距离串行通信都是用的CANBUS和RS485,我因为工作原因所以也使用的是485。
3.回顾一下485,半双工通信,差分信号:AB线电压差来决定这个0和1(因为现在做单片机我暂时不考虑传导辐射,差分干扰等问题,这些交给硬件去解决),匹配电阻120Ω,这些都是基本了解即可。
485IC
我使用的485IC是淘宝上面那种2元一个的485模块用的IC就是MAX485,就是这玩意!相信这个引脚图已经很清晰了。
一开始的时候我就比较好奇(因为我比较菜而且也没做过485)485怎么和单片机通信的呢,后来查了一大堆资料,就是串口的串行异步通信,没啥玩意。和串口通信的最大区别就是这个使用485的时候得使能引脚。这个貌似不算什么大问题吧。
485代码
下面就是正题了,讲一讲485的通信主要是 总结一下我踩过的坑。所谓坑就是你不知道哪里有坑,只有一脚踩下去了
才发现卧槽,这竟然有个坑!
下面是我的代码,写的不好,还要继续修改,现在只是架子。这个只是其中的主要部分,有需要整个工程就把邮箱给我,我给你发过去。
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "string.h"/*
文件:TIM_Switch_485
名称:时控开关
工程师:两颗楠木
版本号:V3.0
时间:2021.6.10
功能:从上位机接收到数据控制多个单片机进而控制多个继电器开关上位机通过USB转485和单片机串口通信协议:单片机接收:01/02(0F主机信息,01从机信息)+0X(组地址)+地址(从机地址)+开关状态单片机发送:01(01从机信息)+0X(组地址)+地址(从机地址)+开关状态
备注:485总线无竞争机制,无干扰处理。
*/
#define Master_Com 0x0F//主机发送
#define Slave_Com 0x01//从机发送
#define Address_Group 0x01//高地址(分组地址)
#define Address_Slave 0x03//低地址(组内具体从机)
#define Function_number_Close 0x01//高地址
#define Function_number_Open 0x02//低地址struct DataAdress
{uint8_t *DataArray_Address;uint8_t *IndexData;
} ArrayAdress;static uint8_t *Addres ;void RS485(void)
{int i;if(*ArrayAdress.IndexData==4){EA=0;//中断保护,不利于实时性//用了全局变量就可以不用这个指针了,但是我写完了,不删除了。if(*(ArrayAdress.DataArray_Address++)==Master_Com){ if(*(ArrayAdress.DataArray_Address++)==Address_Group){if(*(ArrayAdress.DataArray_Address++)==Address_Slave){if(*(ArrayAdress.DataArray_Address)==Function_number_Close){P04=1; P05=0;//拉低发送信息Send_Data_To_UART0(Master_Com); Send_Data_To_UART0(Address_Group); Send_Data_To_UART0(Address_Slave); Send_Data_To_UART0(Function_number_Close); P05=1;}else if(*ArrayAdress.DataArray_Address==Function_number_Open){ P04=0;P05=0;Send_Data_To_UART0(Slave_Com); Send_Data_To_UART0(Address_Group); Send_Data_To_UART0(Address_Slave); Send_Data_To_UART0(Function_number_Open); P05=1;} } }/*memset函数做的事情是将一个数值复制到一片地址中,第一个参数是地址,第二个是数据最后一个是大小*/ } *ArrayAdress.IndexData=0;/*memset(Addres,NULL,4);*/for( i=0;i<4;i++){*ArrayAdress.DataArray_Address=0;ArrayAdress.DataArray_Address--;} EA=1;//解除保护}
}void main (void)
{P05_PushPull_Mode;P04_PushPull_Mode; //P05=1;P05是485IC使能脚(低电平接收)引脚已经由硬件拉高P04=0;InitialUART0_Timer1(19200);//UART0 Baudrate initial,T1M=0,SMOD=0while(1){RS485();}
} void SerialPort0_ISR(void) interrupt 4
{static uint8_t DataArray[4],Index=0,Master_Slave_Flag=0;if(RI==1) { if((Master_Com==SBUF)||Master_Slave_Flag){ Master_Slave_Flag=1; DataArray[Index++]=SBUF;if(Index==4){ArrayAdress.IndexData=&Index;Addres=ArrayAdress.DataArray_Address=DataArray; Master_Slave_Flag=0;} } }RI=0;
}
更新代码2021.6.11
注意事项
1.这个我在做的时候要清空数组和下标但是我做的时候忘记了,导致了数组越界引用,但是代码没错,只是在最后有一个提示没仔细看后来在DEBUG的时候发现这个数据不对(Index由于越界引用变成了0X0A再取余本来应该是0现在变成了2)。
2. Usrt0Dat和中断中的局部变量i:就很奇怪这个Usrt0Dat会自减(会随着这个局部变量i变化)但是程序中没有设置让他变化(自减),虽然对于程序没有什么影响,但是在监测时看到了!就很离谱!并且在程序运行到最后时i本来由0会变成1。我就很迷惑
3. 这个通信协议中最后的那个发送给上位机的值要给延时,不然在多机通信时会发生:最先发送数据的单片机可以发送应答信号,其他单片机都不能发送应答信号。或者上位机无法正常和单片机通信等情况。但是加了这个延时就好了,我真是一脸蒙圈。我为什么在这里加呢我觉得这个是因为通信协议内部原因,就想锁死接收或者演示一段时间。没想到真的可以!
4. 这一周就是在改BUG,比如说接受乱码:这个是因为AB线插反了
5. 当多机通信时出现只有一个从机正常其他从机都不能正常控制可能问题是
存储时序的数据包出现错误。(无法有效清除,或者过度清楚,Debug一下基本就没啥问题了)
6.还比如说从机正常接收数据并且可以发送数据到串口就是没输出,有可能是硬件虚焊了。
7.当有从机出现问题时可能会影响整个通信。
第一个正经的软件项目,谨以此文纪念!万事开头难,做一做就好了。非淡泊无以明志,非宁静无以致远!加油啊!
基于新塘51单片机的485通信相关推荐
- 51单片机c语言485通讯案例,485通讯协议程序怎么写(51单片机的485通信程序案例)...
RS-485总线接口是一种常用的串口,具有网络连接方便.抗干扰性能好.传输距离远等优点.RS-485收发器采用平衡发送和差分接收,因此具有抑制共模干扰的能力,加上收发器具有高的灵敏度,能检测到低达20 ...
- 【制作】基于金沙滩51单片机的电子密码锁程序
基于金沙滩51单片机的电子密码锁程序 很久之前做的一个课设,在B站发了效果视频,发现忘记分享代码了,现在整理分享一下. 零.设计报告 1.设计要求 这部分是讲的整个系统实现了什么功能. 1.1.密码的 ...
- 基于高速51单片机的模拟USB接口设计
基于高速51单片机的模拟USB接口设计 作者:廖颂文 摘要:参照AVRUSB技术给出了51单片机通过模拟USB通信的实现方法.用VC编写了上位机软件,通过libusb驱动实现了PC与ST12LE560 ...
- 51单片机与PC通信
本博客以广西大学电气工程学院陈柏轩老师编写的单片机原理与应用实验指导书为基础,建立在读者对51单片机的基本编程软件与烧录软件较为熟悉的基础上撰写. 实现51单片机与PC通信: 1.基于查询法实现通信: ...
- 51单片机stc15w204s串口通信发数据接收数据串口中断发中文字符串完美运行软件延时发送一字节函数全注释
这里写自定义目录标题 KEIL自己先调试通了然后再说下面的事 51单片机stc15w204s串口通信直接上文件 KEIL自己先调试通了然后再说下面的自己看看就可 KEIL自己先调试通了然后再说下面的事 ...
- MATLAB与51单片机进行串口通信详解
目录 一.51单片机与电脑进行串口通信 二.MATLAB串口通信函数 三.串口属性 四.示例Demo 4.1 MATLAB接收单片机发来的数据 4.2 MATLAB向单片机发送数据控制LED 五.总结 ...
- 基于Atmel 51单片机开发平台和自动控制原理的数字电压表系统
基于Atmel 51单片机开发平台和自动控制原理的数字电压表系统 ///插播一条:我自己在今年年初录制了一套还比较系统的入门单片机教程,想要的同学找我拿就行了免費的,私信我就可以哦~点我头像黑色字体加 ...
- 单片机c语言程序开发洗衣机,基于的51单片机全自动洗衣机设计(北理工
<基于的51单片机全自动洗衣机设计(北理工>由会员分享,可在线阅读,更多相关<基于的51单片机全自动洗衣机设计(北理工(24页珍藏版)>请在人人文库网上搜索. 1.全自动洗衣机 ...
- 简单双机通信java_完整版)51单片机实现双机通信(自己整理的
<完整版)51单片机实现双机通信(自己整理的>由会员分享,可在线阅读,更多相关<完整版)51单片机实现双机通信(自己整理的(6页珍藏版)>请在人人文库网上搜索. 1.PjfAl ...
最新文章
- 评论与回复php代码,php – 显示评论和回复?
- CentOS安装jdk(无需配置环境变量)
- Springboot配置不当
- 如何检测本计算机耗电量,如何查看电脑耗电量?鲁大师查看电脑使用功率的方法...
- 启动文件、简单的消息框
- git 回退上一个版本
- 在kettle中实现数据验证和检查
- 坚持就是成功,为自己的梦想全力以赴
- 【Android 教程系列第 10 篇】史上最全的 Android 应用包名汇总,含主流应用商店包名,持续更新...
- Linux中交叉编译器的安装
- Python调用百度API实现人脸融合
- Linux Command ss
- 记一个docker网络问题--network=host
- lae界面开发工具入门之介绍七--组件篇-文本篇
- 关于十七届恩智浦杯安徽赛区基础组参赛分享
- Android最全的屏幕适配
- october cms-官方文档-ajax
- java.io.FileNotFoundException: file:/xxx/xxx.jar!/BOOT-INF/classes!/xxx.xlsx (没有那个文件或目录)
- 2015-10-13 OC语言中的复合
- Mac下安装cordova-hot-code-push-cli失败