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

📄 stm8s_can.c

📁 按键是比较复杂。可以用状态机表示。 每10mS执行一次键盘扫描任务 0、无键
💻 C
📖 第 1 页 / 共 3 页
字号:
		/*Enable the TTCM mode */
		CAN->MCR |= CAN_MCR_TTCM;
		/*Set TGT bits setting in Tx and FIFO pages*/
		CAN->PSR = CAN_Page_TxMailBox0;
		CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
		CAN->PSR = CAN_Page_TxMailBox1;
		CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
		CAN->PSR = CAN_Page_TxMailBox2;
		CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
		CAN->PSR = CAN_Page_RxFifo;
		CAN->Page.RxFIFO.MDLCR |= CAN_MDLCR_TGT;
	}
	else
	{
	  /*Disable the TTCM mode */
		CAN->MCR &= ((u8)~CAN_MCR_TTCM);
		/*Reset TGT bits setting in Tx and FIFO pages*/
		CAN->PSR = CAN_Page_TxMailBox0;
		CAN->Page.TxMailbox.MDLCR &= ((u8)~CAN_MDLCR_TGT);
		CAN->PSR = CAN_Page_TxMailBox1;
		CAN->Page.TxMailbox.MDLCR &= ((u8)~CAN_MDLCR_TGT);
		CAN->PSR = CAN_Page_TxMailBox2;
		CAN->Page.TxMailbox.MDLCR &= ((u8)~CAN_MDLCR_TGT);
		CAN->PSR = CAN_Page_RxFifo;
		CAN->Page.RxFIFO.MDLCR &= ((u8)~CAN_MDLCR_TGT);
	}
	/*Restore Last Page*/
	CAN_SelectPage(can_page);
}

/**
  * @brief Initiates the transmission of a message.
  * @param[in] CAN_Id the ID number of the message, its size depends on @ref CAN_IDE value.
	* @param[in] CAN_IDE the ID type of the message, this parameter can be one of the @ref CAN_Id_TypeDef enumeration.
	* @param[in] CAN_RTR the message type, this parameter can be one of the @ref CAN_RTR_TypeDef enumeration.
	* @param[in] CAN_DLC the number of data in the message type, this parameter can be a value between 0 to 7.
	* @param[in] CAN_Data pointer to a the @ref u8 table which contains data to sent.
  * @retval Transmit Status, this returned value can be one of the @ref CAN_TxStatus_TypeDef enumeration.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_TxStatus_TypeDef CAN_Transmit(u32 CAN_Id,
                                  CAN_Id_TypeDef CAN_IDE,
								                  CAN_RTR_TypeDef CAN_RTR,
								                  u8 CAN_DLC,
								                  u8 *CAN_Data)
{
	CAN_TxStatus_TypeDef CAN_TxStatus = CAN_TxStatus_NoMailBox;
	u8 count =0;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
	/* Check the parameters */
	assert_param(IS_CAN_IDTYPE_OK(CAN_IDE));
	if (CAN_IDE != CAN_Id_Standard)
	{
		assert_param(IS_CAN_EXTID_OK(CAN_Id));
	}
	else
	{
		assert_param(IS_CAN_STDID_OK(CAN_Id));
	}
	assert_param(IS_CAN_RTR_OK(CAN_RTR));
	assert_param(IS_CAN_DLC_OK(CAN_DLC));
	/* Select one empty transmit mailbox */
	if ((CAN->TPR & CAN_TPR_TME0) == CAN_TPR_TME0)
	{
		CAN_TxStatus = CAN_TxStatus_MailBox0Ok;
	}
	else if ((CAN->TPR & CAN_TPR_TME1) == CAN_TPR_TME1)
	{
		CAN_TxStatus = CAN_TxStatus_MailBox1Ok;
	}
	else if ((CAN->TPR & CAN_TPR_TME2) == CAN_TPR_TME2)
	{
		CAN_TxStatus = CAN_TxStatus_MailBox2Ok;
	}
	else
	{
		CAN_TxStatus = CAN_TxStatus_NoMailBox;
	}
	if (CAN_TxStatus != CAN_TxStatus_NoMailBox)
	{
		CAN->PSR = (CAN_TxStatus);
		/* Set up the Id */
		if (CAN_IDE != CAN_Id_Standard)
		{
			CAN_Id &= (u32)CAN_EXTID_SIZE;
			CAN->Page.TxMailbox.MIDR4 = (u8)(CAN_Id);
			CAN_Id = CAN_Id>>8;
			CAN->Page.TxMailbox.MIDR3 = (u8)(CAN_Id);
			CAN_Id = CAN_Id>>8;
			CAN->Page.TxMailbox.MIDR2 = (u8)(CAN_Id);
			CAN_Id = CAN_Id>>8;
			CAN->Page.TxMailbox.MIDR1 |= (u8)(CAN_Id |CAN_IDE | CAN_RTR);
		}
		else
		{
		 	CAN_Id &= (u16)CAN_STDID_SIZE;
			CAN->Page.TxMailbox.MIDR1 = (u8)((CAN_Id>>6) | (CAN_RTR)) ;
			CAN->Page.TxMailbox.MIDR2 = (u8)(CAN_Id<<2);
		}
		/* Set up the DLC                 */
		/*clear old DLC value*/
		CAN->Page.TxMailbox.MDLCR &= (u8)0xF0;
		/*set the new value of DLC*/
		CAN->Page.TxMailbox.MDLCR |= CAN_DLC;
		/* Set up the data field */
		for (count=0;count<CAN_DLC;count++)
		{ 
		  CAN->Page.TxMailbox.MDAR[count] = CAN_Data[count]; 
		}
		/* Request transmission */
		CAN->Page.TxMailbox.MCSR |= CAN_MCSR_TXRQ;
	}
	/*Restore Last Page*/
  CAN_SelectPage(can_page);
	return (CAN_TxStatus_TypeDef)CAN_TxStatus;
}

