亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? can.c

?? Microchip PIC18F 設備驅動代碼 CAN部分
?? C
?? 第 1 頁 / 共 2 頁
字號:

	CIOCON = 0x20;						//Drive TX pin Vdd when recessive, disable capture

#ifdef CAN_LOW_INT
	IPR3 = 0x00;
#else
	IPR3 = 0xFF;
#endif

#ifdef USE_LOOPBACK_MODE
	CANCON = (LOOPBACK_MODE & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF));					//Set loopback mode for debug purposes only
	while((CANSTAT & MODE_MASK) != (LOOPBACK_MODE & MODE_MASK));	//Wait until loopback mode is set
#else
	CANCON = (NORMAL_MODE & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF));					//Set normal mode
	while((CANSTAT & MODE_MASK) != (NORMAL_MODE & MODE_MASK));		//Wait until normal mode is set
#endif
	PIE3 = CAN_INT_BITS & 0xE3;			//Enable CAN interrupts except TX interrupts
	PIR3 = 0x18;						//Set TXB1 & TXB2 int flags

//Send my address to notify our presence
#ifdef MY_ADDRESS_IS_STANDARD
	TXB0SIDL = (unsigned char)(MY_ADDRESS_IDENTIFIER << 5);
	TXB0SIDH = (unsigned char)(MY_ADDRESS_IDENTIFIER >> 3);		//Load address with MY_ADDRESS_IDENTIFIER standard identifier
	TXB0DLC = 0x00;												//0 data bytes to send
	TXB0CON = 0x00;												//Initiate transmission
	TXB0REQ = 1;
#else
	TXB0EIDL = (unsigned char)(MY_ADDRESS_IDENTIFIER & 0xFF);	//Load address with MY_ADDRESS_IDENTIFIER extended identifier
	TXB0EIDH = (unsigned char)((MY_ADDRESS_IDENTIFIER >> 8) & 0xFF);
	TXB0SIDL = (unsigned char)((MY_ADDRESS_IDENTIFIER >> 16) & 0x03) | (unsigned char)((ACCEPTANCE_FILTER_2 >> 13) & 0xE0) | 0x08;
	TXB0SIDH = (unsigned char)((MY_ADDRESS_IDENTIFIER >> 21) & 0xFF);
	TXB0DLC = 0x00;												//0 data bytes to send
	TXB0CON = 0x00;												//Initiate transmission
	TXB0REQ = 1;
#endif
	
	return 0;
}


/*********************************************************************
 * Function:        void CANISR(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    Will modify the RX/TX interrupt flags 
 *                  and interrupt enable bits
 *
 * Overview:        Checks if a CAN reception/transmission was complete 
 *                  and if so write/read to the CAN RX/TX FIFO buffers
 *
 * Note:            This function is supposed to be called from the ISR
 ********************************************************************/
void CANISR(void)
{
	unsigned char TempCANCON;

	if(PIR3 & PIE3)
	{
		TempCANCON = CANCON;
		
		if(RXB0IF && RXB0IE)
		{
			RXB0IF = 0;		//Clear interrupt flag
			CANCON = CANCON & 0xF0 | RXB0Interrupt;
			CANGetMessage();
		}
		else if(RXB1IF && RXB1IE)
		{
			RXB1IF = 0;		//Clear interrupt flag
			CANCON = CANCON & 0xF0 | RXB1Interrupt;
			CANGetMessage();
		}
		else if(TXB0IF && TXB0IE)
		{
			CANCON = CANCON & 0xF0 | TXB0Interrupt;
			if(CANPutMessage())
				TXB0IE = 0;
			else
				TXB0IF = 0;
		}
		else if(TXB1IF && TXB1IE)
		{
			CANCON = CANCON & 0xF0 | TXB1Interrupt;
			if(CANPutMessage())
				TXB1IE = 0;
			else
				TXB1IF = 0;
		}
		else if(TXB2IF && TXB2IE)
		{
			CANCON = CANCON & 0xF0 | TXB2Interrupt;
			if(CANPutMessage())			//if there wasn't any more messages to send
				TXB2IE = 0;				//disable interrupts for TXB2 and leave TXB2IF 
			else						//still on so PutCAN() can reenable the interrupt and instantly vector to ISR
				TXB2IF = 0;				//message was sent, just clear the interrupt flag.
		}
		else if(ERRIF && ERRIE)
		{
			ERRIF = 0;			//Clear interrupt flag
#ifdef CAN_ERROR_HANDLER_ENABLE
			CANErrorHandler();
#endif			
								//No error handler implemented!!!
		}
		else if(WAKIF && WAKIE)
		{
			WAKIF = 0;			//Clear interrupt flag
		}

		CANCON = TempCANCON;
	}
}


