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

📄 stm8s_can.c

📁 按键是比较复杂。可以用状态机表示。 每10mS执行一次键盘扫描任务 0、无键
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
  ******************************************************************************
  * @file stm8s_can.c
  * @brief This file contains all the functions for the CAN peripheral.
  * @author STMicroelectronics - MCD Application Team
  * @version V1.1.0
  * @date 02/27/2009
  ******************************************************************************
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2008 STMicroelectronics</center></h2>
  * @image html logo.bmp
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm8s_can.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define CAN_IDLIST_IDMASK_MASK ((u8) 0x55)
#define CAN_IDMASK_IDLIST_MASK ((u8) 0xAA)
#define CAN_MODE_MASK ((u8) 0x03)
#define CAN_ACKNOWLEDGE_TIMEOUT ((u16)0xFFFF)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
  u32 _Id;
  u8 _IDE;
  u8 _RTR;
  u8 _DLC;
  u8 _Data[8];
  u8 _FMI;
/* Private function prototypes -----------------------------------------------*/
static ITStatus CheckITStatus(u8 CAN_Reg, u8 It_Bit);

/* Private functions ---------------------------------------------------------*/
/**
  * @addtogroup CAN_Public_Functions
  * @{
  */
  
/**
  * @brief Deinitializes the CAN peripheral registers to their default reset values.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_DeInit(void)
{
  /* Request initialisation */
  CAN->MCR = CAN_MCR_INRQ;  
  CAN->PSR = CAN_Page_Config;
  CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);
  CAN->Page.Config.ESR = CAN_ESR_RESET_VALUE;
  CAN->Page.Config.EIER = CAN_EIER_RESET_VALUE;
  CAN->Page.Config.BTR1 = CAN_BTR1_RESET_VALUE;
  CAN->Page.Config.BTR2 = CAN_BTR2_RESET_VALUE;
  CAN->Page.Config.FMR1 = CAN_FMR1_RESET_VALUE;
  CAN->Page.Config.FMR2 = CAN_FMR2_RESET_VALUE;
  CAN->Page.Config.FCR1 = CAN_FCR_RESET_VALUE;
  CAN->Page.Config.FCR2 = CAN_FCR_RESET_VALUE;
  CAN->Page.Config.FCR3 = CAN_FCR_RESET_VALUE;
  CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
  CAN->PSR = CAN_Page_RxFifo;
  CAN->Page.RxFIFO.MDLCR = CAN_MDLC_RESET_VALUE;

  CAN->MCR = CAN_MCR_RESET_VALUE;   
  CAN->MSR = (u8)(~CAN_MSR_RESET_VALUE);/* rc_w1 */
  CAN->TSR = (u8)(~CAN_TSR_RESET_VALUE);/* rc_w1 */
  CAN->RFR = (u8)(~CAN_RFR_RESET_VALUE);/* rc_w1 */
  CAN->IER = CAN_IER_RESET_VALUE; 
  CAN->DGR = CAN_DGR_RESET_VALUE;
  CAN->PSR = CAN_PSR_RESET_VALUE; 
}
/**
  * @brief Initializes the CAN peripheral according to the specified parameters.
  * @param[in] CAN_MasterCtrl : Master control option, can be one or a combinaison of @ref CAN_MasterCtrl_TypeDef.
  * @param[in] CAN_Mode : CAN mode , can be one of @ref CAN_Mode_TypeDef.
  * @param[in] CAN_SynJumpWidth : CAN Synchronisation Jump Width , can be one of @ref CAN_SynJumpWidth_TypeDef.
  * @param[in] CAN_BitSeg1 : CAN bit segment 1 , can be one of @ref CAN_BitSeg1_TypeDef.
  * @param[in] CAN_BitSeg2 : CAN bit segment 2 , can be one of @ref CAN_BitSeg2_TypeDef.
  * @param[in] CAN_ClockSource : CAN clock source , can be one of @ref CAN_ClockSource_TypeDef.
  * @param[in] CAN_Prescaler : CAN Baud Rate Prescaler , can be a value from 0x01 to 0xFF.
  * @retval Indicates if initialization is succeed. it can be one of @ref CAN_InitStatus_TypeDef enumeration.
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  * @endcode
  */

