新塘51单片机485通信总结
前因:最近要用51单片机来跑一个控制继电器的控制板。 主要应用:485通信,51单片机。
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
项目目标:上位机通过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)
{
P06_Quasi_Mode;
P07_Quasi_Mode;
SCON = 0x50;
TMOD |= 0x20;
set_SMOD;
set_T1M;
clr_BRCK;
#ifdef FOSC_160000
TH1 = 256 - (1000000/u32Baudrate+1);
#endif
#ifdef FOSC_166000
TH1 = 256 - (1037500/u32Baudrate);
#endif
set_TR1;
clr_TI;
clr_RI;
set_ES;
set_EA;
}
3Q:时控开关通信时出现错误数据 A:在上位机和时控开关通信时出现时控开关回复的数据出现错误,但是时控开关可以相应动作并且正确回复CRC(ModBus),这遇见这个问题是时检查了一下代码并发现错误和相关警告。后来我将这个全局的数组改成了局部的数据。在每次调用时重新赋值。调用结束就回收内存。解决了在不确定的时间出现时控开关发送错误数据的问题。 注意:这个问题可能是因为单片机内存太小了,我使用的片内RAM只有256字节。这个可能是由于内存溢出了。我将这个全局数组放到局部上,Keil提示内存不对。后来百度了一下说是内存超过了片内RAM,我就改成了片外存储。就是片外存储得用DPTR指令,而且我这个数组是经常调用的。速度会慢一些。后续可能会改一下存储区域重新分配下内存。后来就没有这个发送数据数据错误的问题了。 https://www.cnblogs.com/jikexianfeng/p/5870357.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行。多少个我觉得我不能解决的问题,多少个我觉得很难的事,都过去了,想清楚原因,去尝试。我们失败的原因有无数个,但是我们成功的原因只有一个,那就是我们提前想到可能会出现的问题并避免了这个问题。前面有个坑,不掉进去永远不知道那里有个坑。想想可能会出现问题的地方。问题都会解决的,耐心点。有时候一个问题卡住太久了,就别机械性的去漫无目的尝试,休息下,换个思路再去试试。所有的问题会卡住都是因为不了解原理,或是对整个过程理解不充分,想一下整个过程是什么样的,实际又是什么样的。不要总是我以为,尊重事实 加油!明天会更好!
|