can_loopBack

/*********************************************************************************************************
*
* File                : main.c
* Hardware Environment: 
* Build Environment   : RealView MDK-ARM  Version: 4.20
* Version             : V1.0
* By                  : 
*
*                                  (c) Copyright 2005-2011, WaveShare
*                                       http://www.waveshare.net
*                                          All Rights Reserved
*
*********************************************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/* Private variables ---------------------------------------------------------*/
__IO uint32_t Result = 0; /* for return of the interrupt handling */

/* Private function prototypes -----------------------------------------------*/
void GPIO_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);
int CAN_Polling(void);
int CAN_Interrupt(void);

/*******************************************************************************
* Function Name  : Delay
* Description    : Delay Time
* Input          : - nCount: Delay Time
* Output         : None
* Return         : None
* Attention         : None
*******************************************************************************/
void  Delay (uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}


/*******************************************************************************
* Function Name  : main
* Description    : Main program
* Input          : None
* Output         : None
* Return         : None
* Attention         : None
*******************************************************************************/
int main(void)
{
  int TestRx;

    NVIC_Configuration();
    GPIO_Configuration();
    USART_Configuration();

  printf("
****************************************************************
");

     printf("CAN-Bus Test 
");

  /* CAN transmit at 100Kb/s and receive by polling in loopback mode */
  TestRx = CAN_Polling();

  if (TestRx == DISABLE)
  {
    printf("CAN-Bus by polling in loopback mode is False 
");
  }
  else
  {
    printf("CAN-Bus by polling in loopback mode is OK 
");
  }

  /* CAN transmit at 500Kb/s and receive by interrupt in loopback mode */
  TestRx = CAN_Interrupt();

  if (TestRx == DISABLE)
  {
    printf("CAN-Bus by interrupt in loopback mode is False 
");
  }
  else
  {
    printf("CAN-Bus by interrupt in loopback mode is OK 
");
  }

  /* Infinite loop */
  while (1)
  {
    /*====LED-ON=======*/
    GPIO_SetBits(GPIOF , GPIO_Pin_6);
    GPIO_SetBits(GPIOF , GPIO_Pin_7);
    GPIO_SetBits(GPIOF , GPIO_Pin_8);
    GPIO_SetBits(GPIOF , GPIO_Pin_9);
    Delay(0xfffff);
    Delay(0xfffff);
    Delay(0x5ffff);    

    /*====LED-OFF=======*/ 
    GPIO_ResetBits(GPIOF , GPIO_Pin_6);
    GPIO_ResetBits(GPIOF , GPIO_Pin_7);
    GPIO_ResetBits(GPIOF , GPIO_Pin_8);
    GPIO_ResetBits(GPIOF , GPIO_Pin_9);
    Delay(0xfffff);
    Delay(0xfffff);
    Delay(0x5ffff);    
  }
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configures the different GPIO ports.
* Input          : None
* Output         : None
* Return         : None
* Attention         : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;//初始化I/O
  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOF , ENABLE); //使能高速APB2时钟,使能端口时钟
  /* CAN1 Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);    //使能低速APB1时钟,使能端口时钟                     
  
  /* Configure CAN pin: TX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//PB9端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  GPIO_PinRemapConfig(AFIO_MAPR_CAN_REMAP_REMAP2 , ENABLE);    
  
/**
 *  LED1 -> PF6 , LED2 -> PF7 , LED3 -> PF8 , LED4 -> PF9
 */                     
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  GPIO_Init(GPIOF, &GPIO_InitStructure);
}

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures the nested vectored interrupt controller.
* Input          : None
* Output         : None
* Return         : None
* Attention         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable CAN1 RX0 interrupt IRQ channel */
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占式中断优先级为0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//响应式中断优先级为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
  NVIC_Init(&NVIC_InitStructure);
}

/*******************************************************************************
* Function Name  : CAN_Polling
* Description    : Configures the CAN, transmit and receive by polling.
* Input          : None
* Output         : None
* Return         : PASSED if the reception is well done, FAILED in other case
* Attention         : None
*******************************************************************************/
int CAN_Polling(void)
{
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  CanTxMsg TxMessage;//定义发送消息
  CanRxMsg RxMessage;//描述接受消息
  uint32_t i = 0;//1个字节
  uint8_t TransmitMailbox = 0;//4个字节

  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
  CAN_InitStructure.CAN_ABOM=DISABLE;//离线模式由软件实现
  CAN_InitStructure.CAN_AWUM=DISABLE;//软件唤醒
  CAN_InitStructure.CAN_NART=DISABLE;//禁止自动重传
  CAN_InitStructure.CAN_RFLM=DISABLE;//接受溢出时FIFO不锁定,下一个收到的报文覆盖原有报文
  CAN_InitStructure.CAN_TXFP=DISABLE;//优先级由报文的标识符来决定
  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;//CAN硬件工作环回模式
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度为2个时间单位
  CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;//时间段为8个时间单位
  CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//时间段为7个时间单位
  CAN_InitStructure.CAN_Prescaler=5;//设定一个时间单位的长度为5,范围(1~1024)
  CAN_Init(CAN1, &CAN_InitStructure);

  /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber=0;//设置过滤器组0,范围为0~13
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//设定过滤器组为屏蔽位模式
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽为32位过滤器一个
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//设定过滤器标识符高位(32为高位段,16位为第一个)
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//设定过滤器标识符低位(32为低位段,16位为第二个)
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//设定过滤器标识符高位(32为高位段,16位为第一个)
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//设定过滤器标识符低位(32为低位段,16位为第二个)
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;/使能过滤器
  CAN_FilterInit(&CAN_FilterInitStructure);

  /* transmit */
  TxMessage.StdId=0x11;// 标准标识符
  TxMessage.RTR=CAN_RTR_DATA;// 数据帧
  TxMessage.IDE=CAN_ID_STD;// 标准帧
  TxMessage.DLC=2;// 要发送的数据长度
  TxMessage.Data[0]=0xCA;
  TxMessage.Data[1]=0xFE;

  TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);//启动传输一个消息
  i = 0;
  while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFF))//判断 信息有没有发送成功的
  {
    i++;
  }

  i = 0;
  while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFF))//判断 接收邮箱有没有收到信息
  {
    i++;
  }

  /* receive */
  RxMessage.StdId=0x00;
  RxMessage.IDE=CAN_ID_STD;
  RxMessage.DLC=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;
  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//接受一个消息

  if (RxMessage.StdId!=0x11)
  {
    return DISABLE;  
  }

  if (RxMessage.IDE!=CAN_ID_STD)
  {
    return DISABLE;
  }

  if (RxMessage.DLC!=2)
  {
    return DISABLE;  
  }

  if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
  {
    return DISABLE;
  }
  
  return ENABLE; /* Test Passed */
}

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures the CAN, transmit and receive using interrupt.
* Input          : None
* Output         : None
* Return         : PASSED if the reception is well done, FAILED in other case
* Attention         : None
*******************************************************************************/
int CAN_Interrupt(void)
{
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  CanTxMsg TxMessage;
  uint32_t i = 0;

  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM=DISABLE;
  CAN_InitStructure.CAN_ABOM=DISABLE;
  CAN_InitStructure.CAN_AWUM=DISABLE;
  CAN_InitStructure.CAN_NART=DISABLE;
  CAN_InitStructure.CAN_RFLM=DISABLE;
  CAN_InitStructure.CAN_TXFP=DISABLE;
  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
  CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
  CAN_InitStructure.CAN_Prescaler=1;
  CAN_Init(CAN1, &CAN_InitStructure);

  /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber=1;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;//此过滤器组关联到接收FIFO0
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);

  /* CAN FIFO0 message pending interrupt enable */ 
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);//CAN中断开通设置中断源的动作条件

  /* transmit 1 message */
  TxMessage.StdId=0x00;
  TxMessage.ExtId=0x1234;//扩展标识符
  TxMessage.IDE=CAN_ID_EXT;
  TxMessage.RTR=CAN_RTR_DATA;
  TxMessage.DLC=2;
  TxMessage.Data[0]=0xDE;
  TxMessage.Data[1]=0xCA;
  CAN_Transmit(CAN1, &TxMessage);

  /* initialize the value that will be returned */
  Result = 0xFF;
       
  /* receive message with interrupt handling */
  i=0;
  while((Result == 0xFF) && (i < 0xFFF))
  {
    i++;
  }
  
  if (i == 0xFFF)
  {
    Result=0;  
  }

  /* disable interrupt handling */
  CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);

  return (FunctionalState)Result;
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d
", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/*********************************************************************************************************
      END FILE
*********************************************************************************************************/
原文地址:https://www.cnblogs.com/ljs-666/p/8099736.html