/*********************************************************************
 * Function:        void CANGetMessage(void)
 *
 * PreCondition:    <WIN2:WIN0> in the CANCON register has to set
 *                  to reflect the desired RXB registers
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    Will modify the RX FIFO Write pointer (RXWPtr)
 *
 * Overview:        Gets the registers for a RXB and puts them in the
 *                  CAN Receive buffer
 *
 * Note:            Care is not taken if buffer is full
 ********************************************************************/
void CANGetMessage(void)
{
	unsigned char i;
	if(++RXWPtr >= RXBUF)		//If pointer overflowed
		RXWPtr = 0;				//Clear it
	
	for(i=0;i<14;i++)
	{
		RXMessage[RXWPtr].Data[i] = *(unsigned char *)(0xF60+i);
	}
	RXB0FUL = 0;
}


/*********************************************************************
 * Function:        char CANPutMessage(void)
 *
 * PreCondition:    <WIN2:WIN0> in the CANCON register has to set
 *                  to reflect the desired TXB registers
 *
 * Input:           None
 *
 * Output:          0 -> A new message has been put in the transmit queue
 *                  1 -> There was no messages in the TX buffer to send
 *
 * Side Effects:    Will modify the TX buffer磗 Read pointer (TXRPtr)
 *
 * Overview:        Checks if there is any messages to transmit and if so
 *                  place it in the registers reflected by <WIN2:WIN0> 
 *
 * Note:            None
 ********************************************************************/
char CANPutMessage(void)
{
	unsigned char i;
	if(TXWPtr != TXRPtr)						//If there are any more data to send
	{
		if(++TXRPtr >= TXBUF)					//then increment the TX read pointer
			TXRPtr = 0;
		for(i=0;i<14;i++)
			*(unsigned char *)(0xF60+i) = TXMessage[TXRPtr].Data[i];
		RXB0RTRRO = 1;							//TXREQ = 1;
		return 0;
	}
	else
		return 1;
}


/*********************************************************************
 * Function:        char CANPut(struct CANMessage Message)
 *
 * PreCondition:    None
 *
 * Input:           A CAN message
 *
 * Output:          1 -> Failed to put a CAN on the buffer, buffer is full
 *                  0 -> The CAN message is put on the buffer and will be 
 *                       transmitted eventually 
 *
 * Side Effects:    Will modify the TX Buffer register磗 Write pointer
 *
 * Overview:        Initially checks if at least one buffer slot is available
 *                  and if so push the requested message in the buffer.
 *                  Checks if the TX modules are idle and if they are, reactivate one.
 *
 * Note:            None
 ********************************************************************/
