• 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
    *********************************************************************************************************/
  • 相关阅读:
    Verilog非阻塞赋值的仿真/综合问题 (Nonblocking Assignments in Verilog Synthesis)上
    异步FIFO结构及FPGA设计 跨时钟域设计
    FPGA管脚分配需要考虑的因素
    An Introduction to Delta Sigma Converters (DeltaSigma转换器 上篇)
    An Introduction to Delta Sigma Converters (DeltaSigma转换器 下篇)
    中国通信简史 (下)
    谈谈德国大学的电子专业
    中国通信简史 (上)
    Verilog学习笔记
    Verilog非阻塞赋值的仿真/综合问题(Nonblocking Assignments in Verilog Synthesis) 下
  • 原文地址:https://www.cnblogs.com/ljs-666/p/8099736.html
Copyright © 2020-2023  润新知