打印

CAN通信问题

[复制链接]
1338|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
拿起书本|  楼主 | 2014-9-9 09:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用的stm32f2xx_stdperiph_lib里的示例程序做CAN通信测试,环回模式测试OK。正常模式下,用CAN调试软件向板子发数据,始终进不了接收中断

.c文件

int main(void)
{

  /* NVIC configuration */
  NVIC_Config();

  /* CAN configuration */
  CAN_Config();

  /* Infinite loop */
  while(1)
  {
        Delay();
  }
}

void CAN_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  /* CAN GPIOs configuration **************************************************/

  /* Enable GPIO clock */
  RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK, ENABLE);

  GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
  GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT);

  /* Configure CAN RX and TX pins */
  GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(CAN_GPIO_PORT, &GPIO_InitStructure);

  /* CAN configuration ********************************************************/
  /* Enable CAN clock */
  RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

  /* CAN register init */
  CAN_DeInit(CANx);

  /* 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_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
   
  /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */
  /*CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
  CAN_InitStructure.CAN_Prescaler = 2;
  CAN_Init(CANx, &CAN_InitStructure);*/


  /* CAN filter init */
#ifdef  USE_CAN1
  CAN_FilterInitStructure.CAN_FilterNumber = 0;
#else /* USE_CAN2 */
  CAN_FilterInitStructure.CAN_FilterNumber = 14;
#endif  /* USE_CAN1 */
  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 = 0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
   
  /* Enable FIFO 0 message pending Interrupt */
  CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}

void NVIC_Config(void)
{
  NVIC_InitTypeDef  NVIC_InitStructure;

#ifdef  USE_CAN1
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
#else  /* USE_CAN2 */
  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
#endif /* USE_CAN1 */

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

.h头文件

#define USE_CAN1

//#define USE_CAN2

#ifdef  USE_CAN1
  #define CANx                       CAN1
  #define CAN_CLK                    RCC_APB1Periph_CAN1
  #define CAN_RX_PIN                 GPIO_Pin_11
  #define CAN_TX_PIN                 GPIO_Pin_12
  #define CAN_GPIO_PORT              GPIOA
  #define CAN_GPIO_CLK               RCC_AHB1Periph_GPIOA
  #define CAN_AF_PORT                GPIO_AF_CAN1
  #define CAN_RX_SOURCE              GPIO_PinSource11
  #define CAN_TX_SOURCE              GPIO_PinSource12      
#else /*USE_CAN2*/
  #define CANx                       CAN2
  #define CAN_CLK                    (RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2)
  #define CAN_RX_PIN                 GPIO_Pin_12
  #define CAN_TX_PIN                 GPIO_Pin_13
  #define CAN_GPIO_PORT              GPIOB
  #define CAN_GPIO_CLK               RCC_AHB1Periph_GPIOB
  #define CAN_AF_PORT                GPIO_AF_CAN2
  #define CAN_RX_SOURCE              GPIO_PinSource12
  #define CAN_TX_SOURCE              GPIO_PinSource13   
#endif  /* USE_CAN1 */

stm32f2xx_it.c 文件中涉及的CAN接收中断程序

#ifdef USE_CAN1
void CAN1_RX0_IRQHandler(void)
{
  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
   CAN_FIFORelease(CAN2, CAN_FIFO0);
}
#endif  /* USE_CAN1 */

#ifdef USE_CAN2
/**
  * @brief  This function handles CAN2 RX0 request.
  * @param  None
  * @retval None
  */
void CAN2_RX0_IRQHandler(void)
{
  CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);
    CAN_FIFORelease(CAN2, CAN_FIFO0);
}
#endif  /* USE_CAN2 */

以上,PC端通过USB-CAN-A2设备与板子连接,CAN调试工具不断发数据。用示波器测收发器的CANH及CANL脚,有脉冲波形,说明CAN口能正常接收到PC端数据。但测收发器的RX脚(RX脚连MCU引出的PA11脚,复用为CAN_RX功能)始终为高电平,没有收到有效信号。


沙发
mmuuss586| | 2014-9-9 12:31 | 只看该作者
看你的程序没看出啥问题,下面我调通过的程序:
你测试下,能否通讯上;
#define CAN_GPIO_CLK               RCC_AHB1Periph_GPIOA
#define CANx                       CAN1
#define CAN_CLK                    RCC_APB1Periph_CAN1
#define CAN_RX_PIN                 GPIO_Pin_11
#define CAN_TX_PIN                 GPIO_Pin_12
#define CAN_GPIO_PORT                           GPIOA
#define CAN_AF_PORT                GPIO_AF_CAN1
#define CAN_RX_SOURCE              GPIO_PinSource11
#define CAN_TX_SOURCE              GPIO_PinSource12   

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
CAN_InitTypeDef        CAN_InitStructure;
CAN_FilterInitTypeDef  CAN_FilterInitStructure;
CanTxMsg TxMessage;

/**
  * @brief  Configures the NVIC for CAN.
  * @param  None
  * @retval None
  */
void Can1_NVIC_Config(void)
{
  NVIC_InitTypeDef  NVIC_InitStructure;
       
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  Configures the CAN.
  * @param  None
  * @retval None
  */
void CAN_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  
        RCC_APB2PeriphClockCmd(CAN_GPIO_CLK, ENABLE);
        // Enable GPIO clock
  RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK, ENABLE);
  //CAN GPIOs configuration **************************************************

  // Connect CAN pins to AF9
  GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
  GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT);
  
  // Configure CAN RX and TX pins
        GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(CAN_GPIO_PORT, &GPIO_InitStructure);

  // CAN configuration ********************************************************
  // Enable CAN clock
  RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);
  
  // CAN register init
  CAN_DeInit(CANx);

  // 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_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
   
  // CAN Baudrate = 1 MBps (CAN clocked at 30 MHz)
        //BaudRate = PCLK1/((BS1 + BS2 + 1)*Prescaler)=(168/4)/((5+8+1)*3)=1M
  CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
  CAN_InitStructure.CAN_Prescaler = 3;
  CAN_Init(CANx, &CAN_InitStructure);

  CAN_FilterInitStructure.CAN_FilterNumber = 0;

  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 = 0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
  
  // Transmit Structure preparation
  TxMessage.StdId = 0x321;
  TxMessage.ExtId = 0x01;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 8;
  
  // Enable FIFO 0 message pending Interrupt
  CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}

//³õʼ»¯CAN0
void Can1_Init(void)
{
        Can1_NVIC_Config();
        //CAN configuration
  CAN_Config();
}

使用特权

评论回复
板凳
mmuuss586| | 2014-9-9 12:33 | 只看该作者
硬件参考:

使用特权

评论回复
地板
feilusia| | 2014-9-9 15:34 | 只看该作者
试试把CAN的时钟使能放在最前面,印象中时钟没使能是配置不了相关寄存器的。

使用特权

评论回复
5
zh113214| | 2014-9-9 22:47 | 只看该作者
进来看看,学习哈子!!

使用特权

评论回复
6
hqtdzgs| | 2014-9-10 08:11 | 只看该作者
CAN应用,学习中。。。

使用特权

评论回复
7
huangfeng33| | 2014-9-10 14:37 | 只看该作者
我没用过F2,F2的APB1是30M?有波形,进不了中断的话,不是线接反了就是波特率不……

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:好好学习,天天向上!

519

主题

4194

帖子

31

粉丝