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

📄 comm485.c

📁 几个独立的关于通讯的程序
💻 C
字号:
/********************************************************************************
485总线是一种常用的工业控制总线,支持多机通信,最长通信距离可达1500米,信号抗干扰能力强。
函数功能:用485实现dsPIC30F和PIC16系列的通信,上位机位dsPIC30F
*********************************************************************************/

void __attribute__((__interrupt__)) _U2RXInterrupt(void) //串口2接收中断
{
	IFS1bits.U2RXIF=0;     
	RecvDataBuf[RecvDataLen++]=U2RXREG;    
	if(HOST_ADDRESS==RecvDataBuf[0])    
	{
		U2STAbits.ADDEN=0;           
	}    
	if(RecvDataLen-1==RecvDataBuf[1])    
	{
		if(Check_Sum(RecvDataBuf,RecvDataLen))
		{
			CheckMessageOK=1;             
			U2STAbits.ADDEN=1;             
			RecvDataLen=0;        
		}        
		else        
		{             
			CheckMessageOK=0;             
			U2STAbits.ADDEN=1;             
			RecvDataLen=0;        
		}            
	}     
}

void RS485_Init(void)
{  
	U2BRG=(FCY/16/BAUDRATE)-1;           //设置波特率为9600  
	U2MODEbits.UARTEN=0;                 //暂时关闭串口  
	U2MODEbits.PDSEL=3;                  //九位数据,无奇偶校验位  
	U2MODEbits.STSEL=0;                  //一个停止位  
	U2MODEbits.ABAUD=1;  
	U2STAbits.UTXISEL=1;                 //发送缓冲器空时,产生中断  
	U2STAbits.UTXEN=0;                   //暂时禁止发送  
	U2STAbits.URXISEL=0;  
	U2STAbits.ADDEN=1;                   //地址检测模式使能  
	U2RXREG=0X0000;                      //清发送缓冲和接受缓冲  
	U2TXREG=0X0000;  
	IFS1bits.U2TXIF = 0;  
	IFS1bits.U2RXIF = 0;                 //清除中断标志  
	IEC1bits.U2TXIE = 0;  
	IEC1bits.U2RXIE = 1;                //开启串口中断   
	IPC6bits.U2TXIP = 6;  
	IPC6bits.U2RXIP = 6;                //发送接受优先级3级 
}

void Send_Message(unsigned char Address)      //发送数据函数
{    
	unsigned int i;    
	//RECV_DISABLE;     
	//SEND_ENABLE;    
	PORTG=0x0003;   
	// U2TXREG.UTX8=1;              //&&&&&检测能不能写进地址    
	U2TXREG=(1<<8)|Address;    
	//U2TXREG=0x0155;    
	//while(!U2STA.TRMT);    
	for(i=1000;i>0;i--);                 //等待发送完毕,※※※延时是否合适    
	for(i=1000;i>0;i--);     
	for(i=9000;i>0;i--);     
	PORTG=0x0000;    
	//RECV_ENABLE;    
	//SEND_DISABLE;
}

unsigned char  Check_Sum(unsigned char *CheckData,unsigned char Len)  //校验和函数
{    
	unsigned char i;    
	unsigned char AddSum;    
	for(i=1;i<Len;i++)    
	{      
		//  CheckData+=1;        
		AddSum+=RecvDataBuf[i];    
	}    
	flag=RecvDataBuf[4];    
	if(0==AddSum) {return 1;}    
	else    {return 0;}
}

/********************************************************************************
函数功能:用485实现dsPIC30F和PIC16系列的通信,下位机为PIC16系列
*********************************************************************************/
void initial(void)           //初始化函数
{  
	GIE=0;  
	TRISD7=0;                    //置RD7为输出  
	RD7=1;  
	TRISD6=0;                    //置RD6为输出  
	RD6=1;  
	
	PCFG2=1;  
	PCFG1=1;  
	PCFG0=1;  
	TRISA=0x00;                  //定义A口RA2为输出  
	
	CSRC=1;                      //内部时钟源  
	SYNC=0;                      //异步通信方式  
	BRGH=1;                      //高速  
	SPBRG=0x81;                  //波特初值9600   
	SPEN=1;                      //允许RC6,RC7为USART引脚    
	
	TX9=1;                       //选择9位数据位  
	TXIF=0;                      //不受软件控制  
	TXEN=1;                      //发送使能  
	CREN=1;                      //允许连续接收  
	SREN=1;                      //允许单字节接收  
	ADDEN=1;                     //九位通信状态使能  
	RCIE=1;                      //接收中断使能  
	RCIF=0;                      //接收中断标志  
	RX9=1;                       //接收9位数据  
	PEIE=1;                      //外设中断允许  
	GIE=1;                       //开全局中断
}

void interrupt USART_RECEIVE_ISR(void)   //接收中断服务函数
{ 
	if(RCIF==1)    
	{      
		RCIF=0;      
		RecvAddress=RCREG;           
		if(SLAVE_ADDRESS==RecvAddress)      
			{          
				Delay(500);          
				SendDataLen=strlen(SendDataBuf)/2;          
				Send_Data(HOST_ADDRESS,SendDataLen,SendDataBuf);          
				if(RD7) RD7=0;        //发光管闪烁指示,表示正在发送数据          
				else RD7=1;          //测试点      
			}         
	}     
}

void Send_Data(unsigned char Address,unsigned char DataLen,unsigned char *PointerDataBuf)  //发送数据函数
{    
	unsigned char i;    
	unsigned char CheckSum=0;    
	SEND_ENABLE;    
	TX9D=1;    
	Send_Byte(Address);    
	TX9D=0;    
	Send_Byte(DataLen+2);    
	CheckSum+=DataLen+2;    
	for(i=0;i<DataLen;i++)
	{        
		TX9D=0;        
		Send_Byte(*(PointerDataBuf+i));        
		CheckSum+=*(PointerDataBuf+i);    
	}    
	TX9D=0;    
	Send_Byte(0-CheckSum);    
	Delay(1500);    
	RECV_ENABLE;    
}

void Send_Byte(unsigned char Data)   //发送数据
{    
	TXREG=Data;    
	while(TXIF==0);    
	TXIF=0;    
	Delay(500);
}

/********************************************************************************
注意事项:
1.硬件连接应注意阻抗匹配                  
2.ADDEN位的设置应仔细阅读手册,以确保通信无误                  
3.16位与8位通信注意数据格式
有问题请高手赐教,laosi_laosi@126.com
*********************************************************************************/

⌨️ 快捷键说明

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