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

📄 uart.c

📁 Microchip 公司16F648 芯片实现RS485通讯,符合Modbus通讯协议,可用PICC环境编译.文件完整,可供参考.
💻 C
字号:
//uart.c     
#include  "pic16f62xa.h"
#include  "pic.h"
#include  "typedefine.h"
#include  "extern.h"

#define   TRUE 		1
#define   FLASE 	0
#define   BRCLK     8000000
#define   FRAMEOVERCOU  1000.0*40/BAUD 


bank1  uchar sendBuf[16]; 
bank1  uchar receBuf[16]; 

bank1 volatile uint RCBuf; 

bank1 volatile uchar sendPosi,sendCount;     
bank1 volatile uchar receCount;//,GetCntTemp;   
bank1 volatile uchar GetCntTemp;
volatile uchar GetKeyValue;    
uchar FrameOverCou; 
uint crc_result; 
uchar RecFrameCheck(uchar *p_CheckData,uchar GetCntTempBuf); 
MyWord CRC16(MyByte *data,int iLength); 
uchar LocalAddr = 1;   // 本站地址. 



void ClearBus(char *p_cleararray,char ClearLength) 
{ 
 	do
    {
	    *p_cleararray++ = 0; 
    }
	while( --ClearLength > 0); 
}


//串口初始化
void Uart_init(void)
{
	uint BAUD;
	TRISB |= 0b00000110;
     RBPU = 0;              //使能RB弱上拉
	switch (1)     	 	 	//(SerialSet.bits.band)
	{
		case 0: 	BAUD =  4800;   break;		//波特率初始化 
		case 1: 	BAUD =  9600; 	break;		//
		case 2:		BAUD = 19200;	break;		//
		case 3:		BAUD = 38400;	break;		//
		case 4:		BAUD = 57600;	break;		//
		default:	BAUD = 38400;	break;		//
	}
	SPBRG = BRCLK/BAUD/16-1;
	FrameOverCou = (uchar)(FRAMEOVERCOU);
	FrameOverCou += 1;
	TXSTA = 0b10000100; 
	RCSTA = 0b00100000; 
	RX9 = 1;
	TX9 = 1;
//	RCSTA = 0b10100000; 
 	SPEN = 1; 


	CREN = 1;
	RCIE = 1;
//	TXEN = 1;
//	TXIE = 1;		   //从站程序.
	receCount = 0;             
}



void beginSend(void)
{
	//sendEnable();    //设为发送.
	sendPosi = 0;
	if(sendCount > 1)	
		sendCount--;
//	TX9D = ParityBit(sendBuf[0]);
	TXREG = sendBuf[0];
	TXIE = 1;       //使能发送中断.
 	TXEN = 1;		//使能发送
//	TXIE = 1;     
//	CREN = 1;
//	RCIE = 1;
//	CREN = 0;
//	RCIE = 0;
}

void En_Receive(void)
{
	//	RERECEVIE;      //设为接受.  
//	receCount = 0;
//	TXEN = 0;
//	TXIE = 0;
//	CREN = 1;
//	RCIE = 1;
}

//单键值处理 
void SinglePressKeyDip(void) 
{ 
	sendBuf[0] = 0xff;	
	sendBuf[1] = 0xaa;	
	sendBuf[2] = 0x55;				//0x55 校验确认回复. 
   	crc_result = CRC16(sendBuf,3);	
    sendBuf[3] = (uchar)(crc_result&0x00ff);      // Lo byte. 
	sendBuf[4] = (uchar)((crc_result&0xff00)>>8); // Hi byte. 
//--------
	sendCount = 5;
//----------
	beginSend();
} 

// 从站接受信息帧处理 
void ReceiveFrameDisFun(void)
{
//	uint  crcData;
//	static uchar eepaddr;
 
// 	if(receCount != 0)
// 	{
//		WriteEEPROM(&receBuf[0],5,eepaddr);
//							eepaddr++;
//							
//    	 if(eepaddr==100)
//		      eepaddr = 0;
// 	}
    
 	if(receCount>4)
	{	//校验
//		 	WriteEEPROM(&receBuf[0],5,eepaddr);    
//				 			eepaddr +=5;            
//				 			if(eepaddr>=200)         
//				 				   eepaddr = 0;    


//		if((RecFrameCheck(receBuf,receCount)==1) )//&& (checkoutError==0))
 
 
 		 		switch(receBuf[1])     	    //byte 2: Command byte.
				{	
					case 0:	
				 		  	break;
					
					case 1:	
							break;
					
					case 3:
							break;
					
					case 5:
							break;
					
					case 0xaa:
						if(receCount >= 5)
						{
#ifdef   TEST1
//							RA1 =!RA1;	 
#endif
					   //-----------eeprom test-------
//						  	WriteEEPROM(&receBuf[0],5,eepaddr);    
//				 	 	 		eepaddr +=5;  
//				 	 				if(eepaddr>=200)  
//						  		        eepaddr = 0;   
							//------------------
							if(receBuf[0]==LocalAddr  && checkoutError==0) 
							{
								if( RecFrameCheck(receBuf,5));//receCount) )
								{//交验正确							
#ifdef   TEST1
 						RA1 =!RA1;			
#endif										

#ifdef TEST_RB4_B
		  RB4 = !RB4;
#endif

									GetKeyValue = receBuf[2]; 
					 	 
									SinglePressKeyDip(); 
						 		}	                        
							} //if(receBuf[0]==LocalAddr && checkoutError==0) 
						receCount = 0;	
						checkoutError = 0;	
					    } 
							break;
							
					default:
					    	break;	 	// 错误功能码处理.
				}	//switch(receBuf[1]) 
 
	}	//	if(receCount>4)
 
	NOP();	
}  
	

	
uchar RecFrameCheck(uchar *p_CheckData,uchar GetCntTempBuf)
{	
	uint CRCWord;	
	CRCWord = *(p_CheckData+(GetCntTemp-2))+
					(*(p_CheckData+(GetCntTemp-1))<<8); 
	if(CRCWord == CRC16(p_CheckData,GetCntTemp-2))	 
	{
		return TRUE;
	}
	else
	{
		return FLASE;
	}
}	


	
MyWord CRC16(MyByte *data,int iLength)
{
 	MyByte CRC16Lo,CRC16Hi;
    MyByte CL,CH;
 	MyByte SaveHi,SaveLo;
	int i,Flag;

	CRC16Lo = 0xff;
	CRC16Hi = 0xff;
	CL = 0x01;
	CH = 0xa0;
	for(i=0; i<iLength; i++)
	{
		CRC16Lo = CRC16Lo ^ data[i];
		for( Flag=0; Flag<=7; Flag++)
		{
			SaveHi = CRC16Hi;
			SaveLo = CRC16Lo;
			CRC16Hi = CRC16Hi>>1;
			CRC16Lo = CRC16Lo>>1;

			if((SaveHi&0x01) == 0x01)
			   CRC16Lo = CRC16Lo|0x80;

			if((SaveLo&0x01) == 0x01)
			{
				CRC16Hi = CRC16Hi ^ CH; //
				CRC16Lo = CRC16Lo ^ CL; //
			}
		}
	}
	return(CRC16Hi<<8 | CRC16Lo);
}






⌨️ 快捷键说明

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