51单片机485通信(时控开关)

编程入门 行业动态 更新时间:2024-10-14 00:27:49

51<a href=https://www.elefans.com/category/jswz/34/1769836.html style=单片机485通信(时控开关)"/>

51单片机485通信(时控开关)

新塘51单片机485通信总结

前因:最近要用51单片机来跑一个控制继电器的控制板。
主要应用:485通信,51单片机。


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 新塘51单片机485通信总结
  • 前言
  • 一、步骤
  • 二、遇到的问题
  • 总结


前言

项目目标:上位机通过485和新塘51单片机通信,控制1-4个时控开关控制板的继电器.

难点:
(1)单片机485通信(没作用485通信)
(2)和上位机通信的协议(这个协议太费劲)
(3)和上位机通信时上位机新建线程。


一、步骤

(1)完成PC通过485来和时控开关部分通信
(2) 完成上位机测试代码
(3)增加时控开关的错误处理,并修改协议和上位机一起测试。

二、遇到的问题

1Q:上位机接收到乱码。
A:链路链接不限问题(A,B线接反了)。
2Q:单片机在115200下无法通信。但是19200和9600OK。
A:可能是使用的初始化代码出现问题了。具体是什么问题我没有去深究。
注意:这个使用115200发送数据的时候要加延时!J = 100 ;J-- 。
代码如下(示例):

/*正确的初始化*/
void UART_Init(uint32_t Bound)
{MODIFY_HIRC(HIRC_24);P06_QUASI_MODE;P07_QUASI_MODE;UART_Open(24000000,UART0_Timer3,Bound);ENABLE_UART0_PRINTF; ENABLE_UART0_INTERRUPT;//开TI = 0;RI = 0;EA = 1;
}
/*错误的初始化*/
void InitialUART0_Timer1(UINT32 u32Baudrate)    //T1M = 1, SMOD = 1
{P06_Quasi_Mode;		//Setting UART pin as Quasi mode for transmitP07_Quasi_Mode;		//Setting UART pin as Quasi mode for transmitSCON = 0x50;     	//UART0 Mode1,REN=1,TI=1TMOD |= 0x20;    	//Timer1 Mode1set_SMOD;        	//UART0 Double Rate Enableset_T1M;clr_BRCK;        	//Serial port 0 baud rate clock source = Timer1#ifdef FOSC_160000TH1 = 256 - (1000000/u32Baudrate+1);               /*16 MHz */
#endif    	
#ifdef FOSC_166000TH1 = 256 - (1037500/u32Baudrate);         		     /*16.6 MHz */
#endifset_TR1;clr_TI;						//For printf function must setting TI = 1clr_RI;set_ES;           //enable UART interruptset_EA;           //enable global interrupt
}

3Q:时控开关通信时出现错误数据
A:在上位机和时控开关通信时出现时控开关回复的数据出现错误,但是时控开关可以相应动作并且正确回复CRC(ModBus),这遇见这个问题是时检查了一下代码并发现错误和相关警告。后来我将这个全局的数组改成了局部的数据。在每次调用时重新赋值。调用结束就回收内存。解决了在不确定的时间出现时控开关发送错误数据的问题。
注意:这个问题可能是因为单片机内存太小了,我使用的片内RAM只有256字节。这个可能是由于内存溢出了。我将这个全局数组放到局部上,Keil提示内存不对。后来百度了一下说是内存超过了片内RAM,我就改成了片外存储。就是片外存储得用DPTR指令,而且我这个数组是经常调用的。速度会慢一些。后续可能会改一下存储区域重新分配下内存。后来就没有这个发送数据数据错误的问题了。
.html
(转载)这个讲内存挺不错的。

/**/
static uint8_t TimSwitch_Agreement_Explain(void)
{uint16_t CRC_Value;uint8_t i;uint8_t CRC_Array[8] = { 0X00};uint8_t Send_Array[11]={0X00, 0X40, 0X00, 0X03, 0X00, 0X01, 0X01 , 0x00, 0X00, 0X00};	

4Q:每次发送数据延时的问题,波特率都是115200。
A:在和PC的上位机通信时单片机延时100自减就可以,但是在和X1000的芯片通信时就得10000个本征函数。这个在和PC通信时延时的时候延时10000个本征函数就会很“稳”,稳不稳我也不知道就是在PC串口助手上看接收到的数据会看起来接收的慢一点。我也不知道哪个好,就是要加延时才能正常通信。原因我也不懂!
5Q:多机通信和错误处理
A:这个控制板是多机通信,多个控制板都挂在一个485总线上。如果说多机通信有问题,那么一定是因为上位机发送给时空开关的是8个字节,但是时控开关的回复是9个字节。那么在多机通信时时控开关的回复信息将数据挂载到总线上,总线上所有的从机都会接收到9个字节。正常所有从机接收到8个字节后就去解析数据了,当有第九个数据时就会产生冲突(函数解析到一半进入中断了),为了避免这个情况1.函数解析关闭中断2.接收到第九个字节后立刻跳转到错误处理函数。

总结

万事开头难,第一个单片就的项目基本就结束了。真是不容易啊,这个项目的目标一点点变化。从一开始做引脚终端,再到做485通信,在做微光协议。再加地址判断,再换MODBUS协议,再写上位机,再加错误处理,联调。

遇到了很多小问题(1)单片机烧录问题(2)数组引用越界(3)定义数据错误:定义uint8_t,赋值时10000(用于延时计数),这尼玛就离谱,后果就是发送不出数据。(4)memset清除数组。(5)485没接触好。(6)485总线接到示波器探头会一直拉高总线等。
问题都会被解决的,没解决是没找对方法,没想对原因(这就是废话,但是真有道理)。这个项目做了两个月,本以为是做21天,但是超时这么多。代码从50行到400行。多少个我觉得我不能解决的问题,多少个我觉得很难的事,都过去了,想清楚原因,去尝试。我们失败的原因有无数个,但是我们成功的原因只有一个,那就是我们提前想到可能会出现的问题并避免了这个问题。前面有个坑,不掉进去永远不知道那里有个坑。想想可能会出现问题的地方。问题都会解决的,耐心点。有时候一个问题卡住太久了,就别机械性的去漫无目的尝试,休息下,换个思路再去试试。所有的问题会卡住都是因为不了解原理,或是对整个过程理解不充分,想一下整个过程是什么样的,实际又是什么样的。不要总是我以为,尊重事实 加油!明天会更好!

更多推荐

51单片机485通信(时控开关)

本文发布于:2024-02-27 15:13:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1707068.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:单片机   通信

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!