|
发表于 2022-2-28 11:59:12
|
显示全部楼层
硬汉大哥,想请问下这个回调函数:
----------------------------------------------------------------------------
void MODS_ReciveNew(uint8_t _byte)
{
/*
3.5个字符的时间间隔,只是用在RTU模式下面,因为RTU模式没有开始符和结束符,
两个数据包之间只能靠时间间隔来区分,Modbus定义在不同的波特率下,间隔时间是不一样的,
所以就是3.5个字符的时间,波特率高,这个时间间隔就小,波特率低,这个时间间隔相应就大
4800 = 7.297ms
9600 = 3.646ms
19200 = 1.771ms
38400 = 0.885ms
*/
uint32_t timeout;
g_mods_timeout = 0;
timeout = 35000000 / SBAUD485; /* 计算超时时间,单位us 35000000*/
/* 硬件定时中断,定时精度us 硬件定时器1用于ADC, 定时器2用于Modbus */
bsp_StartHardTimer(1, timeout, (void *)MODS_RxTimeOut);
if (g_tModS.RxCount < S_RX_BUF_SIZE)
{
g_tModS.RxBuf[g_tModS.RxCount++] = _byte;
}
}
--------------------------------------------------------------------------------------
如果在每个中断里面都进行了数据写入,那么串口FIFO里的接收数据FIFO缓冲是不是失去了意义呢(想着节省内存)?因为没有用到从串口接收缓冲里以FIFO的方式去取数据而是直接中断里面取了数据。
还有一个问题,是否会出现当执行轮询函数POLL:
-------------------------------------------------------------
void MODS_Poll(void)
{
uint16_t addr;
uint16_t crc1;
/* 超过3.5个字符时间后执行MODH_RxTimeOut()函数。全局变量 g_rtu_timeout = 1; 通知主程序开始解码 */
if (g_mods_timeout == 0)
{
return; /* 没有超时,继续接收。不要清零 g_tModS.RxCount */
}
g_mods_timeout = 0; /* 清标志 */
if (g_tModS.RxCount < 4) /* 接收到的数据小于4个字节就认为错误 */
{
goto err_ret;
}
/* 计算CRC校验和 */
crc1 = CRC16_Modbus(g_tModS.RxBuf, g_tModS.RxCount);
if (crc1 != 0)
{
goto err_ret;
}
/* 站地址 (1字节) */
addr = g_tModS.RxBuf[0]; /* 第1字节 站号 */
if (addr != SADDR485) /* 判断主机发送的命令地址是否符合 */
{
goto err_ret;
}
/* 分析应用层协议 */
MODS_AnalyzeApp();
err_ret:
#if 1 /* 此部分为了串口打印结果,实际运用中可不要 */
g_tPrint.Rxlen = g_tModS.RxCount;
memcpy(g_tPrint.RxBuf, g_tModS.RxBuf, g_tModS.RxCount);
#endif
g_tModS.RxCount = 0; /* 必须清零计数器,方便下次帧同步 */
}
-----------------------------------------------------------------------
在执行过程中,下一个接收中断来了,改变了g_tModS.RxCount的值,导致后续的以g_tModS.RxCount值为判断的分支进不去而丢弃这个帧呢? |
|