CAN_InitStatus_TypeDef CAN_Init(CAN_MasterCtrl_TypeDef CAN_MasterCtrl,
						                    CAN_Mode_TypeDef CAN_Mode,
						                    CAN_SynJumpWidth_TypeDef CAN_SynJumpWidth,
						                    CAN_BitSeg1_TypeDef CAN_BitSeg1,
						                    CAN_BitSeg2_TypeDef CAN_BitSeg2,
						                    CAN_ClockSource_TypeDef CAN_ClockSource,
						                    u8 CAN_Prescaler)
{
	CAN_InitStatus_TypeDef InitStatus =  CAN_InitStatus_Failed;
	u16 timeout = CAN_ACKNOWLEDGE_TIMEOUT;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
    

	/* Check the parameters */
	assert_param(IS_CAN_MASTERCTRL_OK(CAN_MasterCtrl));
	assert_param(IS_CAN_MODE_OK(CAN_Mode));
	assert_param(IS_CAN_SYNJUMPWIDTH_OK(CAN_SynJumpWidth));
	assert_param(IS_CAN_BITSEG1_OK(CAN_BitSeg1));
	assert_param(IS_CAN_BITSEG2_OK(CAN_BitSeg2));
	assert_param(IS_CAN_CLOCKSOURCE_OK(CAN_ClockSource));
	assert_param(IS_CAN_PRESCALER_OK(CAN_Prescaler));

	/* Request initialisation */
	CAN->MCR = CAN_MCR_INRQ;
	/* Wait the acknowledge */
	while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK))
	{
		timeout--;
	}

	/* Check acknowledged */
	if ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
	{
		
		InitStatus =  CAN_InitStatus_Failed;
		
	}
	else
	{
		/* Set the time triggered communication mode  &  Set the automatic bus-off management  &   Set the automatic wake-up mode 
		&     Set the no automatic retransmission & Set the receive FIFO locked mode & Set the transmit FIFO priority */
		CAN->MCR |= CAN_MasterCtrl;

		/* Set the bit timing register */
		CAN->DGR |= CAN_Mode ;
		CAN->PSR = CAN_Page_Config;
		CAN->Page.Config.BTR1 = (u8)(CAN_SynJumpWidth | (CAN_Prescaler - 1));
		CAN->Page.Config.BTR2 = (u8)(CAN_BitSeg1 | CAN_BitSeg2 | CAN_ClockSource);
		
		/* Request leave initialisation */
		CAN->MCR &= (u8)(~CAN_MCR_INRQ);
		/* Wait the acknowledge */
		timeout = 0xFFFF;
		while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK))
		{
			timeout--;
		}
		/* Check acknowledged */
		if ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
		{
			InitStatus = CAN_InitStatus_Failed;
		}
		else
		{
			InitStatus = CAN_InitStatus_Success;
		}
	}
	/*Restore Last Page*/
    CAN_SelectPage(can_page);
		
	/* Return the status of initialization */
	return (CAN_InitStatus_TypeDef)InitStatus;
}

