#include "modbus_client.h" #ifndef _PGM #define _PGM #include <avr/pgmspace.h> #endif //========================================= // 返回CRC校验结果 //========================================= extern unsigned int Get_CRC(BYTE *,BYTE); //========================================= // 缓冲区 //========================================= extern ADU_CONTROL adu; extern MB_INFORMATION mb_infor; extern BYTE WAIT_Time,Receive_en,WAIT_Responsion;
//======================================================================== // 设备参数表 //======================================================================== EQUIPMENT_PARAMETER EQUIPMENT_PARAMETER_TABLE[MAX_EQU_NUM]= { {0X09,0,OK,0,0x15}, //1、地址 2、类型 3、状态 4、起始寄存器 5、寄存器数量(十六位,两个字节) {0x02,1,OK,0,0x0f}, {0x11,0,OK,0,0x15}/*, {0x00,0,OK,0,0}, {0x00,0,OK,0,0}*/ };
//========================================================================== // 定时计数器1溢出中断函数 //========================================================================== ISR(SIG_OVERFLOW1) { TCNT1 = 0xf70c; //4M时0.5个字符-0.000573s产生一个中断 mb_infor.TO_times ++; if(mb_infor.TO_times == 3)mb_infor.T15_OUT = TRUE; //1.5ms延时到 if(mb_infor.TO_times == 7) { mb_infor.T35_OUT = TRUE; //3.5ms延时到 CLOSE_TIMER1(); //关定时器 } } //========================================================================== // 定时计数器0溢出中断函数 //========================================================================== ISR(SIG_OVERFLOW0) { WAIT_Time ++; if(WAIT_Time >= MAX_WAIT_TIME) { //WAIT_Time = MAX_WAIT_TIME; CLOSE_WaitResponsionClk(); //关T0中断 OPEN_USART1_ReINTERRUPT(); //关接收中断 } else TCNT0 = 0x00; //重新装入计数器初值 } //========================================================================== // USART接收中断函数 //========================================================================== ISR(SIG_UART_RECV) //串口接受中断 { BYTE Rdata; Rdata = UDR; if(Rdata == EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_ADDR) //是当前等待帧 { WAIT_Responsion = 0; //结束超时判断 Receive_en = 1; //使能接收 adu.ADULength = 0; *(adu.RxADUBuffPtr + adu.ADULength) = Rdata; //为了CRC计算方便,还是要在缓冲区存储整个PDU帧 adu.ADULength ++; CLOSE_USART1_ReINTERRUPT(); //关接收中断 OPEN_TIMER1(); //开定时器T1 } // delay_us(40); //退出时启动定时器 } //=========================================================================== // 初始化函数 //=========================================================================== //modbus状态 void MB_INFORMATION_Init(MB_INFORMATION *MBi) { MBi -> EQUIPMENT_NOW = 0; //初始化时,从第0台设备开始 // MBi -> MODBUS_STATE = (enum _MODBUS_STATE)0; MBi -> T15_OUT = FALSE; MBi -> T35_OUT = FALSE; MBi -> TO_times = 0; }
void ADU_CONTROL_Init(ADU_CONTROL *adu) { adu -> Address = 0; adu -> TxADUBuffptr = TxAdu_buf; adu -> RxADUBuffPtr = RxAdu_buf; adu -> ADULength = 0; adu -> FrameOK = FALSE; } //================================================================================ // 接收帧的处理; // 参数: 1.要处理帧的指针 2.要处理帧的长度 //================================================================================ MESSAGE_ERR message_process(BYTE *Message,BYTE len) { unsigned int CRC_data,RX_crc; RX_crc = *(adu.RxADUBuffPtr + adu.ADULength - 2)/*CRC高位*/*256 + *(adu.RxADUBuffPtr + adu.ADULength - 1)/*CRC低位*/; CRC_data = Get_CRC (adu.RxADUBuffPtr,adu.ADULength - 2); //计算CRC校验 if(CRC_data == RX_crc) //CRC校验正确 { if(bit_is_clear(*(adu.RxADUBuffPtr + 1),7)) //功能码返回正确? { if(*(adu.RxADUBuffPtr + 2) == adu.ADULength - 5) // { return NO_ERR; } else return LEN_ERR; } else return FUNC_ERR; } else return CRC_ERR; }
|