/**
  * @brief Checks the transmission of a message.
  * @param[in] TransmitMailbox: the number of the mailbox that is used for transmission, can be on of  @ref CAN_TransmitMailBox_TypeDef.
  * @retval CAN_TxStatus_Ok if the CAN driver transmits the message, CAN_TxStatus_Failed in an other case.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_TxStatus_TypeDef CAN_TransmitStatus(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox)
{
	/* RQCP, TXOK and TME bits */
	CAN_TxStatus_TypeDef tstate = CAN_TxStatus_Failed;
	u8 tmpstate=0;
 
	/* Check the parameters */
	assert_param(IS_CAN_TRANSMITMAILBOX_OK(CAN_TransmitMailbox));
  	
    switch (CAN_TransmitMailbox)
    {
    case (CAN_TransmitMailBox_0): tmpstate = (u8)((CAN->TSR & (CAN_TSR_RQCP0|CAN_TSR_TXOK0)));
		                              tmpstate |= (u8)((CAN->TPR & CAN_TPR_TME0)); 
																	break;
    case (CAN_TransmitMailBox_1): tmpstate = (u8)((CAN->TSR & (CAN_TSR_RQCP1|CAN_TSR_TXOK1))>>1);
		                              tmpstate |= (u8)((CAN->TPR & CAN_TPR_TME1) >> 1); 
																	break;
    case (CAN_TransmitMailBox_2): tmpstate = (u8)((CAN->TSR & (CAN_TSR_RQCP2|CAN_TSR_TXOK2))>>2);
                                  tmpstate |= (u8)((CAN->TPR & CAN_TPR_TME2) >> 2); 
																	break;
    default: tstate = CAN_TxStatus_Failed;	
		         break;
   }
   
	switch (tmpstate)
	{
		/*transmit pending  */
		case (0x00): tstate = CAN_TxStatus_Pending;		
		             break;
		/* transmit failed  */
		case (0x05): tstate = CAN_TxStatus_Failed;		
		             break;
		/* transmit succedeed */ 
		case (0x15): tstate = CAN_TxStatus_Ok;		
		             break;
    /* transmit mailbox is empty : no activity on this TX mail box */ 
		case (0x04): tstate = CAN_TxStatus_MailBoxEmpty;		
		             break;
	  default: tstate = CAN_TxStatus_Failed;		
		         break;
	}

	return (CAN_TxStatus_TypeDef)tstate;
}