/**
  * @brief Initializes the CAN peripheral Filter according to the specified parameters.
  * @param[in] CAN_FilterNumber : CAN Filter number , can be one of @ref CAN_FilterNumber_TypeDef
  * @param[in] CAN_FilterActivation : CAN Filter Activation state , can be one of @ref FunctionalState
  * @param[in] CAN_FilterMode : CAN Filter Mode , can be one of @ref CAN_FilterMode_TypeDef
  * @param[in] CAN_FilterScale : CAN Filter Scale , can be one of @ref CAN_FilterScale_TypeDef
  * @param[in] CAN_FilterID1 : CAN Filter ID 1 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterID2 : CAN Filter ID 2 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterID3 : CAN Filter ID 3 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterID4 : CAN Filter ID 4 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterIDMask1 : CAN Filter ID 1/ Mask 1  , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @param[in] CAN_FilterIDMask2 : CAN Filter ID 2/ Mask 2 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @param[in] CAN_FilterIDMask3 : CAN Filter ID 3/ Mask 3 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @param[in] CAN_FilterIDMask4 : CAN Filter ID 4/ Mask 4 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @retval void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_FilterInit(CAN_FilterNumber_TypeDef CAN_FilterNumber,
                    FunctionalState CAN_FilterActivation,
                    CAN_FilterMode_TypeDef CAN_FilterMode,
					          CAN_FilterScale_TypeDef CAN_FilterScale,
					          u8 CAN_FilterID1,  
				          	u8 CAN_FilterID2,
				          	u8 CAN_FilterID3,
				           	u8 CAN_FilterID4,
				          	u8 CAN_FilterIDMask1,
				           	u8 CAN_FilterIDMask2,
					          u8 CAN_FilterIDMask3,
				            u8 CAN_FilterIDMask4)
{
	u8 fact = 0;
	u8 fsc  = 0;
	u8 fmhl = 0;

	CAN_Page_TypeDef can_page_filter = CAN_Page_Filter01;
	CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
    
	/* Check the parameters */
	assert_param(IS_CAN_FILTER_NUMBER_OK(CAN_FilterNumber));
	assert_param(IS_FUNCTIONALSTATE_OK(CAN_FilterActivation));
	assert_param(IS_CAN_FILTER_MODE_OK(CAN_FilterMode));
	assert_param(IS_CAN_FILTER_SCALE_OK(CAN_FilterScale));
	
	
	if (CAN_FilterNumber == CAN_FilterNumber_0)
	{
	  fact = 0x01;
	  fsc  = 0x00;
	  fmhl = 0x03;

	  can_page_filter = CAN_Page_Filter01;
	}
	else if (CAN_FilterNumber == CAN_FilterNumber_1)
	{
	  fact = 0x10;
	  fsc  = 0x04;
	  fmhl = 0x0C;

	  can_page_filter = CAN_Page_Filter01;
	}
	else if (CAN_FilterNumber == CAN_FilterNumber_2)
	{
	  fact = 0x01;
	  fsc  = 0x00;
	  fmhl = 0x30;

	  can_page_filter = CAN_Page_Filter23;
	}
	else if (CAN_FilterNumber == CAN_FilterNumber_3)
	{
	  fact = 0x10;
	  fsc  = 0x04;
	  fmhl = 0xC0;

	  can_page_filter = CAN_Page_Filter23;
	}
	else if (CAN_FilterNumber == CAN_FilterNumber_4)
	{
	  fact = 0x01;
	  fsc  = 0x00;
	  fmhl = 0x03;

	  can_page_filter = CAN_Page_Filter45;
	}
	else /*if (CAN_FilterNumber == CAN_FilterNumber_5)*/
	{
	  fact = 0x10;
	  fsc  = 0x04;
	  fmhl = 0x0C;

	  can_page_filter = CAN_Page_Filter45;
	}


	CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);

	CAN->PSR = CAN_Page_Config;
 /*---------------------------------------------------------*/
 /*Configuration of Filter Scale                            */
 /*---------------------------------------------------------*/
	
	if (can_page_filter == CAN_Page_Filter01) /* FCR1 */
	{ 
		/* Filter Deactivation  & Reset the Filter Scale */ 
		CAN->Page.Config.FCR1 &= (u8)~( fact | ((CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));
		/* Set the new Filter Scale */
		CAN->Page.Config.FCR1 |= (u8)(CAN_FilterScale << fsc);
    }
	else if(can_page_filter == CAN_Page_Filter23) /* FCR2*/
	{
	    /* Filter Deactivation  & Reset the Filter Scale */ 
		CAN->Page.Config.FCR2 &= (u8)~( fact | ((CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));

		/* Set the new Filter Scale */
		CAN->Page.Config.FCR2 |= (u8)(CAN_FilterScale << fsc);

	}
	else /*if(can_page_filter == CAN_Page_Filter45)*/ /* FCR3*/
	{
	    /* Filter Deactivation  & Reset the Filter Scale */ 
		CAN->Page.Config.FCR3 &= (u8)~( fact | ((CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));

		/* Set the new Filter Scale */
		CAN->Page.Config.FCR3 |= (u8)(CAN_FilterScale << fsc);
	}
	
 /*---------------------------------------------------------*/
 /*Configuration of Filter Mode                             */
 /*---------------------------------------------------------*/
	if (can_page_filter != CAN_Page_Filter45) /* FMR1*/
	{ 
			/* Filter Mode */
		if (CAN_FilterMode == CAN_FilterMode_IdMask)
		{
			/*Id/Mask mode for the filter*/
			CAN->Page.Config.FMR1 &= (u8)~(fmhl);
		}
		else if( CAN_FilterMode == CAN_FilterMode_IdList)
		{
			/*Identifier list mode for the filter*/
			CAN->Page.Config.FMR1 |= (u8)(fmhl);
		}
		else if( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
		{
			/*Identifier list mode is first  for the filter*/
			CAN->Page.Config.FMR1 |= (u8)(fmhl & CAN_IDLIST_IDMASK_MASK);
		}
		else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
		{
		  /*Id Mask mode is first  for the filter*/
			CAN->Page.Config.FMR1 |= (u8)(fmhl & CAN_IDMASK_IDLIST_MASK);
		}
		

	}
	else /* FMR2 */
	{ 
	
		/* Filter Mode */
		if (CAN_FilterMode == CAN_FilterMode_IdMask)
		{
			/*Id/Mask mode for the filter*/
			CAN->Page.Config.FMR2 &= (u8)~(fmhl);
		}
		else if( CAN_FilterMode == CAN_FilterMode_IdList)
		{
			/*Identifier list mode for the filter*/
			CAN->Page.Config.FMR2 |= (u8)(fmhl);
		}
		else if( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
		{
			/*Identifier list mode is first  for the filter*/
			CAN->Page.Config.FMR2 |= (u8)(fmhl & CAN_IDLIST_IDMASK_MASK);
		}
		else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
		{
		  /*Id Mask mode is first  for the filter*/
			CAN->Page.Config.FMR2 |= (u8)(fmhl & CAN_IDMASK_IDLIST_MASK);
		}
	}
 /*---------------------------------------------------------*/
 /*Configuration of Filter IDs                              */
 /*---------------------------------------------------------*/
	CAN->PSR = can_page_filter;
	fsc= (u8)(fsc<<1);/*if fsc=4 -> fsc=8*/
	/* Filter Scale */
	if (CAN_FilterScale == CAN_FilterScale_8Bit)
	{
		CAN->Page.Filter.FR[0+fsc] = CAN_FilterID1;
		CAN->Page.Filter.FR[1+fsc] = CAN_FilterIDMask1;
		CAN->Page.Filter.FR[2+fsc] = CAN_FilterID2;
		CAN->Page.Filter.FR[3+fsc] = CAN_FilterIDMask2;
		CAN->Page.Filter.FR[4+fsc] = CAN_FilterID3;
		CAN->Page.Filter.FR[5+fsc] = CAN_FilterIDMask3;
		CAN->Page.Filter.FR[6+fsc] = CAN_FilterID4;
		CAN->Page.Filter.FR[7+fsc] = CAN_FilterIDMask4;
	} 
	else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
	{
		CAN->Page.Filter.FR[0+fsc] = CAN_FilterID1;
		CAN->Page.Filter.FR[1+fsc] = CAN_FilterID2;
		CAN->Page.Filter.FR[2+fsc] = CAN_FilterIDMask1;
		CAN->Page.Filter.FR[3+fsc] = CAN_FilterIDMask2;
		CAN->Page.Filter.FR[4+fsc] = CAN_FilterID3;
		CAN->Page.Filter.FR[5+fsc] = CAN_FilterIDMask3;
		CAN->Page.Filter.FR[6+fsc] = CAN_FilterID4;
		CAN->Page.Filter.FR[7+fsc] = CAN_FilterIDMask4;
	} 
	else if (CAN_FilterScale == CAN_FilterScale_16Bit)
	{
		CAN->Page.Filter.FR[0+fsc] = CAN_FilterID1;
		CAN->Page.Filter.FR[1+fsc] = CAN_FilterID2;
		CAN->Page.Filter.FR[2+fsc] = CAN_FilterIDMask1;
		CAN->Page.Filter.FR[3+fsc] = CAN_FilterIDMask2;
		CAN->Page.Filter.FR[4+fsc] = CAN_FilterID3;
		CAN->Page.Filter.FR[5+fsc] = CAN_FilterID4;
		CAN->Page.Filter.FR[6+fsc] = CAN_FilterIDMask3;
		CAN->Page.Filter.FR[7+fsc] = CAN_FilterIDMask4;
	} 
	else if (CAN_FilterScale == CAN_FilterScale_32Bit)
	{
		CAN->Page.Filter.FR[0+fsc] = CAN_FilterID1;
		CAN->Page.Filter.FR[1+fsc] = CAN_FilterID2;
		CAN->Page.Filter.FR[2+fsc] = CAN_FilterID3;
		CAN->Page.Filter.FR[3+fsc] = CAN_FilterID4;
		CAN->Page.Filter.FR[4+fsc] = CAN_FilterIDMask1;
		CAN->Page.Filter.FR[5+fsc] = CAN_FilterIDMask2;
		CAN->Page.Filter.FR[6+fsc] = CAN_FilterIDMask3;
		CAN->Page.Filter.FR[7+fsc] = 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 void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * None
  */
void CAN_ITConfig(CAN_IT_TypeDef CAN_IT, FunctionalState NewState)
{
		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));
    
	CAN->PSR = CAN_Page_Config;
	if (NewState != DISABLE)
	{
		/* Enable the selected CAN interrupt */
		CAN->IER |= (u8)(CAN_IT);
		CAN->Page.Config.EIER |= (u8)(((u16)CAN_IT) >>8);
	}
	else
	{
		/* Disable the selected CAN interrupt */
		CAN->IER &= (u8)(~CAN_IT);
		CAN->Page.Config.EIER &= (u8)~(((u16)CAN_IT) >>8);
	}
    /*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 void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * 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 |= (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 void None
  * @par Required preconditions:
  * None
  * @par Called functions:
  * 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)
	{

⌨️ 快捷键说明

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