char CANPut(struct CANMessage Message)
{
	unsigned char TempPtr, i;
	if(TXWPtr == TXRPtr-1 || (TXWPtr == TXBUF-1 && TXRPtr == 0))	//if all transmit buffers are full return 1
		return 1;
		
	//Do not modify the TX pointer until the message has been successfully copied so the CANISR don't
	//send a message that isn't ready
	if(TXWPtr >= TXBUF-1)					//check if transmit write pointer will overflow
	{
		TempPtr = 0;							//and post clear write pointer
	}
	else
	{
		TempPtr = TXWPtr+1;							//and postincrement write pointer
	}
	
	if(Message.NoOfBytes > 8)					//Ensure we don't handle more than 8 bytes
		Message.NoOfBytes = 8;	
		
	TXMessage[TempPtr].Specific.TXBDLC.Byte = Message.NoOfBytes;				//Set the data count

	if(!Message.Remote)			//If dataframe
	{
		TXMessage[TempPtr].Specific.TXBDLC.Bits.TXRTR = 0;								//Clear the Remote Transfer Request bit
		
		for(i = 0; i < Message.NoOfBytes; i++)	//Load data registers
		{
			TXMessage[TempPtr].Specific.TXBD.Array[i] = Message.Data[i];
		}
	}
	else											//Remote frame
	{
		TXMessage[TempPtr].Specific.TXBDLC.Bits.TXRTR = 1;								//Set TXRTR bit
	}
	if(Message.Ext)						//Extended identifier
	{
		TXMessage[TempPtr].Specific.TXBEIDL.Byte = (unsigned char)(Message.Address & 0xFF);			// Put address <7:0> in EIDL
		TXMessage[TempPtr].Specific.TXBEIDH.Byte = (unsigned char)((Message.Address >> 8) & 0xFF);	// Put address <15:8> in EIDH
		TXMessage[TempPtr].Specific.TXBSIDL.Byte = (unsigned char)((Message.Address >> 16) & 0x03) | (unsigned char)((Message.Address >> 13) & 0xE0);
		TXMessage[TempPtr].Specific.TXBSIDH.Byte = (unsigned char)((Message.Address >> 21) & 0xFF);
		TXMessage[TempPtr].Specific.TXBSIDL.Bits.EXIDE = 1;
	}
	else											//Standard identifier
	{
		TXMessage[TempPtr].Specific.TXBSIDL.Byte = (unsigned char)((Message.Address << 5) & 0xFF);	//Put address <2:0> in SIDL
		TXMessage[TempPtr].Specific.TXBSIDH.Byte = (unsigned char)((Message.Address >> 3) & 0xFF);	//Put address <10:3> in SIDH
		TXMessage[TempPtr].Specific.TXBSIDL.Bits.EXIDE = 0;
	}
	TXMessage[TempPtr].Specific.TXBCON.Byte = Message.Priority & 0x03;	//Set the internal priority of the data frame
	
	TXWPtr = TempPtr;

	//Reenable an interrupt if it is idle, it doesn't matter if another TX source caught the pending message
	//before the source that is enabled here does since the interrupt CHECKS if there are any messages pending
	//and if the buffer is empty, it will disable itself again.
	if(!TXB0IE)			//TXB0 is idle
		TXB0IE = 1;		//enable TXB0 to fire an interrupt to send the pending message
	else if(!TXB1IE)		//else if TXB1 is idle
		TXB1IE = 1;		//same procedure
	else if(!TXB2IE)		//finally try TXB2
		TXB2IE = 1;	

	return 0;
}


/*********************************************************************
 * Function:        char CANRXMessageIsPending(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          1 -> At least one received message is pending in the RX buffer
 *                  0 -> No received messages are pending
 *
 * Side Effects:    None
 *
 * Overview:        Checks if the RX Write pointer is equal to RX Read pointer and
 *                  if so returns 0, else returns 1
 *
 * Note:            Since no care is taken if the buffer overflow
 *                  this function has to be polled frequently to
 *                  prevent a software receive buffer overflow
 ********************************************************************/
char CANRXMessageIsPending(void)
{
	if(RXWPtr != RXRPtr)
		return 1;
	else
		return 0;
}



/*********************************************************************
 * Function:        struct CANMessage CANGet(void)
 *
 * PreCondition:    An unread message has to be in the buffer
 *                  use RXCANMessageIsPending(void) prior to 
 *                  calling this function in order to determine
 *                  if an unread message is pending.
 *
 * Input:           None
 *
 * Output:          The received message
 *
 * Side Effects:    Will modify the RX Buffer register磗 Read pointer
 *
 * Overview:        Pops the the first message of the RX buffer
 *
 * Note:            None
 ********************************************************************/
struct CANMessage CANGet(void)
{
	struct CANMessage ReturnMessage;
	unsigned char TempPtr, i;

	/*Do not modify the RX pointer until the message has been successfully
	  copied to prevent ISR to overwrite it (Note. this is not implemented in the ISR yet)*/
	if(RXRPtr >= RXBUF-1)					//Check if pointer will overflow
	{
		TempPtr = 0;
	}
	else
	{
		TempPtr = RXRPtr+1;
	}
	
	ReturnMessage.NoOfBytes = RXMessage[TempPtr].Specific.RXBDLC.Byte & 0x0F;					//copy data count
	if(RXMessage[TempPtr].Specific.RXBCON.Bits.RXRTRRO)	//Remote frame request
	{
		ReturnMessage.Remote = 1;
	}
	else				//Data frame 
	{
		ReturnMessage.Remote = 0;									//Clear remote flag
		for(i = 0; i < ReturnMessage.NoOfBytes; i++)				//copy data content
			ReturnMessage.Data[i] = RXMessage[TempPtr].Specific.RXBD.Array[i];
	}
	CANCON = CANCON & 0xF0;
	
