⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus_client.c

📁 458通讯
💻 C
字号:
#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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -