打印
[STM32F1]

CAN接收中断问题

[复制链接]
430|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huangchui|  楼主 | 2022-12-10 13:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用以STM32F103ZET6 为MCU的一块板子调试CAN的收发,外围器件是SN65HVD230D(VP230),用的一款USB-CAN的Adapter连接的电脑,通过PC端配套的Cantools 来进行收发。现在的问题是板子可以发数据到电脑上,也就是发送好用,但是接收数据的时候,只有PC上发送AB AA AA AA AA AA AA AA 的时候能进中断

使用特权

评论回复
沙发
chuxh| | 2022-12-10 13:44 | 只看该作者

AB 后面AA的个数任意?

使用特权

评论回复
板凳
huangchui|  楼主 | 2022-12-10 13:46 | 只看该作者
嗯,发送其它数据,例如11 22 33 44 55 66 77 88  就进不来中断。

使用特权

评论回复
地板
bqyj| | 2022-12-10 13:50 | 只看该作者

void CAN_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;                                                                                 
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

     /* Configure CAN pin: RX */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

     /* Configure CAN pin: TX */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);        
}

void RCC_Configuration(void)
{
  ErrorStatus HSEStartUpStatus;                          //定义外部高速晶体启动状态枚举变量
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* ADCCLK = PCLK2/4=18MHZ */
    RCC_ADCCLKConfig(RCC_PCLK2_Div4);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1 , RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Configure the NVIC Preemption Priority Bits */  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  #ifdef VECT_TAB_RAM
                NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
  #else
                NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
  #endif
   /* Enable the USART2 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* Enable the CAN Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void CAN_Configuration(void)
{
        CAN_InitTypeDef        CAN_InitStructure;
        CAN_FilterInitTypeDef  CAN_FilterInitStructure;

   /* CAN Periph clock enable */        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

        CAN_DeInit(CAN1);
        CAN_StructInit(&CAN_InitStructure);
        
        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;                                        //失能发送FIFO优先级
        CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;                        //CAN硬件工作在普通模式
        /* 200K的波特率 */
        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;                                        //重新同步跳跃宽度1个时间单位
        CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;                                                //时间段1为9个时间单位
        CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;                                                //时间段2为8个时间单位
        CAN_InitStructure.CAN_Prescaler = 10;                                                        //时间单位的长度
        CAN_Init(CAN1, &CAN_InitStructure);                                                        //200K=36M/(1+9+8)*10

        CAN_FilterInitStructure.CAN_FilterNumber = 0;                                                //待初始化的过滤器0
        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;                //标识符屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;                //1个32位过滤器
        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;                                
        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;                                //使能过滤器
        CAN_FilterInit(&CAN_FilterInitStructure);
}

下面是中断服务函数
void USB_LP_CAN1_RX0_IRQHandler(void)               
{
        u8 i ;               
        CanRxMsg RxMessage;
        RxMessage.StdId=0x00;
        RxMessage.ExtId=0x00;
        RxMessage.IDE=0;
        RxMessage.DLC=0;
        RxMessage.FMI=0;
        RxMessage.Data[0]=0x00;
        RxMessage.Data[1]=0x00;
        RxMessage.Data[2]=0x00;
        RxMessage.Data[3]=0x00;
        RxMessage.Data[4]=0x00;
        RxMessage.Data[5]=0x00;
        RxMessage.Data[6]=0x00;
        RxMessage.Data[7]=0x00;
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);        

        for(i=0; i<8; i++)                                                       //通过串口将CAN收到的数据发出来到串口助手上
    {                                                                                                                                                                                                
                USART_ClearFlag(USART2, USART_FLAG_TC);                                                         
                USART_SendData(USART2,RxMessage.Data);                    
                while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);                        
    }

        CAN_FIFORelease(CAN1,CAN_FIFO0);//释放邮箱
}

最后是主函数
int main(void)
{
          RCC_Configuration();
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1 , ENABLE);
        NVIC_Configuration();
        TIM_Configuration();        
                CAN_GPIO_Config();
        CAN_Configuration();
        CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);  //CAN中断

        USART_GPIO_Config();
        USART2_Config();
       while(1)                 {        
         }        
}        

使用特权

评论回复
5
songqian17| | 2022-12-10 13:57 | 只看该作者
你从PC发送过来的数据格式跟接收端设置一直吗?

使用特权

评论回复
6
huangchui|  楼主 | 2022-12-10 13:59 | 只看该作者
串口发送是在CAN接收中断里面的,就是收到AB AA AA ...的时候能进中断,然后串口能发出来,其它时候都进不来中断,也就没法通过串口发出去。。。

使用特权

评论回复
7
huangchui|  楼主 | 2022-12-10 14:00 | 只看该作者
刚才看了下配置也一样啊还有可能是哪里的问题呢?想好几天了想不通啊。。。

使用特权

评论回复
8
yszong| | 2022-12-10 14:02 | 只看该作者
然后呢?你是怎么应对这个的呢

使用特权

评论回复
9
dingy| | 2022-12-10 14:04 | 只看该作者
能发送不能接收,那基本是程序问题;
硬件的话用示波器看下

使用特权

评论回复
10
xxrs| | 2022-12-10 14:07 | 只看该作者
CanRxMsg RxMessage; 这个应该放在外部定义

使用特权

评论回复
11
jlyuan| | 2022-12-10 14:11 | 只看该作者
用示波器看看波形

使用特权

评论回复
12
chenjunt| | 2022-12-10 14:13 | 只看该作者
确认发送的数据没有问题吗

使用特权

评论回复
13
xxrs| | 2022-12-10 14:15 | 只看该作者
你的那问题是在太奇怪了  没有遇到过 只能自己摸索了 但是感觉 应该是软件问题

使用特权

评论回复
14
yszong| | 2022-12-10 14:17 | 只看该作者
有没有可能是发送端发送的是由于程序的关系没有发送出来呢

使用特权

评论回复
15
dingy| | 2022-12-10 14:19 | 只看该作者
从来没偶遇到过这么奇怪的问题

使用特权

评论回复
16
dengdc| | 2022-12-10 14:25 | 只看该作者
首先这个波特率设置有问题,你这里 1+9+8=28 ,调整在20左右吧,最大是25
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;                                        //重新同步跳跃宽度1个时间单位
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;                                                //时间段1为9个时间单位
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;                                                //时间段2为8个时间单位

使用特权

评论回复
17
dengdc| | 2022-12-10 14:27 | 只看该作者
CAN_FIFORelease(CAN1,CAN_FIFO0); //释放邮箱        
中断里读取数据后自动释放的,这个注释了不要

使用特权

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

本版积分规则

918

主题

12323

帖子

4

粉丝