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

📄 main.c

📁 458通讯
💻 C
字号:

#include"485.h"
#include"modbus_client.h"

extern UINT16 Get_CRC ( BYTE *, BYTE);
extern void message_storage(BYTE *,BYTE,BYTE);
extern EQUIPMENT_PARAMETER EQUIPMENT_PARAMETER_TABLE[MAX_EQU_NUM];
//extern uchar T_flag;
//extern uchar buf_p;
//extern uchar Receive_now;         
//在接收中断中,只要确认应答的设备地址正确就置位
                                   //
//===========================================
BYTE Receive_en;                   
//接收使能
//===========================================								   
BYTE WAIT_Responsion;              
//等待应答:发送完一帧请求后置位,作为持续等待标志,
//在接收中断中,如果接到这个设备的应答,只要地址正
//就可以清除从而结束超时等待;
BYTE WAIT_Time;                    //
//===========================================
//  全局变量结构体
//===========================================
MB_INFORMATION      mb_infor;
//MASTER_INFORMATION  mas_infor;
ADU_CONTROL         adu;
//===========================================
//              超时错误
//===========================================
#define MAX_CHAOSHI  3
BYTE CHAOSHI_ErrTime[MAX_EQU_NUM];         
//超时错误计数器  超过MAX_CHAOSHI次就要把
//EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQUIP_STATE
//变为ERR
//===========================================
//        帧错误
//===========================================
BYTE ZHEN_ErrTime[MAX_EQU_NUM];

int main(void)
{
    UINT16 CRC_BUF;
	BYTE CRC_CHAR;
	MESSAGE_ERR MESSAGE_err;
	//=================================================
	//                 变量初始化
	//=================================================
	WAIT_Time = 0;
	Receive_en =0;
    memset(TxAdu_buf,0,BUFSIZE);
	memset(RxAdu_buf,0,BUFSIZE);
	memset(CHAOSHI_ErrTime,0,MAX_EQU_NUM);
	memset(ZHEN_ErrTime,0,MAX_EQU_NUM);
//	Receive_now = 0;
//===========================================
	MB_INFORMATION_Init(&mb_infor);
//	MASTER_INFORMATION_Init( &mas_infor);
	ADU_CONTROL_Init(&adu);
    PORTd_INIT();
//===========================================
	cli();
	comInit();
	sei();
//	t_485("ni hao ma?\n");
//	t_485("Hello! da jia hao,wo shi tiao zao tuan zhang;\n");
	while(1)
	{
	    begin:
		//&&&&&&&&&&&&&&&&&&&&&&&
		// 拼装帧 发送帧
		//&&&&&&&&&&&&&&&&&&&&&&&
		if(!EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_ADDR/*0代表没有设备*/ &&
            EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_STATE/*设备无故障*/) 
        {
		    adu.ADULength = 0;
            *(adu.TxADUBuffptr + adu.ADULength) = 
			EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_ADDR;
			//地址
            adu.ADULength ++;
			*(adu.TxADUBuffptr + adu.ADULength) = 0x03;                    
			//功能号
			adu.ADULength ++;
			*(adu.TxADUBuffptr + adu.ADULength) = 0x00;                    
			adu.ADULength ++;
			*(adu.TxADUBuffptr + adu.ADULength) = 
			EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW]. REG_ORIGINATION;
			//起始寄存器
			adu.ADULength ++;
			*(adu.TxADUBuffptr + adu.ADULength) = 0x00;
			adu.ADULength ++;
			*(adu.TxADUBuffptr + adu.ADULength) = 
			EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].REG_NUM;
			//寄存器数量
		    adu.ADULength ++;
			CRC_BUF = Get_CRC ( adu.TxADUBuffptr, adu.ADULength  ) ;
			CRC_CHAR = (BYTE)CRC_BUF;                                    
			*(adu.TxADUBuffptr + adu.ADULength) = (BYTE)(CRC_BUF >> 4);   
			//CRC校验高四位
			adu.ADULength ++;                                         
			*(adu.TxADUBuffptr + adu.ADULength) = CRC_BUF;                 
			//CRC校验低四位
			adu.ADULength ++;
			*(adu.TxADUBuffptr + adu.ADULength) = '\n';                    
			//在帧的结尾加上‘\n’做为发送结束标志
			t_485(adu.TxADUBuffptr);                                       
			//发送帧
			adu.ADULength = 0;
			WAIT_Responsion = 1;                                         
			//使能等待标志
			OPEN_WaitResponsionClk();                                    
			//打开超时计数器T0中断
			OPEN_USART1_ReINTERRUPT();                                   
			//打开接收中断
		}
		else     //如果设备不存在或设备故障转到下一台设备
		{
			if(++mb_infor.EQUIPMENT_NOW  > MAX_EQU_NUM)        
			//查询完一遍?
			mb_infor.EQUIPMENT_NOW = 0;                         
			//设备编号从0开始
			goto begin;
		}
		while(WAIT_Responsion)                                  
		//在接收中断中如果收到当前地址选中设备的应答则清除标志,跳出循环
		{
			if(WAIT_Time >= MAX_WAIT_TIME)                       
			//超时
			{
			    //CLOSE_WaitResponsionClk();                      
				//关闭T0;
				WAIT_Time = 0;                                  
				//复位WAIT_Time
			    CHAOSHI_ErrTime[mb_infor.EQUIPMENT_NOW] ++;     
				//超时错误计数器++
				if(CHAOSHI_ErrTime[mb_infor.EQUIPMENT_NOW] >= MAX_CHAOSHI)             
				//超过最大超时错误
				{
				    EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_STATE = ERR; 
					//修改设备参数表中的状态,以后不再查询该设备
					CHAOSHI_ErrTime[mb_infor.EQUIPMENT_NOW] = 0;                       
					//超时错误计数器清0
				}	
				if(++mb_infor.EQUIPMENT_NOW  > MAX_EQU_NUM)                            
				//设备查询过来一遍?
				mb_infor.EQUIPMENT_NOW = 0;                                             
				//设备编号从0开始
				WAIT_Responsion = 0;                                                    
				//重新初始化等待回应标志
				goto begin;
			}
		}
		//&&&&&&&&&&&&&&&&&&&&&&
		//接收除地址外的其他字节
		//&&&&&&&&&&&&&&&&&&&&&&
		for(;;)
		{
			while(!(UCSRA & (1<<RXC)))
			{
				if(mb_infor.T35_OUT)
				{
					mb_infor.T35_OUT = FALSE;
					WAIT_Time = 0;             
					//WAIT_Time复位
					goto ZHEN_OVER;
				}
			}
			TCNT0 = 0x00;   
			//重新计数
			WAIT_Time = 0;  
			//中断次数清零
			delay_us(50);
			*(adu.RxADUBuffPtr + adu.ADULength) = UDR;
			adu.ADULength ++;
		}
		ZHEN_OVER:
		CLOSE_TIMER1(); //关定时器1
