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

📄 uart_s.c

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

#define   TRUE 		1
#define   FLASE 	0
#define   BRCLK     8000000
#define   FRAMEOVERCOU  1000.0*40/BAUD 
//-------------------------------------------------
//#define   40001	   analogCurrentValue      //模拟量当前值
//#define   40002    pointPosi               //小数点位置
//#define   40003    signalInUpLimit		   //模拟量输入上限	
//#define   40004    signalInDownLimit	   //模拟量输入下限
////#define     40005	   
////#define	  40006    
//-------------------------------------------------
typedef unsigned char	uint8;
typedef unsigned int	uint16;
typedef unsigned long	uint32;

/*
//CRC 高位字节值表 
const uchar  auchCRCHi[] = { 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 
} ; 

// CRC低位字节值表 
const uchar auchCRCLo[] = { 
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 
0x43, 0x83, 0x41, 0x81, 0x80, 0x40 
} ;
*/ 

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); 
//uint16 CRC16(uint8 *puchMsg, uint16 usDataLen);
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: //请求变量
//						if(receCount >= 5)
//						{	
//							if(receBuf[0]==LocalAddr && checkoutError==0) 
//							{
//								if( RecFrameCheck(receBuf,5) )
//								{ //校验正确
//						//			readRegisters();
//								}  
//							}
//						}	
							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) )
								{//校验正确		
									
									//	    -----------eeprom test-------
//	           				  	WriteEEPROM(&receBuf[0],5,eepaddr); 
//	                   	 	 	 		eepaddr +=5;  
//	            	 				if(eepaddr>=200)  
//	            			  		        eepaddr = 0;  
			//		------------------
														
#ifdef   TEST1
 						RA1 =!RA1; 
#endif

#ifdef TEST_RB4_B
		  RB4 = !RB4;
#endif

#ifdef	TEST_RB3
     		RB3 = !RB3;
#endif

									GetKeyValue = receBuf[2]; 
					   	     	LedSSLink = GetKeyValue;	// &&&&&&&&&&
					 	 	//		LedStruct.linkLedNewDataTag = 1;
							//		LedStruct.linkLedData = GetKeyValue;
									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+(GetCntTempBuf-1))+
					(*(p_CheckData+(GetCntTempBuf-2))<<8); 
	if(CRCWord == CRC16(p_CheckData,GetCntTempBuf-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);
}

//uint16 CRC16(uint8 *puchMsg, uint16 usDataLen) 
//{ 
//	uint8 uchCRCHi = 0xFF ; // 高CRC字节初始化  
//	uint8 uchCRCLo = 0xFF ; // 低CRC 字节初始化  
//	uint32 uIndex ;  
//	while (usDataLen--)  
//	{ 
//		uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */ 
//		uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; 
//		uchCRCLo = auchCRCLo[uIndex] ; 
//	} 
//	return (uchCRCHi << 8 | uchCRCLo) ; 
//}//uint16 crc16(uint8 *puchMsg, uint16 usDataLen)
//

/*
//读寄存器
void readRegisters(void)
{
	uint8 addr;
	uint8 tempAddr;
	uint16 result;
	uint16 crcData;
	uint8 readCount;
	uint8 byteCount;
	uint8  finsh;	//1完成  0出错
	uint16 i;
	uint16 tempData = 0;	

	//addr = (receBuf[2]<<8) + receBuf[3];
	//tempAddr = addr & 0xfff;	
	addr = receBuf[3];
	tempAddr = addr;

	//readCount = (receBuf[4]<<8) + receBuf[5];	//要读的个数
	readCount = receBuf[5];

	byteCount = readCount * 2;

	for(i=0;i<byteCount;i+=2,tempAddr++)
	{
		getRegisterVal(tempAddr,&tempData);	 
		sendBuf[i+3] = tempData >> 8;   
		sendBuf[i+4] = tempData & 0xff;	  
	}

	sendBuf[0] = localAddr;
	sendBuf[1] = 3;
	sendBuf[2] = byteCount;
	byteCount += 3;
	crcData = crc16(sendBuf,byteCount);
	sendBuf[byteCount] = crcData >> 8;
	byteCount++;
	sendBuf[byteCount] = crcData & 0xff;

	sendCount = byteCount + 1;
	beginSend();
}//void readRegisters(void)


//取寄存器值 返回0表示成功
uint16 getRegisterVal(uint16 addr,uint16 *tempData)
{
	uint16 result = 0;
	uint16 tempAddr;
	
	tempAddr = addr & 0xfff;
	
	switch(tempAddr & 0xff)
	{
		case 0:
				break;
		case 1:	
				break;
		case 2:		
				break;		
		case 3:
				break;		
		case 4:
				break;		
		case 5:
				break;
		case 6:
				break;			
		case 7:
				break;		
		case 8:
				break;		
		case 9:
				break;  
		case 10:
				break;
		case 11:
				break;
		case 12:
				break;
		case 13:
				break;
		case 14:
				break;
		case 15:
				break;
		case 16:
				*tempData = testRegister;
				break;		 
		default:
				break;		
	}
	return result;
}//uint16 getRegisterVal(uint16 addr,uint16 &data)
*/




⌨️ 快捷键说明

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