	ReturnMessage.Address = (unsigned int)(RXMessage[TempPtr].Specific.RXBSIDH.Byte) << 3;			//Load the standard identifier into the address
	ReturnMessage.Address |= (RXMessage[TempPtr].Specific.RXBSIDL.Byte >> 5);

	if(RXMessage[TempPtr].Specific.RXBSIDL.Bits.EXID)				//Extended identifier
	{
		ReturnMessage.Ext = 1;										//Set the extended identifier flag
		ReturnMessage.Address = (ReturnMessage.Address << 2) | (RXMessage[TempPtr].Specific.RXBSIDL.Byte & 0x03);
		ReturnMessage.Address = ReturnMessage.Address << 16;		//and copy the extended address 
		ReturnMessage.Address |= (unsigned int)(RXMessage[TempPtr].Specific.RXBEIDH.Byte) << 8;
		ReturnMessage.Address |= RXMessage[TempPtr].Specific.RXBEIDL.Byte;		
	}
	else								//Standard identifier
	{
		ReturnMessage.Ext = 0;		//clear the extended identifier flag
	}
	
	RXRPtr = TempPtr;
	return ReturnMessage;		
}


/*********************************************************************
 * Function:        void CANSetMode(unsigned char Mode)
 *
 * PreCondition:    None
 *
 * Input:           Desired CAN Mode
 *                  (CAN_LISTEN_MODE, CAN_LOOPBACK_MODE
 *                   CAN_DISABLE_MODE, CAN_NORMAL_MODE)
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Requests to set the desired mode and waits until
 *                  the mode has been set.
 *
 * Note:            If USE_LOOPBACK_MODE is defined the requested
 *                  mode will be loopback mode if the input is
 *                  Normal mode
 ********************************************************************/
void CANSetMode(unsigned char Mode)
{
#ifdef USE_LOOPBACK_MODE
	if(Mode == NORMAL_MODE)
	{
		CANCON = (LOOPBACK_MODE & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF));
		while((CANSTAT & MODE_MASK) != (LOOPBACK_MODE & MODE_MASK));	
	}
	else
