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

📄 stm8s_can.c

📁 按键是比较复杂。可以用状态机表示。 每10mS执行一次键盘扫描任务 0、无键
💻 C
📖 第 1 页 / 共 3 页
字号:
}

/**
  * @brief Select the CAN Operation mode.
  * @param[in] CAN_OperatingMode CAN Operating Mode , this parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode)
{
  u8 tmpreg =0;
	u16 timeout = CAN_ACKNOWLEDGE_TIMEOUT;
	
 assert_param(IS_CAN_OPERATINGMODE_OK(CAN_OperatingMode));
 
 if(CAN_OperatingMode == CAN_OperatingMode_Initialization)
 {
    /* Request initialisation */
		CAN->MCR = (u8)((CAN->MCR & (u8)(~CAN_MCR_SLEEP)) | CAN_MCR_INRQ);
	   
		/* Wait the acknowledge */
		while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0))
		{
		   timeout--;
		}
		if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK)
		{
			return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
		}
		else
		{
			 return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
		}
		
 }
 else  if(CAN_OperatingMode == CAN_OperatingMode_Normal)
 {
	  /* Request leave initialisation and sleep mode  and enter Normal mode */
		CAN->MCR &= (u8)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ));
    
		/* Wait the acknowledge */
		while (((CAN->MSR & CAN_MODE_MASK) != 0) && (timeout!=0))
		{
		   timeout--;
		}
		if ((CAN->MSR & CAN_MODE_MASK) != 0)
		{
			return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
		}
		else
		{
			 return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
		}
 }
  else  if(CAN_OperatingMode == CAN_OperatingMode_Sleep)
 {
	  /* Request Sleep mode */
		CAN->MCR = (u8)((CAN->MCR & (u8)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
	  
		/* Wait the acknowledge */
		while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0))
		{
		   timeout--;
		}
		if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK)
		{
			return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
		}
		else
		{
			 return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
		}
 }
 else
 {
	 return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
 }
 
}
 
/**
  * @brief Gets the  Last Error Code.
  * @par Parameters:
  * None
  * @retval Error Code.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_ErrorCode_TypeDef CAN_GetLastErrorCode(void)
{
  CAN_ErrorCode_TypeDef errcode = CAN_ErrorCode_NoErr;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
	 
	CAN->PSR = CAN_Page_Config;
  errcode = (u8)((CAN->Page.Config.ESR) & (CAN_ESR_LEC));
  
	/*Restore Last Page*/
  CAN_SelectPage(can_page);

  return (CAN_ErrorCode_TypeDef)(errcode);
}
/**
  * @brief Clears the CAN's pending flags.
  * @param[in] CAN_FLAG : Flag to be cleared, can be one of @ref CAN_Flag_TypeDef.
	* check that the correspondant Flag can be cleared (read IS_CAN_FLAG_CLEAR_OK assert
  * possibilities.	
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_ClearFlag(CAN_Flag_TypeDef CAN_Flag)
{
	CAN_Page_TypeDef can_page = 0;
	/* Check the parameters */
	assert_param(IS_CAN_FLAG_CLEAR_OK(CAN_Flag));
  if((CAN_Flag & 0x0700)!=(u16)RESET)
	{
	  if((CAN_Flag & 0x020B)!=(u16)RESET)
		{
		   /*Receive Flags*/
		   CAN->RFR = (u8)(CAN_Flag);
		}
		else if((CAN_Flag & 0x0403)!=(u16)RESET)
		{
		  /*Transmit Flags*/
		   CAN->TSR = (u8)(CAN_Flag);
		}
		else /*if((CAN_Flag & 0x0108)!=(u16)RESET)*/
		{
		  /*wake up Flags*/
		   CAN->MSR = (u8)(CAN_Flag);
		}
	}
	else
	{
	 /*Error Flags*/
	  can_page = CAN_GetSelectedPage();
		
		/* Clear the selected CAN flags */
		CAN->PSR = CAN_Page_Config;
		CAN->Page.Config.ESR = (u8)RESET;
		
		/*Restore Last Page*/
    CAN_SelectPage(can_page);
	}
}

/**
  * @brief Checks whether the specified CAN flag is set or not.
  * @param[in] CAN_FLAG: specifies the flag to check, can be one of @ref CAN_Flag_TypeDef enumeration.
  * @retval The new state of CAN_FLAG which can be one of @ref FlagStatus.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
FlagStatus CAN_GetFlagStatus(CAN_Flag_TypeDef CAN_Flag)
{
	FlagStatus bitstatus = RESET;
	CAN_Page_TypeDef can_page = 0;

	/* Check the parameters */
	assert_param(IS_CAN_FLAG_STATUS_OK(CAN_Flag));
	
	if((CAN_Flag & 0x0700)!=(u16)RESET)
	{
	  if((CAN_Flag & 0x020B)!=(u16)RESET)
		{
		   /*Receive Flags*/
		   if((CAN->RFR & CAN_Flag )!= (u16)RESET)
			 {
				/* CAN_FLAG is set */
				bitstatus = SET;
			}
			else
			{
				/* CAN_FLAG is reset */
				bitstatus = RESET;
			}
			 
		}
		else if((CAN_Flag & 0x0403)!=(u16)RESET)
		{
		  /*Transmit Flags*/
		   if((CAN->TSR & CAN_Flag )!= (u16)RESET)
			 {
				/* CAN_FLAG is set */
				bitstatus = SET;
			 }
			 else
			 {
				/* CAN_FLAG is reset */
				bitstatus = RESET;
			 }
		}
		else /*if((CAN_Flag & 0x0108)!=(u16)RESET)*/
		{
		  /*wake up Flags*/
		   if((CAN->MSR & CAN_Flag )!= (u16)RESET)
			 {
				/* CAN_FLAG is set */
				bitstatus = SET;
			 }
			 else
			 {
				/* CAN_FLAG is reset */
				bitstatus = RESET;
			 }
		}
	}
	else
	{
	  /*Error Flags*/
	    can_page = CAN_GetSelectedPage();
		
			CAN->PSR = CAN_Page_Config;
			if ((CAN->Page.Config.ESR & CAN_Flag) != (u32)RESET)
			{
				/* CAN_FLAG is set */
				bitstatus = SET;
			}
			else
			{
				/* CAN_FLAG is reset */
				bitstatus = RESET;
			}
		  /*Restore Last Page*/
		  CAN_SelectPage(can_page);
	}


	/* Return the CAN_FLAG status */
	return  (FlagStatus)bitstatus;
}

/**
  * @brief Checks whether the specified CAN interrupt has occurred or not.
  * @param[in] CAN_IT: specifies the CAN interrupt source to check, can be one of @ref CAN_IT_TypeDef.
  * @retval The new state of CAN_IT, which can be one of @ref ITStatus.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
ITStatus CAN_GetITStatus(CAN_IT_TypeDef CAN_IT)
{
	ITStatus pendingbitstatus = RESET;
	u8 itreg1;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();

	/* Check the parameters */
	assert_param(IS_CAN_IT_STATUS_OK(CAN_IT));

	
	switch (CAN_IT)
	{
	case CAN_IT_TME:
								  if((CAN->IER & CAN_IER_TMEIE) !=RESET)
									{
									 pendingbitstatus = CheckITStatus(CAN->TSR, CAN_TSR_RQCP012);
									}
									else
									{
									 pendingbitstatus = RESET;
									}
									break;
	
	case CAN_IT_FMP:
								   if((CAN->IER & CAN_IER_FMPIE) !=RESET)
									{
									   pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FMP01);
									}
									else
									{
									 pendingbitstatus = RESET;
									}
		              break;
	case CAN_IT_FF:
							   if((CAN->IER & CAN_IER_FFIE) !=RESET)
								 {
								    pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FULL);
								 }
								 else
								 {
								    pendingbitstatus = RESET;
								 }
		             break;
	case CAN_IT_FOV:
							   if((CAN->IER & CAN_IER_FOVIE) !=RESET)
								 {	
		                pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FOVR);
		             }
		             else
		             {
		                pendingbitstatus = RESET;
		             }
		             break;
	case CAN_IT_WKU:
							   if((CAN->IER & CAN_IER_WKUIE) !=RESET)
								 {	
		                 pendingbitstatus = CheckITStatus(CAN->MSR, CAN_MSR_WKUI);
				         }
								else
								{
								 pendingbitstatus = RESET;
								}
		            break;
	
	case CAN_IT_ERR:
	               CAN->PSR = CAN_Page_Config;
								 if((CAN->Page.Config.EIER & CAN_EIER_ERRIE) !=RESET)
								 {	
									    pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EWGF|CAN_ESR_EPVF|CAN_ESR_BOFF|CAN_ESR_LEC);
								 }
								 else
								 {
								      pendingbitstatus = RESET;
							   }
								 break;
		
	case CAN_IT_EWG:
	                CAN->PSR = CAN_Page_Config;
									if((CAN->Page.Config.EIER & CAN_EIER_EWGIE) !=RESET)
								 {	
		                 pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EWGF);
								 }
								 else
								 {
								      pendingbitstatus = RESET;
							   }
								 break;
									
	case CAN_IT_EPV:
	                CAN->PSR = CAN_Page_Config;
									if((CAN->Page.Config.EIER & CAN_EIER_EPVIE) !=RESET)
								  {	
		                 	pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EPVF);
								 }
								 else
								 {
								      pendingbitstatus = RESET;
							   }
								 break;
	case CAN_IT_BOF:
	                CAN->PSR = CAN_Page_Config;
									if((CAN->Page.Config.EIER & CAN_EIER_BOFIE) !=RESET)
								 {	
		                  pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_BOFF);
								 }
								 else
								 {
								      pendingbitstatus = RESET;
							   }
								 break;
		case CAN_IT_LEC:
	                CAN->PSR = CAN_Page_Config;
			            if((CAN->Page.Config.EIER & CAN_EIER_LECIE) !=RESET)
								  {	
		                  pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_LEC);
									}
								  else
								  {
								      pendingbitstatus = RESET;
							    }
								  break;
		default :
		       pendingbitstatus = RESET;
		break;
	}
    /*Restore Last Page*/
    CAN_SelectPage(can_page);
	/* Return the CAN_IT status */
	return  (ITStatus)pendingbitstatus;
}

/**
  * @brief  Clears the CAN抯 interrupt pending bits.
  * @param[in] CAN_IT: specifies the interrupt pending bit to clear, can be one of @ref CAN_IT_TypeDef.
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_ClearITPendingBit(CAN_IT_TypeDef CAN_IT)
{
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
	/* Check the parameters */
	assert_param(IS_CAN_IT_PENDING_BIT_OK(CAN_IT));

	switch (CAN_IT)
	{
	case CAN_IT_TME:
		CAN->TSR = CAN_TSR_RQCP012;/* rc_w1*/
		break;
		
	case CAN_IT_FF:
		CAN->RFR = CAN_RFR_FULL; /* rc_w1*/
		break;
		
	case CAN_IT_FOV:
		CAN->RFR = CAN_RFR_FOVR; /* rc_w1*/
		break;
	
		case CAN_IT_WKU:
		CAN->MSR = CAN_MSR_WKUI;  /* rc_w1*/
		break;
  
	case CAN_IT_ERR:
		CAN->PSR = CAN_Page_Config;
		CAN->Page.Config.ESR = (u8)CAN_ESR_RESET_VALUE;
		CAN->MSR = CAN_MSR_ERRI;
		break;
		
	case CAN_IT_EWG:
		CAN->MSR = CAN_MSR_ERRI;
		break;
		
	case CAN_IT_EPV:
	    CAN->MSR = CAN_MSR_ERRI;
		break;
	
		case CAN_IT_BOF:
	    CAN->MSR = CAN_MSR_ERRI;
		break;
		
	case CAN_IT_LEC:
	    CAN->PSR = CAN_Page_Config;
		  CAN->Page.Config.ESR = (u8)CAN_ESR_RESET_VALUE;
		break;
		

		
		default :
		break;
	}
    /*Restore Last Page*/
    CAN_SelectPage(can_page);
}

/**
  * @brief Gets the selected registers page.
  * @par Parameters:
  * None
  * @retval the selected page which can be one of the @ref CAN_Page_TypeDef.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_Page_TypeDef CAN_GetSelectedPage(void)
{
	return (CAN_Page_TypeDef)(CAN->PSR);
}

/**
  * @brief Sets the registers page to be selected.
  * @param[in] the selected page which can be one of the @ref CAN_Page_TypeDef.
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_SelectPage(CAN_Page_TypeDef CAN_Page)
{
	CAN->PSR = CAN_Page;
}

/**
  * @brief Checks whether the CAN interrupt has occurred or not.
  * @param[in] CAN_Reg: specifies the CAN interrupt register to check.
  * @param[in] It_Bit: specifies the interrupt source bit to check.
  * @retval The new state of the CAN Interrupt, which can be one of ITStatus.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
static ITStatus CheckITStatus(u8 CAN_Reg, u8 It_Bit)
{
	ITStatus pendingbitstatus = RESET;
	if ((CAN_Reg & It_Bit) != (u8)RESET)
	{
		/* CAN_IT is set */
		pendingbitstatus = SET;
	}
	else
	{
		/* CAN_IT is reset */
		pendingbitstatus = RESET;
	}
	return (ITStatus)pendingbitstatus;
}
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

⌨️ 快捷键说明

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