本帖最后由 huzhiyang 于 2020-6-30 22:22 编辑
modbus最底层就是基于uart的,我们移植的时候主要的是两个文件,一个c文件提供板级uart的相关接口,用于收发数据;一个c文件提供板级定时器相关接口,用于判断接收发送超时。
我有两个疑问:
1.在串口接收中断里面调用了modbus提供的处理函数,但这个函数里面有很多判断,还有开定时器,我不明白,如果是115200这种频率比较高的波特率,在中断里面有过多的判断,不会引起数据丢失吗?
我测器来好像会有这个问题,我记得几年前用freescale的M4的芯片时,当时用的是120M的主频,我在串口接收中断里面多加了几个判断,就导致接收数据会丢,后来改成9600才解决。
现在用的单片机是EFM32的,使用的片内28M RC振荡器,测试下来问题很大: 我在串口中断里面用数组接收能完全收到:
void LEUART0_IRQHandler(void)
{
rx_buff[rx_idx++] = LEUART_Rx(LEUART0);
if(USART_IEN_TXC == (LEUART_IntGet(LEUART0) & USART_IEN_TXC)) /*当前是发送完成中断*/
{
prvvUARTTxReadyISR();
}
else if(USART_IEN_RXDATAV == (LEUART_IntGet(LEUART0) & USART_IEN_RXDATAV))
{
prvvUARTRxISR();
}
}
但是如果放在prvvUARTRxISR里面就接收不完全了,我发送才5个字节,仿真的时候看那个全局数组,有的时候接收3个字节,有的时候接收2个字节。
static void prvvUARTRxISR( void )
{
rx_buff[rx_idx++] = LEUART_Rx(LEUART0);
pxMBFrameCBByteReceived( );
}
void LEUART0_IRQHandler(void)
{
if(USART_IEN_TXC == (LEUART_IntGet(LEUART0) & USART_IEN_TXC)) /*当前是发送完成中断*/
{
prvvUARTTxReadyISR();
}
else if(USART_IEN_RXDATAV == (LEUART_IntGet(LEUART0) & USART_IEN_RXDATAV))
{
prvvUARTRxISR();
}
}
2.我看modbus在初始化时钟的时候,大于19200的时候,超时时间设置的是1800us,也就是1.8ms, 这个可以理解,毕竟115200的波特率1ms能接收到11个字节,也就是说接收一个字节的时间0.1ms都不到。
再来看看9600的波特率,设置的时间是4ms,9600的波特率接收一个字节的时间差不多是1ms,4ms的时间应该也没问题,但还是接上面的话题,如果主频慢的话,4ms超时不一定够吧?
3.难道主频低的单片机玩不了modbus吗?大家是怎么玩modbus的呢,期待大家的建议。
|