• 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
    *********************************************************************************************************/
  • 相关阅读:
    30岁女IT工程师感叹:靠这工具,把报表做成养老工作,月薪快3W
    直播丨墨天轮邂逅MySQL之父,腾讯云CDB/CynosDB技术揭秘之自主可控、前沿探索
    主备库内存不一致的Data Guard环境搭建全过程
    每日一题丨2020.05.27
    Redis Python 客户端
    Hack The Box——Sauna
    数据分析工具测评!被Excel打过的“耳光”,现在可以还回去了
    FORM中的MOAC控制
    网上看到的一张图,销售-客户各层次关系表
    Oracle WorkFlow(工作流)(一)
  • 原文地址:https://www.cnblogs.com/ljs-666/p/8099736.html
Copyright © 2020-2023  润新知