打印
[STC单片机]

关于MODBUS通讯3.5字符间隔问题,请指点

[复制链接]
10527|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
KINSN33|  楼主 | 2013-8-8 22:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大侠,小弟在用STC12C5A60S2做485通讯modbus-RTU协议,多机通讯的过程中(从机程序)。
在通讯过程中,要求3.5个字符的延时,一般采用定时器中断来计时置标志完成。
而我现在的T0、T1中断均已用完,且不可复用。
此时有无其他方法解决modbus-rtu通讯中的关于3.5个字符间隔的问题。

我现在没做字符间隔处理,1主机 多从机通讯过程中,有的从机就掉了。郁闷啊。。请大侠们指点指点。

相关帖子

沙发
原野之狼| | 2013-8-8 23:06 | 只看该作者
可以使用软件定时器

使用特权

评论回复
板凳
gx_huang| | 2013-8-9 08:51 | 只看该作者
这是最基本的软件技巧。
别告诉我们,T0/T1全部用完了,无法复用了。
贴出T0/T1程序,大家看看你都干了什么用了。

使用特权

评论回复
地板
KINSN33|  楼主 | 2013-8-9 10:39 | 只看该作者
首先感谢两位的指教。现将定时器段程序贴出。并作解释。
以下采用T0与T1定时器,用来实现对外部脉冲的频率测量。
T0外部中断,用来计算外部脉冲的个数
T1定时器中断,用来50ms中断一次,若完成20次,即1秒。从而得到外部频率值。

请问此时,modbus-rtu通讯中,对3.5字符延时,该如何处理???

void T0_Init(void)
{
        TMOD |= 0x05;                                        //T0计数器方式,计算外部的脉冲个数,方式1,16位
        ET0 = 1;
//        IP = 0x08;
        TH0 = 0x00;                                               
        TL0 = 0x00;
        TR0 = 1;                                       
//        EA = 1;
}
//-----------------------------------------------
void T1_Init(void)
{                                                                        //50000uS中断一次
        TMOD |= 0x10;                                        //T1定时器方式,方式1,16位
        ET1 = 1;
//        IP = 0x08;
        TH1 = 0x49;                                                                               
        TL1 = 0x00;                                               
        TR1 = 1;
        EA = 1;
}
//-----------------------------------------------
void Time0_Routine(void) interrupt 1 using 0        //计数器方式
{                                                       
        TR0 = 0;
        TR1 = 0;
        TH0 = 0x00;                                               
        TL0 = 0x00;
        TH1 = 0x49;                                       
        TL1 = 0x00;
        TR0 = 1;
        TR1 = 1;
}
//-----------------------------------------------
void Time1_Routine(void) interrupt 3 using 1        //定时器方式
{                                                //50000uS中断一次
        TR0 = 0;
        TR1 = 0;
        RH_Temp_H = TH0;                        //读取外部脉冲个数
        RH_Temp_L = TL0;
        TH0 = 0;
        TL0 = 0;
        TH1 = 0x49;                                //重新赋值                                       
        TL1 = 0x00;
        TR0 = 1;
        TR1 = 1;
}

使用特权

评论回复
5
ccxlslr| | 2013-8-9 10:49 | 只看该作者
KINSN33 发表于 2013-8-9 10:39
首先感谢两位的指教。现将定时器段程序贴出。并作解释。
以下采用T0与T1定时器,用来实现对外部脉冲的频率 ...


3.5个时钟,你不一定要求如此严格,在不快的场合大于它就可以了。

有50ms定时器,对一个初如值为2的数据倒计时,为0截止,这样就能产生50-100ms的定时标志了。

你果你将50ms,弄得更小,比如10ms,20ms就更精确。如果单片机速度快,可以更小。
定时中断不处理复杂算法,只是判断和设置一些标志即可。

使用特权

评论回复
6
令狐神逸| | 2013-8-9 10:52 | 只看该作者
本人过去、现在以及将来都不认识楼主,且自古以来与楼主无利益关系。楼主表述之事与本人无关