#endif
	{
		CANCON = (Mode & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF));
		while((CANSTAT & MODE_MASK) != (Mode & MODE_MASK));
	}

}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美午夜不卡在线观看免费| 日韩亚洲欧美综合| 在线观看三级视频欧美| 国产精品污污网站在线观看| 老汉av免费一区二区三区 | 亚洲精品一区二区三区福利| 日韩av电影免费观看高清完整版| av午夜一区麻豆| 国产欧美一区二区精品婷婷 | 狠狠色丁香婷婷综合久久片| 欧美另类videos死尸| 午夜一区二区三区视频| 欧美丝袜丝nylons| 亚洲成精国产精品女| 欧美午夜理伦三级在线观看| 亚洲成年人网站在线观看| 欧美少妇xxx| 亚洲成av人片在线观看无码| 91精品一区二区三区在线观看| 亚洲精品成人天堂一二三| 99在线精品视频| 亚洲一区二区三区激情| 欧美三片在线视频观看| 日韩av中文在线观看| 日韩欧美国产综合一区| 成人小视频在线| 亚洲一区二区高清| 亚洲精品在线免费播放| 91麻豆视频网站| 午夜精品久久久久| 2023国产精华国产精品| 成人国产免费视频| 天堂一区二区在线免费观看| 精品国产乱码久久| 一本高清dvd不卡在线观看| 亚洲成a人v欧美综合天堂| 国产日韩欧美不卡| 欧美网站大全在线观看| 成人性生交大片| 国产曰批免费观看久久久| 亚洲综合色丁香婷婷六月图片| www国产成人| 日韩一区二区三区观看| 欧美在线高清视频| www.亚洲色图.com| 国产suv精品一区二区6| 理论片日本一区| 婷婷开心激情综合| 亚洲动漫第一页| 亚洲精品国产品国语在线app| 久久综合久久鬼色中文字| 555夜色666亚洲国产免| 欧美性色欧美a在线播放| 成人18视频在线播放| 国产精品自拍网站| 久久精品国产一区二区三区免费看 | 亚洲一区免费观看| 国产精品久久久久aaaa| 国产精品色噜噜| 中文字幕一区二区日韩精品绯色| 久久精品视频一区二区| 亚洲国产成人午夜在线一区| 中文字幕av不卡| 一区二区三区中文字幕电影| 亚洲欧美日韩中文播放| 亚洲国产成人精品视频| 蜜臀a∨国产成人精品| 狠狠色丁香久久婷婷综| 国产成人精品一区二区三区四区| 国产福利一区二区三区视频| 高清av一区二区| 欧美偷拍一区二区| 久久这里只有精品6| 中文字幕一区二区三区蜜月 | 欧美国产一区在线| 一区二区三区丝袜| 久久国产精品99精品国产 | 亚洲午夜国产一区99re久久| 日韩国产欧美一区二区三区| 国产精品一品视频| 欧美性色黄大片| 国产婷婷色一区二区三区在线| 亚洲丝袜精品丝袜在线| 精品一区二区三区在线视频| 成人avav影音| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 亚洲国产精品久久艾草纯爱| 国产高清不卡二三区| 欧美一区二区三区四区五区| 国产欧美视频一区二区三区| 日韩avvvv在线播放| 国产成人av福利| 91精品午夜视频| 日韩精品一二三四| 在线观看日韩高清av| 综合激情成人伊人| 高清视频一区二区| 国产喂奶挤奶一区二区三区| 美女国产一区二区三区| 欧美日韩第一区日日骚| 亚洲va天堂va国产va久| 欧美性色欧美a在线播放| 欧美国产亚洲另类动漫| 国产一区二区三区| 日韩欧美国产三级| 日韩国产精品久久久| 在线精品视频免费观看| 一区二区三区四区在线免费观看| 欧美自拍偷拍一区| 亚洲成人在线观看视频| 欧美综合在线视频| 日本三级亚洲精品| 精品国产第一区二区三区观看体验| 秋霞午夜av一区二区三区| 8x8x8国产精品| 国内精品写真在线观看| 国产精品网站在线| 色婷婷综合久色| 日韩精品电影一区亚洲| 欧美精品一区二区在线观看| 国产白丝精品91爽爽久久| 一区二区成人在线| 欧美蜜桃一区二区三区| 国模大尺度一区二区三区| 国产精品久久三| 欧美日韩在线播放一区| 国产成人综合在线观看| 国产精品超碰97尤物18| 欧美一区二区视频在线观看| 成人永久aaa| 久久激五月天综合精品| 亚洲午夜日本在线观看| 久久久国产精品午夜一区ai换脸| 欧美午夜一区二区三区 | 亚洲欧洲综合另类| 欧美精品一区视频| 这里是久久伊人| 色88888久久久久久影院野外| 蜜桃av一区二区三区电影| 亚洲综合图片区| 亚洲视频一区在线观看| 久久久久88色偷偷免费| 欧美电视剧在线观看完整版| 91一区二区三区在线观看| 韩国精品主播一区二区在线观看| 午夜久久久影院| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 亚洲一区视频在线| 综合分类小说区另类春色亚洲小说欧美| 91精品国产综合久久精品app| 99国产精品久久久| 不卡视频免费播放| 不卡电影一区二区三区| 成人精品免费视频| 波多野结衣欧美| 国产xxx精品视频大全| 国产精品99久久久久| 国产一区二区中文字幕| 美洲天堂一区二卡三卡四卡视频| 久久亚洲综合色| 精品免费视频.| 欧美日韩一区二区三区在线 | 久久九九国产精品| 亚洲一级二级三级在线免费观看| 久久97超碰国产精品超碰| 欧美日韩亚洲高清一区二区| 国产欧美日本一区二区三区| 婷婷开心激情综合| 欧美日韩一二三| 一区二区三区在线看| 99精品视频在线观看免费| 久久综合色天天久久综合图片| 日韩黄色小视频| 91国模大尺度私拍在线视频| 国产精品国产a| aaa欧美日韩| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 亚洲国产成人av网| 玉米视频成人免费看| 日本欧美大码aⅴ在线播放| 粉嫩久久99精品久久久久久夜| 在线观看免费亚洲| 欧美久久久久久久久中文字幕| 日本国产一区二区| 久久久久99精品一区| 一个色在线综合| 久久狠狠亚洲综合| 亚洲精品乱码久久久久久日本蜜臀| 久久精品国产亚洲aⅴ| 91麻豆swag| 精品国产一区二区亚洲人成毛片| 一区二区三区免费观看| 美女视频黄 久久| www.亚洲免费av| 一区二区三区中文字幕电影| 久久99久久99精品免视看婷婷 | 久久99蜜桃精品| 国模套图日韩精品一区二区| 欧美日韩国产高清一区二区三区| 国产欧美日韩另类视频免费观看|