基于AVRmega128的modbus程序

来源:本站
导读:目前正在解读《基于AVRmega128的modbus程序》的相关信息,《基于AVRmega128的modbus程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《基于AVRmega128的modbus程序》的详细说明。
简介:在这里为大家提供一个可读性非常好的MODBUS源代码(1)为了加快发送采用了:数据空中断 (2)为了保证最后一个字节能够发送到上位机采用了:发送完成中断

#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&&registerAmount<=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&&registerAmount<=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&&registerAmount<=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&&registerAmount<=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;

}

提醒:《基于AVRmega128的modbus程序》最后刷新时间 2024-03-14 00:58:53,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《基于AVRmega128的modbus程序》该内容的真实性请自行鉴别。