使用特权

评论回复
7
xyz769| | 2013-8-9 11:04 | 只看该作者
一般不需处理,除非你的单片机特别慢,要对通讯部分做专门的优化。

从机掉队,应该是你主机软件写得有问题。

使用特权

评论回复
8
小嘿| | 2013-8-9 11:09 | 只看该作者
定时器没有用完一说,只要一个定时器,就可以催生无数个;单片机也只要一个晶振就有几个硬件定时器了

使用特权

评论回复
9
KINSN33|  楼主 | 2013-8-9 11:13 | 只看该作者
xyz769 发表于 2013-8-9 11:04
一般不需处理,除非你的单片机特别慢,要对通讯部分做专门的优化。

从机掉队,应该是你主机软件写得有问题 ...

读取地址1的命令:01 03 00 00 00 02 C4 0B
读取地址2的命令:02 03 00 00 00 02 C4 38
等等

观察以上指不难发现,发送地址1指令时,指令中含有0x02,所有从机2也进入了串口中断。
若忽略3.5字符延时处理的话,请问主从机的串口通讯该如何优化?

使用特权

评论回复
10
gx_huang| | 2013-8-9 11:36 | 只看该作者
就是说么,还有一个定时器T1,怎么说不能和其它的复用?
T0作为计数,无法再使用,但是T1基本没有什么任务,怎么不能做其它用途呢?
你的软件思路太初级了。

UART中断接收和发送数据,自动判断帧头帧尾。
定时中断监控串口数据流状态,如果发现连续3.5帧以上时间没有接收到数据,复位到帧头的状态,丢弃已经接收的数据。

使用特权

评论回复
11
gx_huang| | 2013-8-9 11:38 | 只看该作者
做的好,串口数据接收都在中断里处理,接收到一帧MODBUS数据,转移到一个缓冲,置位一个标志。
主程序只要查询标志就可以了。

使用特权

评论回复
12
coody| | 2013-8-9 11:42 | 只看该作者
就是35个位的时间

使用特权

评论回复
13
KINSN33|  楼主 | 2013-8-9 12:07 | 只看该作者
gx_huang 发表于 2013-8-9 11:36
就是说么,还有一个定时器T1,怎么说不能和其它的复用?
T0作为计数,无法再使用,但是T1基本没有什么任务 ...

不愧是 温度仪表设计专家。讲的很到位。明白了,我这就去实施。

谢谢楼上所有支持我的大神们!:handshake

使用特权

评论回复
14
草民| | 2013-8-9 13:04 | 只看该作者
按照楼主的软件思路,要是用PIC中低端的片子,只有一个中断入口,岂不啥都干不了了

使用特权

评论回复
15
xyz769| | 2013-8-9 13:43 | 只看该作者
KINSN33 发表于 2013-8-9 11:13
读取地址1的命令:01 03 00 00 00 02 C4 0B
读取地址2的命令:02 03 00 00 00 02 C4 38
等等

主机在发送指令之间,间隔一定时间就可,不一定非要3.5字符延时。但不能小于3.5字符时间。

使用特权

评论回复
16
baiyunfei.k.f| | 2013-8-9 13:53 | 只看该作者
即使UART占用一个timer,还有PCA呢

使用特权

评论回复
17
jiabin1024| | 2013-8-9 14:29 | 只看该作者
楼主还没转过弯来,一个定时器可以当成多个定时器使用的

使用特权

评论回复
18
红金龙吸味| | 2013-8-9 15:24 | 只看该作者
3.5字符时间,不需要抠的那么准。大于它即可。

使用特权

评论回复
19
lk07828| | 2013-8-9 15:58 | 只看该作者
定时器不会用完的,楼主

使用特权

评论回复
20
流水无意| | 2013-8-9 16:24 | 只看该作者
用一个定时器做个基本节拍,,再用这个节拍派生出若干个定时器了,就可以了
借鉴一下简易的OS的思路

使用特权

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

本版积分规则

3

主题

13

帖子

0

粉丝