关于STM32移值FreeModbus的心得
关于FreeModbus
FreeMODBUS是一个奥地利人写的Modbus-slave协议栈。它是一个针对嵌入式应用的一个免费(自由)的通用MODBUS协议的移植。感兴趣的可自行baidu. 移值完成后可以做为Modbus-slave运行。
踩过的坑
移植工作主要需要完成的是portserial.c和porttimer.c两个文件。这里只说几个重点,其余的可参考固件库手册来完成。
1、“注意: 1.在数据传输过程中,除了在智能卡模式下,如果TE位上有个0脉冲(即设置为’0’之后再设置为’1’),会在当前数据字传输完成后,发送一个“前导符”(空闲总线)。” 这段话摘至STM32参考手册关于USART_CR1控制寄存器的TE位说明。意思是当你在初始化串口模式包含发送模式的时候,硬件会自动的先从串口发送一个字节的数据。如果你在接下来的初始程序中使能了"USART_IT_TC"中断标志位,这将会导致程序在初始化完成后紧接着就进入中断程序。。。汗。在这里踩了个坑。参考网络上其它同仁的移值过程均没有对此进行说明。
2、关于porttimer.c中TIM的设定,需要搞清楚的是原作者说的T35_50us的意思是定时器每Tick一下为50us(时基为50us),因此按照协议的规定,在波特率小于19200时根据波物率计算定时器的重载值,大于19200时直接用1800us作为两个有效帧的间隔。
3、原作者参考例子中使用TXE作为发送中断,个人建议还是使用TC中断标志比较好。使用中断标志的话,在mbrtu.c文件中使能发送中断以后要先执行一次发送,这样才可以进入到TC中断。
提供移值源码仅供参考,不足之处请指正
portserial.c
/* ----------------------- Start implementation -----------------------------/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
/ If xRXEnable enable serial receive interrupts. If xTxENable enable
* transmitter empty interrupts.
*/
if (xRxEnable == TRUE)
{
USART_ITConfig(ModBus_Port,USART_IT_RXNE,ENABLE);
}
else
{
USART_ITConfig(ModBus_Port,USART_IT_RXNE,DISABLE);
}
if (xTxEnable == TRUE)
{
USART_ITConfig(ModBus_Port,USART_IT_TC,ENABLE);
}
else
{
USART_ITConfig(ModBus_Port,USART_IT_TC,ENABLE);
}
}
BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//never change following paras
(void)ucPORT;