/**
  * @brief Cancels a transmit request.
  * @param[in] TransmitMailbox : the Transmission mailbox, can be one of CAN_TransmitMailBox_TypeDef
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_CancelTransmit(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox)
{
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
	/* Check the parameters */
	assert_param(IS_CAN_TRANSMITMAILBOX_OK(CAN_TransmitMailbox));
	/*switch to the specific page */
	CAN->PSR = CAN_TransmitMailbox;
	/* abort transmission */
	CAN->Page.TxMailbox.MCSR |= CAN_MCSR_ABRQ;
	/*Restore Last Page*/
  CAN_SelectPage(can_page);
}


/**
  * @brief  Releases the CAN FIFO.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_FIFORelease(void)
{
	/* Release FIFO*/
	CAN->RFR = CAN_RFR_RFOM; /*rc-w1*/
}


/**
  * @brief Returns the number of pending messages.
  * @param void None
  * @retval Number of pending messages.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_NbrPendingMessage_TypeDef CAN_MessagePending(void)
{ 
	CAN_NbrPendingMessage_TypeDef msgpending = CAN_NbrPendingMessage_0;
	msgpending = (u8)(CAN->RFR & CAN_RFR_FMP01);
	return (CAN_NbrPendingMessage_TypeDef)msgpending;
}

/**
  * @brief  Receives a message which contains CAN Id, IDE, RTR
  * DLC, datas and FMI number.
  * In order to get these data, use CAN_GetReceivedId(), CAN_GetReceivedIDE(), CAN_GetReceivedRTR(),
  * CAN_GetReceivedDLC(), CAN_GetReceivedFMI() and CAN_GetReceivedData() functions.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_Receive(void)
{
  u8 count = 0;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();

	/* select Fifo page*/
	CAN->PSR = CAN_Page_RxFifo;

	/* Get the Id */
	_IDE = (u8)(CAN->Page.RxFIFO.MIDR1 & CAN_Id_Extended);
	if (_IDE != CAN_Id_Standard)
	{
		_Id = (u32)CAN_EXTID_SIZE & ((CAN->Page.RxFIFO.MIDR4) | ((u32)((u32)CAN->Page.RxFIFO.MIDR3) << 8) | ((u32)((u32)CAN->Page.RxFIFO.MIDR2) << 16) | ((u32)((u32)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 24) );	
	}
	else
	{
		_Id = (u16)CAN_STDID_SIZE & ((u16)((u16)(CAN->Page.RxFIFO.MIDR1 & 0x1F) << 6) | ((CAN->Page.RxFIFO.MIDR2 >> 2)&0x3F) );
	}

	_RTR = (u8)(0x20 & CAN->Page.RxFIFO.MIDR1);

	/* Get the DLC */
	_DLC = (u8)(CAN->Page.RxFIFO.MDLCR);

	/* Get the FMI */
	_FMI = CAN->Page.RxFIFO.MFMI;

	/* Get the data field */
	for (count=0;count<_DLC;count++)
	{ 
	  _Data[count] = CAN->Page.RxFIFO.MDAR[count]; 
	}

	/* Release the FIFO */
	CAN_FIFORelease();
    /*Restore Last Page*/
	CAN_SelectPage(can_page);
}


/**
  * @brief Gets the  CAN Id of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message Id.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  * @par Called functions:
  * None
  */
u32 CAN_GetReceivedId(void)
{
  return (_Id);
}	

/**
  * @brief Gets the  CAN IDE of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message IDE.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  * @par Called functions:
  * None
  */
CAN_Id_TypeDef CAN_GetReceivedIDE(void)
{
  return (_IDE);
}

/**
  * @brief Gets the  CAN RTR of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message RTR.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  * @par Called functions:
  * None
  */
CAN_RTR_TypeDef CAN_GetReceivedRTR(void)
{
  return (_RTR);
}