//================================================================
/*		           以下内容是帧处理:                            */
//================================================================
        MESSAGE_err = message_process(adu.RxADUBuffPtr,adu.ADULength);
		switch(MESSAGE_err)
		{
		    case  CRC_ERR:  ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] ++;     
			//错误计数器++
							if(ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] >= MAX_ZHENERR)                
							//超过最大超时错误
							{
								EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_STATE 
								= ERR; //修改设备参数表中的状态,以后不再查询该设备
								ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] = 0;                          
								//超时错误计数器清0
							}
                            goto begin;
			                break;
			case  FUNC_ERR://&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
			                //   这里要分析错误代码 找到原因
			                //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
			                ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] ++;     //错误计数器++
							if(ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] >= MAX_ZHENERR)                
							//超过最大超时错误
							{
								EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_STATE 
								= ERR; //修改设备参数表中的状态,以后不再查询该设备
								ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] = 0;                          
								//超时错误计数器清0
							}
			                break;
			case  LEN_ERR: ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] ++;     //错误计数器++
							if(ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] >= MAX_ZHENERR)                
							//超过最大超时错误
							{
								EQUIPMENT_PARAMETER_TABLE[mb_infor.EQUIPMENT_NOW].EQU_STATE 
								= ERR; //修改设备参数表中的状态,以后不再查询该设备
								ZHEN_ErrTime[mb_infor.EQUIPMENT_NOW] = 0;                          
								//超时错误计数器清0
							}
			                goto begin;
			                break;
		    case  NO_ERR:   message_storage(adu.RxADUBuffPtr,mb_infor.EQUIPMENT_NOW,
			                                 adu.ADULength);    //                   //存储帧
			                if(++mb_infor.EQUIPMENT_NOW  > MAX_EQU_NUM)                            
							//设备查询过来一遍?
				            mb_infor.EQUIPMENT_NOW = 0;                                             
							//设备编号从0开始
			                goto begin;
			                break;
		}
	}
}


⌨️ 快捷键说明

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