#include<iom128v.h>
#include<macros.h>
#define_USART1_H
#include"DMS2000.h"
constUCHARauchCRCHi[]={
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,
0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,
0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,
0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,
0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40
};
constUCHARauchCRCLo[]={
0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,
0x07,0xC7,0x05,0xC5,0xC4,0x04,0xCC,0x0C,0x0D,0xCD,
0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,
0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,
0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,0x14,0xD4,
0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,
0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3,
0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,
0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,
0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,
0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,
0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60,
0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,
0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,
0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,
0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5,
0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,
0x70,0xB0,0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,
0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C,
0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,
0x99,0x59,0x58,0x98,0x88,0x48,0x49,0x89,0x4B,0x8B,
0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,
0x43,0x83,0x41,0x81,0x80,0x40
};
BOOLvolatileUSART1_send_mark=FALSE;
UCHARvolatileUSART1_sendPosi=0;
SHORTvolatileUSART1_receCount=0;
UCHARvolatileUSART1_receTimeOut=0;
UCHARvolatileUSART1_checkoutError=0;
UCHARvolatileUSART1_sendCount=0;
UCHARUSART1_ch_type=0;
UCHARUSART1_set_number=0;
UCHARUSART1_send_buffer[MSCOMM_BUFFER_LENGTH];
UCHARUSART1_mscomm_buffer[MSCOMM_BUFFER_LENGTH];
USHORTCRC16(UCHAR*puchMsg,USHORTusDataLen)
{
UCHARuchCRCHi=0xFF;
UCHARuchCRCLo=0xFF;
ULONGuIndex;
while(usDataLen--)
{
uIndex=uchCRCHi^*puchMsg++;
uchCRCHi=uchCRCLo^auchCRCHi[uIndex];
uchCRCLo=auchCRCLo[uIndex];
}
return(uchCRCHi<<8|uchCRCLo);
}
voidUSART1_Init(SHORTMSCOMM_baud)
{
UCHARme_STOP=(UCHAR)(MSCOMM_baud&0x01);
UCHARme_UPM=(UCHAR)(MSCOMM_baud&0x06)>>0x01;
UCHARme_Baud=(UCHAR)(MSCOMM_baud&0x38)>>0x03;
UCSR1B=0x00;
UCSR1A=0x00;
UCSR1C=(1<<UCSZ10)|(1<<UCSZ11);
switch(me_STOP)
{
case0:
UCSR1C|=(0<<USBS1);
break;
case1:
UCSR1C|=(1<<USBS1);
break;
}
switch(me_UPM)
{
case0:
case1:
UCSR1C|=((0<<UPM11)|(0<<UPM10));
break;
case2:
UCSR1C|=((1<<UPM11)|(0<<UPM10));
break;
case3:
UCSR1C|=((1<<UPM11)|(1<<UPM10));
break;
}
switch(me_Baud)
{
case0:
UBRR1L=0x3F;
UBRR1H=0x02;
break;
case1:
UBRR1L=0x1F;
UBRR1H=0x01;
break;
case2:
UBRR1L=0x8F;
UBRR1H=0x00;
break;
case3:
UBRR1L=0x47;
UBRR1H=0x00;
break;
case4:
UBRR1L=0x23;
UBRR1H=0x00;
break;
case5:
UBRR1L=0x11;
UBRR1H=0x00;
break;
case6:
UBRR1L=0x0B;
UBRR1H=0x00;
break;
default:
UBRR1L=0x05;
UBRR1H=0x00;
break;
}
UCSR1B=(1<<RXEN1)|(1<<RXCIE1)|(1<<TXEN1);
}
BOOLUSART1_CoilRegistersAddr(SHORTstartAddr,SHORTregisterAmount)
{
if(registerAmount>=1&®isterAmount<=2000)
{
if(startAddr>=0&&startAddr<=4)
{
if((startAddr+registerAmount-1)<=4)
return(TRUE);
}
}
return(FALSE);
}
voidUSART1_GetCoilVal(SHORT*tempData,SHORTtempAddr)
{
switch(tempAddr)
{
case0:
*tempData=0;
break;
}
}
voidUSART1_SetCoilVal(SHORTOnOff,SHORTtempAddr)
{
}
BOOLUSART1_DiscreteRegistersAddr(SHORTstartAddr,SHORTregisterAmount)
{
if(registerAmount>=1&®isterAmount<=2000)
{
if(startAddr>=0&&startAddr<=7)
{
if((startAddr+registerAmount-1)<=7)
return(TRUE);
}
}
return(FALSE);
}
voidUSART1_GetDiscreteVal(SHORT*tempData,SHORTtempAddr)
{
switch(tempAddr)
{
case0:
*tempData=0;
break;
}
}
BOOLUSART1_InputRegisterAddr(SHORTstartAddr,SHORTregisterAmount)
{
if(registerAmount>=1&®isterAmount<=125)
{
if(startAddr>=0&&startAddr<=7)
{
if((startAddr+registerAmount-1)<=7)
return(TRUE);
}
}
return(FALSE);
}
voidUSART1_GetInputRegisterVal(SHORT*tempData,SHORTtempAddr)
{
switch(tempAddr)
{
case0:
*tempData=0;
break;
}
}
BOOLUSART1_HoldingRegisterAddr(SHORTstartAddr,SHORTregisterAmount,UCHAR*set_number)
{
if(registerAmount>=1&®isterAmount<=125)
{
if(startAddr>=0&&startAddr<BUFFER_LENGTH)
{
if((startAddr+registerAmount-1)<BUFFER_LENGTH)
{
*set_number=startAddr+1;
return(TRUE);
}
}
}
return(FALSE);
}
voidUSART1_GetHoldingRegisterVal(SHORT*tempData,UCHARset_number)
{
}
BOOLUSART1_SetHoldingRegisterVal(SHORTtempData,SHORTtempAddr)
{
return(FALSE);
}
voidUSART1_Time_Proc(void)
{
if(USART1_receTimeOut>0)
{
USART1_receTimeOut--;
if(USART1_receTimeOut==0&&USART1_receCount>0)
{
USART1_receCount=0;
USART1_checkoutError=0;
if(!USART1_send_mark)
RS485_RECIVE();
}
}
}
voidUSART1_Begin_Send(void)
{
RS485_SEND();
NOP(); // --------|
NOP(); // |
NOP(); // |-----------等待总线释放
NOP(); // |
NOP(); // --------|
NOP(); // --------|
NOP(); // |
NOP(); // |-----------等待总线释放
NOP(); // |
NOP(); // --------|
USART1_send_mark=TRUE;
USART1_sendPosi=0;
UCSR1B|=BIT(5);
}
voidUSART1_MODBUS_Error(UCHARerror_code)
{
USHORTcrcData;
USART1_send_buffer[0]=USART1_mscomm_buffer[0];
USART1_send_buffer[1]=USART1_mscomm_buffer[1]|0x80;
USART1_send_buffer[2]=error_code;
crcData=CRC16(USART1_send_buffer,3);
USART1_send_buffer[3]=crcData>>8;
USART1_send_buffer[4]=crcData&0xff;
USART1_sendCount=5;
USART1_Begin_Send();
}
voidUSART1_ReadCoilRegisters(void)
{
UCHARi,k;
UCHARbyteCount;
SHORTregisterAmount;
SHORTstartAddr;
SHORTtempAddr;
SHORTtempData;
USHORTcrcData;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
registerAmount=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_CoilRegistersAddr(startAddr,registerAmount))
{
tempAddr=startAddr;
byteCount=registerAmount>>0x03;
if(registerAmount&0x07)
byteCount++;
for(k=0;k<byteCount;k++)
{
USART1_send_buffer[k+3]=0;
for(i=0;i<8;i++)
{
USART1_GetCoilVal(&tempData,tempAddr++);
USART1_send_buffer[k+3]|=(tempData<<i);
if(tempAddr>=startAddr+registerAmount)
break;
}
}
USART1_send_buffer[0]=USART1_mscomm_buffer[0];
USART1_send_buffer[1]=USART1_mscomm_buffer[1];
USART1_send_buffer[2]=byteCount;
byteCount+=3;
crcData=CRC16(USART1_send_buffer,byteCount);
USART1_send_buffer[byteCount]=crcData>>8;
byteCount++;
USART1_send_buffer[byteCount]=crcData&0xff;
USART1_sendCount=byteCount+1;
USART1_Begin_Send();
}
else
USART1_MODBUS_Error(2);
}
voidUSART1_ReadDiscreteRegisters(void)
{
UCHARi,k;
UCHARbyteCount;
SHORTregisterAmount;
SHORTstartAddr;
SHORTtempAddr;
SHORTtempData;
USHORTcrcData;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
registerAmount=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_DiscreteRegistersAddr(startAddr,registerAmount))
{
tempAddr=startAddr;
byteCount=registerAmount>>0x03;
if(registerAmount&0x07)
byteCount++;
for(k=0;k<byteCount;k++)
{
USART1_send_buffer[k+3]=0;
for(i=0;i<8;i++)
{
USART1_GetDiscreteVal(&tempData,tempAddr++);
USART1_send_buffer[k+3]|=(tempData<<i);
if(tempAddr>=startAddr+registerAmount)
break;
}
}
USART1_send_buffer[0]=USART1_mscomm_buffer[0];
USART1_send_buffer[1]=USART1_mscomm_buffer[1];
USART1_send_buffer[2]=byteCount;
byteCount+=3;
crcData=CRC16(USART1_send_buffer,byteCount);
USART1_send_buffer[byteCount]=crcData>>8;
byteCount++;
USART1_send_buffer[byteCount]=crcData&0xff;
USART1_sendCount=byteCount+1;
USART1_Begin_Send();
}
else
USART1_MODBUS_Error(2);
}
voidUSART1_ReadHoldingRegisters(void)
{
UCHARi;
SHORTstartAddr;
SHORTregisterAmount;
SHORTbyteCount;
SHORTtempData;
USHORTcrcData;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
registerAmount=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_HoldingRegisterAddr(startAddr,registerAmount,&USART1_set_number))
{
byteCount=registerAmount<<0x01;
for(i=0;i<registerAmount;i++)
{
USART1_GetHoldingRegisterVal(&tempData,USART1_set_number++);
USART1_send_buffer[2*i+3]=tempData>>8;
USART1_send_buffer[2*i+4]=tempData&0xff;
}
USART1_send_buffer[0]=USART1_mscomm_buffer[0];
USART1_send_buffer[1]=USART1_mscomm_buffer[1];
USART1_send_buffer[2]=byteCount;
byteCount+=3;
crcData=CRC16(USART1_send_buffer,byteCount);
USART1_send_buffer[byteCount]=crcData>>8;
byteCount++;
USART1_send_buffer[byteCount]=crcData&0xff;
USART1_sendCount=byteCount+1;
USART1_Begin_Send();
}
else
USART1_MODBUS_Error(2);
}
voidUSART1_ReadInputRegisters(void)
{
UCHARi;
SHORTstartAddr;
SHORTtempAddr;
SHORTregisterAmount;
SHORTbyteCount;
SHORTtempData;
USHORTcrcData;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
registerAmount=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_InputRegisterAddr(startAddr,registerAmount))
{
tempAddr=startAddr;
byteCount=registerAmount<<0x01;
for(i=0;i<registerAmount;i++)
{
USART1_GetInputRegisterVal(&tempData,tempAddr++);
USART1_send_buffer[2*i+3]=tempData>>8;
USART1_send_buffer[2*i+4]=tempData&0xff;
}
USART1_send_buffer[0]=USART1_mscomm_buffer[0];
USART1_send_buffer[1]=USART1_mscomm_buffer[1];
USART1_send_buffer[2]=byteCount;
byteCount+=3;
crcData=CRC16(USART1_send_buffer,byteCount);
USART1_send_buffer[byteCount]=crcData>>8;
byteCount++;
USART1_send_buffer[byteCount]=crcData&0xff;
USART1_sendCount=byteCount+1;
USART1_Begin_Send();
}
else
USART1_MODBUS_Error(2);
}
voidUSART1_ForceSingleCoil(void)
{
UCHARi;
SHORTOnOff;
SHORTstartAddr;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
if(USART1_CoilRegistersAddr(startAddr,1))
{
OnOff=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
switch(OnOff)
{
case0x00:
USART1_SetCoilVal(0,startAddr);
break;
case0xFF:
USART1_SetCoilVal(1,startAddr);
break;
}
if(USART1_mscomm_buffer[0]==module_addr)
{
for(i=0;i<8;i++)
USART1_send_buffer[i]=USART1_mscomm_buffer[i];
USART1_sendCount=8;
USART1_Begin_Send();
}
}
elseif(USART1_mscomm_buffer[0]==module_addr)
USART1_MODBUS_Error(2);
}
voidUSART1_PresetSingleHoldingRegister(void)
{
UCHARi;
SHORTstartAddr;
SHORTtempData;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
tempData=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_HoldingRegisterAddr(startAddr,1,&USART1_set_number))
{
if(USART1_mscomm_buffer[0]==module_addr)
{
for(i=0;i<8;i++)
USART1_send_buffer[i]=USART1_mscomm_buffer[i];
USART1_sendCount=8;
USART1_Begin_Send();
}
if(USART1_SetHoldingRegisterVal(tempData,startAddr))
{
QUEUE_In_CRC16();
EEPROM_START();
}
}
elseif(USART1_mscomm_buffer[0]==module_addr)
USART1_MODBUS_Error(2);
}
voidUSART1_ForceMultipleCoil(void)
{
UCHARi,k;
UCHARbyteCount;
SHORTregisterAmount;
SHORTstartAddr;
SHORTtempAddr;
SHORTOnOff;
USHORTcrcData;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
registerAmount=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_CoilRegistersAddr(startAddr,registerAmount))
{
tempAddr=startAddr;
byteCount=(SHORT)USART1_mscomm_buffer[6];
if(USART1_mscomm_buffer[0]==module_addr)
{
for(i=0;i<6;i++)
USART1_send_buffer[i]=USART1_mscomm_buffer[i];
crcData=CRC16(USART1_send_buffer,6);
USART1_send_buffer[6]=crcData>>8;
USART1_send_buffer[7]=crcData&0xff;
USART1_sendCount=8;
USART1_Begin_Send();
}
for(k=0;k<byteCount;k++)
{
for(i=0;i<8;i++)
{
OnOff=USART1_mscomm_buffer[k+7]>>i;
if(OnOff&0x01)
USART1_SetCoilVal(1,tempAddr++);
else
USART1_SetCoilVal(0,tempAddr++);
if(tempAddr>=startAddr+registerAmount)
break;
}
}
}
elseif(USART1_mscomm_buffer[0]==module_addr)
USART1_MODBUS_Error(2);
}
voidUSART1_PresetMultipleHoldingRegisters(void)
{
UCHARi;
SHORTregisterAmount;
SHORTstartAddr;
SHORTtempData;
USHORTcrcData;
BOOLEnable=FALSE;
startAddr=(SHORT)(USART1_mscomm_buffer[2]<<8)+(SHORT)USART1_mscomm_buffer[3];
registerAmount=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
if(USART1_HoldingRegisterAddr(startAddr,registerAmount,&USART1_set_number))
{
if(USART1_mscomm_buffer[0]==module_addr)
{
for(i=0;i<6;i++)
USART1_send_buffer[i]=USART1_mscomm_buffer[i];
crcData=CRC16(USART1_send_buffer,6);
USART1_send_buffer[6]=crcData>>8;
USART1_send_buffer[7]=crcData&0xff;
USART1_sendCount=8;
USART1_Begin_Send();
}
for(i=0;i<registerAmount;i++)
{
tempData=(SHORT)(USART1_mscomm_buffer[i*2+7]<<8)+(SHORT)USART1_mscomm_buffer[i*2+8];
if(USART1_SetHoldingRegisterVal(tempData,startAddr++))
Enable=TRUE;
}
if(Enable)
{
QUEUE_In_CRC16();
EEPROM_START();
}
}
else
USART1_MODBUS_Error(2);
}
voidUSART1_Modbus_Analyze(void)
{
SHORTtempData;
USHORTcrcData;
if(USART1_receCount>5)
{
switch(USART1_mscomm_buffer[1])
{
case1:
if(USART1_receCount>=8)
{
UCSR1B&=~BIT(7);
if(USART1_mscomm_buffer[0]==module_addr&&USART1_checkoutError==0)
{
crcData=CRC16(USART1_mscomm_buffer,6);
if(crcData==(USHORT)(USART1_mscomm_buffer[6]<<8)+(USHORT)USART1_mscomm_buffer[7])
USART1_ReadCoilRegisters();
}
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
break;
case2:
if(USART1_receCount>=8)
{
UCSR1B&=~BIT(7);
if(USART1_mscomm_buffer[0]==module_addr&&USART1_checkoutError==0)
{
crcData=CRC16(USART1_mscomm_buffer,6);
if(crcData==(USHORT)(USART1_mscomm_buffer[6]<<8)+(USHORT)USART1_mscomm_buffer[7])
USART1_ReadDiscreteRegisters();
}
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
break;
case3:
if(USART1_receCount>=8)
{
UCSR1B&=~BIT(7);
if(USART1_mscomm_buffer[0]==module_addr&&USART1_checkoutError==0)
{
crcData=CRC16(USART1_mscomm_buffer,6);
if(crcData==(USHORT)(USART1_mscomm_buffer[6]<<8)+(USHORT)USART1_mscomm_buffer[7])
USART1_ReadHoldingRegisters();
}
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
break;
case4:
if(USART1_receCount>=8)
{
UCSR1B&=~BIT(7);
if(USART1_mscomm_buffer[0]==module_addr&&USART1_checkoutError==0)
{
crcData=CRC16(USART1_mscomm_buffer,6);
if(crcData==(USHORT)(USART1_mscomm_buffer[6]<<8)+(USHORT)USART1_mscomm_buffer[7])
USART1_ReadInputRegisters();
}
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
break;
case5:
if(USART1_receCount>=8)
{
UCSR1B&=~BIT(7);
if((USART1_mscomm_buffer[0]==module_addr||USART1_mscomm_buffer[0]==0)&&USART1_checkoutError==0)
{
crcData=CRC16(USART1_mscomm_buffer,6);
if(crcData==(USHORT)(USART1_mscomm_buffer[6]<<8)+(USHORT)USART1_mscomm_buffer[7])
USART1_ForceSingleCoil();
}
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
break;
case6:
if(USART1_receCount>=8)
{
UCSR1B&=~BIT(7);
if((USART1_mscomm_buffer[0]==module_addr||USART1_mscomm_buffer[0]==0)&&USART1_checkoutError==0)
{
crcData=CRC16(USART1_mscomm_buffer,6);
if(crcData==(USHORT)(USART1_mscomm_buffer[6]<<8)+(USHORT)USART1_mscomm_buffer[7])
USART1_PresetSingleHoldingRegister();
}
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
break;
case15:
if((USART1_mscomm_buffer[0]==module_addr||USART1_mscomm_buffer[0]==0)&&USART1_checkoutError==0)
{
tempData=(SHORT)(USART1_mscomm_buffer[6]);
tempData+=9;
if(USART1_receCount>=tempData&&USART1_receCount<MSCOMM_BUFFER_LENGTH)
{
UCSR1B&=~BIT(7);
crcData=CRC16(USART1_mscomm_buffer,tempData-2);
if(crcData==(USHORT)(USART1_mscomm_buffer[tempData-2]<<8)+(USHORT)USART1_mscomm_buffer[tempData-1])
USART1_ForceMultipleCoil();
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
}
break;
case16:
if((USART1_mscomm_buffer[0]==module_addr||USART1_mscomm_buffer[0]==0)&&USART1_checkoutError==0)
{
tempData=(SHORT)(USART1_mscomm_buffer[4]<<8)+(SHORT)USART1_mscomm_buffer[5];
tempData<<=0x01;
tempData+=9;
if(USART1_receCount>=tempData&&USART1_receCount<MSCOMM_BUFFER_LENGTH)
{
UCSR1B&=~BIT(7);
crcData=CRC16(USART1_mscomm_buffer,tempData-2);
if(crcData==(USHORT)(USART1_mscomm_buffer[tempData-2]<<8)+(USHORT)USART1_mscomm_buffer[tempData-1])
USART1_PresetMultipleHoldingRegisters();
USART1_receCount=0;
USART1_checkoutError=0;
UCSR1B|=BIT(7);
}
}
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 可靠地判断帧结束,防止通信停滞
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 利用单独的软件定时器,来判断一帧接收报文结束,可以防止若报文接收不完整,该帧通信任务无法结束而影响下一帧的接收。
//由于一帧报文中字节与字节之间的时间间隔和帧与帧之间的时间间隔相比要小得多,因此每当接收一个新字节,就启动软件定时器
//开始计时,定时器的时间设定为帧与帧的最小时间间隔。波特率不同,该时间间隔也不同。
// (1).若不到预定的时间内又接收到下一个字节,则说明一帧报文未结束,定时器重新计时;若定时器顺利计数到预定时间,就
//会触发相应的中断号,在该定时器中断子程序中设定帧结束标志字节,表明一帧报文接收完毕。
// (2).当主程序内检测到一帧报文接收完毕后,会通过核查从方地址及循环冗余校验字节是否正确来判断该帧的有效性。若确定
//接收到的是一帧发送给已方的正确报文,则会根据报文内的功能码对该帧命令进行相应的处理,并准备发送帧。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragmainterrupt_handlerUSART1_RI_ISR:iv_USART1_RX
voidUSART1_RI_ISR(void)
{
UCHARch;
UCHARstatus;
status=UCSR1A;
ch=UDR1;
if(USART1_receCount<MSCOMM_BUFFER_LENGTH)
USART1_mscomm_buffer[USART1_receCount++]=ch;
else
USART1_receCount=0;
if(status&0x1c)
USART1_checkoutError=2;
USART1_receTimeOut=3;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//由于USART1通讯模式=RS232,因此发送完最后一个字节后,无需允许《发送完成中断》,只在在RS485时才会。因为需要确认最后
//一个字节发送出去后,才能将总线置为接收状态。否则,如果不使用《发送完成中断》,而在《数据空中断》中判断如果是发送
//最后一个字节时,立即置总线为接收状态,会导致最后一个字节无法回送给上位机,导致上位机接收不到最后一个字节。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragmainterrupt_handlerUSART1_UDRE_ISR:iv_USART1_UDRE
voidUSART1_UDRE_ISR(void)
{
UDR1=USART1_send_buffer[USART1_sendPosi++];
if(USART1_sendPosi>=USART1_sendCount)
{
UCSR1B&=~BIT(5);
UCSR1B|=BIT(6);
}
}
#pragmainterrupt_handlerUSART1_TX_ISR:iv_USART1_TX
voidUSART1_TX_ISR(void)
{
USART1_checkoutError=0;
USART1_receCount=0;
RS485_RECIVE();
USART1_send_mark=FALSE;
}