/**
  * @brief Gets the  CAN DLC of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message DLC.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  * @par Called functions:
  * None
  */
u8 CAN_GetReceivedDLC(void)
{
  return (_DLC);
}

/**
  * @brief Gets the  CAN Data of the received message.
  * @param[in] CAN_DataIndexe : number of the received Data, it can
  *  be an integer between 0 to 7.
  * @retval the received CAN message ith Data.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  * @par Called functions:
  * None
  */
u8 CAN_GetReceivedData(u8 CAN_DataIndex)
{
	assert_param(IS_CAN_DLC_OK(CAN_DataIndex));
  return (_Data[CAN_DataIndex]);
}

/**
  * @brief Gets the  CAN FMI of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message FMI.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  * @par Called functions:
  * None
  */
u8 CAN_GetReceivedFMI(void)
{
  return (_FMI);
}
/**
  * @brief Returns the Received time stamp.
  * @par Parameters:
  * None
  * @retval u16 the received  time stamp.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
u16 CAN_GetMessageTimeStamp(void)
{
  u16 time;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
	
	/*switch to the specific page */
	CAN->PSR = CAN_Page_RxFifo;
	/* Get the Received Time stamp */
	time = CAN->Page.RxFIFO.MTSRL;
	time |= (u16)(((u16)CAN->Page.RxFIFO.MTSRH)<<8);
  
	/*Restore Last Page*/
  CAN_SelectPage(can_page);

  return (u16)(time);
}


/**
  * @brief Enters the Sleep low power mode.
  * @par Parameters:
  * None
  * @retval  CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed in an other case.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_Sleep_TypeDef CAN_Sleep(void)
{

	CAN_Sleep_TypeDef sleepstatus = CAN_Sleep_Failed;

  /* Request Sleep mode */
	CAN->MCR = (u8)(((CAN->MCR) & (u8)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);

	/* Sleep mode status */
	if ((CAN->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK)
	{
		/* Sleep mode not entered */
		sleepstatus =  CAN_Sleep_Ok;
	}

	/* At this step, sleep mode status */
	return (CAN_Sleep_TypeDef) sleepstatus;
}




/**
  * @brief Wakes the CAN up.
  * @par Parameters:
  * None
  * @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed in an other  case.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
CAN_WakeUp_TypeDef CAN_WakeUp(void)
{
	CAN_WakeUp_TypeDef wakeupstatus = CAN_WakeUp_Failed;

	/* Wake up request */
	CAN->MCR &= (u8)(~CAN_MCR_SLEEP);

	/* Sleep mode status */
	if ((CAN->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK)
	{
		/* Sleep mode exited */
		wakeupstatus = CAN_WakeUp_Ok;
	}

	/* At this step, sleep mode status */
	return (CAN_WakeUp_TypeDef)wakeupstatus;
}


/**
  * @brief  Select the CAN clock input.
  * @param[in] CAN_ClockSource : CAN clock input, can be one of @ref CAN_ClockSource_TypeDef.
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_SelectClock(CAN_ClockSource_TypeDef CAN_ClockSource)
{
	u16 timeout =0;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
	/* Check the parameters */
	assert_param(IS_CAN_CLOCKSOURCE_OK(CAN_ClockSource));
    /* Request initialisation */
	CAN->MCR |= (CAN_MCR_INRQ & ((u8)(~CAN_MCR_SLEEP)));
	
	CAN->PSR = CAN_Page_Config;
	if(CAN_ClockSource != CAN_ClockSource_Internal)
	{
		CAN->Page.Config.BTR2 |= (u8)CAN_BTR2_CLKS;
	}
	else
	{
		CAN->Page.Config.BTR2 &= (u8)(~CAN_BTR2_CLKS);
	}
	/* Request leave initialisation */
	CAN->MCR &= (u8)(~CAN_MCR_INRQ);
	/* Wait the acknowledge */
		while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK))
		{
			timeout--;
		}

	/*Restore Last Page*/
    CAN_SelectPage(can_page);

⌨️ 快捷键说明

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