📄 stm8s_can.c
字号:
CAN->Page.Filter.FR09 = CAN_FilterID1;
CAN->Page.Filter.FR10 = CAN_FilterID2;
CAN->Page.Filter.FR11 = CAN_FilterIDMask1;
CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
CAN->Page.Filter.FR13 = CAN_FilterID3;
CAN->Page.Filter.FR14 = CAN_FilterIDMask3;
CAN->Page.Filter.FR15 = CAN_FilterID4;
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
}
else if (CAN_FilterScale == CAN_FilterScale_16Bit)
{
CAN->Page.Filter.FR09 = CAN_FilterID1;
CAN->Page.Filter.FR10 = CAN_FilterID2;
CAN->Page.Filter.FR11 = CAN_FilterIDMask1;
CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
CAN->Page.Filter.FR13 = CAN_FilterID3;
CAN->Page.Filter.FR14 = CAN_FilterID4;
CAN->Page.Filter.FR15 = CAN_FilterIDMask3;
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
}
else if (CAN_FilterScale == CAN_FilterScale_32Bit)
{
CAN->Page.Filter.FR09 = CAN_FilterID1;
CAN->Page.Filter.FR10 = CAN_FilterID2;
CAN->Page.Filter.FR11 = CAN_FilterID3;
CAN->Page.Filter.FR12 = CAN_FilterID4;
CAN->Page.Filter.FR13 = CAN_FilterIDMask1;
CAN->Page.Filter.FR14 = CAN_FilterIDMask2;
CAN->Page.Filter.FR15 = CAN_FilterIDMask3;
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
}
}
else
{
/* Filter Scale */
if (CAN_FilterScale == CAN_FilterScale_8Bit)
{
CAN->Page.Filter.FR01 = CAN_FilterID1;
CAN->Page.Filter.FR02 = CAN_FilterIDMask1;
CAN->Page.Filter.FR03 = CAN_FilterID2;
CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
CAN->Page.Filter.FR05 = CAN_FilterID3;
CAN->Page.Filter.FR06 = CAN_FilterIDMask3;
CAN->Page.Filter.FR07 = CAN_FilterID4;
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
}
else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
{
CAN->Page.Filter.FR01 = CAN_FilterID1;
CAN->Page.Filter.FR02 = CAN_FilterID2;
CAN->Page.Filter.FR03 = CAN_FilterIDMask1;
CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
CAN->Page.Filter.FR05 = CAN_FilterID3;
CAN->Page.Filter.FR06 = CAN_FilterIDMask3;
CAN->Page.Filter.FR07 = CAN_FilterID4;
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
}
else if (CAN_FilterScale == CAN_FilterScale_16Bit)
{
CAN->Page.Filter.FR01 = CAN_FilterID1;
CAN->Page.Filter.FR02 = CAN_FilterID2;
CAN->Page.Filter.FR03 = CAN_FilterIDMask1;
CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
CAN->Page.Filter.FR05 = CAN_FilterID3;
CAN->Page.Filter.FR06 = CAN_FilterID4;
CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
}
else if (CAN_FilterScale == CAN_FilterScale_32Bit)
{
CAN->Page.Filter.FR01 = CAN_FilterID1;
CAN->Page.Filter.FR02 = CAN_FilterID2;
CAN->Page.Filter.FR03 = CAN_FilterID3;
CAN->Page.Filter.FR04 = CAN_FilterID4;
CAN->Page.Filter.FR05 = CAN_FilterIDMask1;
CAN->Page.Filter.FR06 = CAN_FilterIDMask2;
CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
}
}
/*---------------------------------------------------------*/
/*Configuration of Filter Activation */
/*---------------------------------------------------------*/
/* Filter activation */
CAN->PSR = CAN_Page_Config;
if (CAN_FilterActivation != DISABLE)
{
if ((CAN_FilterNumber & 0x06) == 0x00) /* FCR1*/
{ CAN->Page.Config.FCR1 |= (u8)fact;
}
else if ((CAN_FilterNumber & 0x06) == 0x02) /*FCR2*/
{ CAN->Page.Config.FCR2 |= (u8)fact;
}
else /*if((CAN_FilterNumber & 0x06) == 0x04)*/ /*FCR3*/
{ CAN->Page.Config.FCR3 |= (u8)fact;
}
}
CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
/**
* @brief Enables or disables the specified CAN interrupts.
* @param[in] CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
* @param[in] NewState : CAN_IT new state , can be one of @ref FunctionalState
* @retval None
*/
void CAN_ITConfig(CAN_IT_TypeDef CAN_IT, FunctionalState NewState)
{
u8 tmperrorinterrupt = 0;
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/* Check the parameters */
assert_param(IS_CAN_IT_CONFIG_OK(CAN_IT));
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
tmperrorinterrupt = (u8)(((u16)CAN_IT) >>7);
tmperrorinterrupt = (u8)(((u8)(tmperrorinterrupt & 0xF0)) | ((u8)((tmperrorinterrupt & 0x0F) >>1)));
CAN->PSR = CAN_Page_Config;
if (NewState != DISABLE)
{
/* Enable the selected CAN interrupt */
CAN->IER |= (u8)(CAN_IT);
CAN->Page.Config.EIER |= (u8)(tmperrorinterrupt);
}
else
{
/* Disable the selected CAN interrupt */
CAN->IER &= (u8)(~CAN_IT);
CAN->Page.Config.EIER &= (u8)~(tmperrorinterrupt);
}
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
/**
* @brief Enables or Disables the ST7 CAN Compatibility.
* if the ST7 compatibilty is Enabled, CAN provides only 2 mailboxes.
* if the ST7 compatibilty is Disabled, CAN provides 3 mailboxes.
* @param[in] CAN_ST7Compatibility : CAN ST7 Compatibility , this parameter can be one of @ref CAN_ST7Compatibility_TypeDef enumeration.
* @retval None
*/
void CAN_ST7CompatibilityCmd(CAN_ST7Compatibility_TypeDef CAN_ST7Compatibility)
{
/* Check the parameters */
assert_param(IS_CAN_ST7_COMPATIBILITY_OK(CAN_ST7Compatibility));
/*Reset the old configuration of TXM2E */
CAN->DGR &= (u8)(~CAN_DGR_TXM2E);
/*Set the old configuration of TXM2E */
CAN->DGR |= (u8)CAN_ST7Compatibility;
}
/**
* @brief Enables or disabes the CAN Time TriggerOperation communication mode.
* @param[in] NewState : Mode new state , can be one of @ref FunctionalState
* @retval None
*/
void CAN_TTComModeCmd(FunctionalState NewState)
{
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/* Check the parameters */
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
if (NewState != DISABLE)
{
/*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.
*/
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;
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 = (u8)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 */
CAN->Page.TxMailbox.MDAR1 = CAN_Data[0];
CAN->Page.TxMailbox.MDAR2 = CAN_Data[1];
CAN->Page.TxMailbox.MDAR3 = CAN_Data[2];
CAN->Page.TxMailbox.MDAR4 = CAN_Data[3];
CAN->Page.TxMailbox.MDAR5 = CAN_Data[4];
CAN->Page.TxMailbox.MDAR6 = CAN_Data[5];
CAN->Page.TxMailbox.MDAR7 = CAN_Data[6];
CAN->Page.TxMailbox.MDAR8 = CAN_Data[7];
/* 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.
*/
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 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 = (u8)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 None
*/
void CAN_FIFORelease(void)
{
/* Release FIFO*/
CAN->RFR = CAN_RFR_RFOM; /*rc-w1*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -