|
我采用ATMEAL 128单片机
(1)、定时中断时间间隔=10MS
(2)、串口接收采用中断方式
(3)、串口发送采用中断方式
(4)、MODBUS分析程序在主程序中执行
(5)、每次读51个INT数据
(6)、每次写51个INT数据
以下是读取保持寄存器(功能码=03)和预置多个寄存器(功能码=16)程序片段
为什么:
(1)通过上位机可以每次都正确读取到51个整数数据,
(2)而通过上位机预置51个数据给单片机时,上位机基本上收不到单片机的《应答信号》
我感觉好象是定时中断将下面一段代码打断,导致单片机CRC校验无法通过,使得上位机无法收到预置多个寄存器的应答信号
case 16: //预置多个寄存器
tempData = (USART1_mscomm_buffer[4]<<8) + USART1_mscomm_buffer[5];
tempData = tempData * 2;
tempData += 9;
if (USART1_receCount >= tempData)
{
....
if (crcData == (USART1_mscomm_buffer[tempData-2]<<8)+ USART1_mscomm_buffer[tempData-1])
} //校验通不过
(3)如果将定时中断服务程序中的代码全部屏蔽,则通过上位机预置51个数据给单片机时,上位机可以收到单片机的正确应答信号
难道是中断服务程序执行时间过长吗?
我的定时中断间隔=10ms,中断服务程序大约执行3.2ms
(4)我测试过跟置数间隔没有关系,我将上位PC机定时中断设置为每隔1秒预置一次数据,还是收不到应答。
void USART1_Modbus_Analyze(void)
{
unsigned int crcData;
unsigned int tempData;
if (USART1_receCount > 5)
{
switch (USART1_mscomm_buffer[1])
{
case 3: //读取保持寄存器
if (USART1_receCount >= 8)
{
UCSR1B &= ~BIT(7);
if (USART1_mscomm_buffer[0] == module_addr)//比较从设备地址
{
crcData = CRC16(USART1_mscomm_buffer,6);
if (crcData == (USART1_mscomm_buffer[6]<<8) + USART1_mscomm_buffer[7])
USART1_ReadRegisters();
}
USART1_receCount = 0;
USART1_checkoutError = 0;
UCSR1B |= BIT(7);
}
break;
case 16: //预置多个寄存器
tempData = (USART1_mscomm_buffer[4]<<8) + USART1_mscomm_buffer[5];
tempData = tempData * 2;
tempData += 9;
if (USART1_receCount >= tempData)
{
UCSR1B &= ~BIT(7);
if (USART1_mscomm_buffer[0] == module_addr))//比较从设备地址
{
crcData = CRC16(USART1_mscomm_buffer,tempData-2);
if (crcData == (USART1_mscomm_buffer[tempData-2]<<8)+ USART1_mscomm_buffer[tempData-1])
USART1_PresetMultipleRegisters();
}
USART1_receCount = 0;
USART1_checkoutError = 0;
UCSR1B |= BIT(7);
}
break;
}
}
}
void main(void)
{
//初始化省略
while (1)
{
USART1_Time_Proc();//超时处理
USART1_Modbus_Analyze();//MODBUS分析程序
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|