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