打印

关于CAN总线 进入错误中断问题

[复制链接]
7369|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qq302011|  楼主 | 2012-9-16 21:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 qq302011 于 2012-9-16 21:11 编辑



各位前辈:
我使用STM32控制CAN总线;
  硬件环境:


我现在 通过CAN总线给32个模块 发送查询 数据帧,但是实际上我只有一个模块和一个CAN控制器连接到总线,模块的滤波地址为1,控制器是接收所有数据帧,控制器方有120欧姆终端电阻,模块没有终端电阻。
上电后CAN主机按地址 对1-31号模块发送扫描指令,这时候发现,模块1出现 位填充错误  接收错误计数为0XFF,请教如何避免该问题哈?如果不处理该错误,则不能检测到该模块。
我现在的处理方式是 在进入错误中断之后 把CAN外设初始化程序重新运行一遍,运行之后再次扫描则不会出现该问题了。我是用的STM32。请教如何避免该问题的发生?如何再出现问题之后,使用最简单最快速的语句初始化CAN外设?
以下是我的CAN总线程序,请相关高手不吝赐教。谢谢。
void CAN_SetBaudRate(uint8_t iBaud)
{
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = ENABLE; //ENABLE:一旦硬件检测到128 次11位连续的隐性位,则自动退出离线状态
CAN_InitStructure.CAN_AWUM = ENABLE;//ENABLE硬件自动唤醒
CAN_InitStructure.CAN_NART = DISABLE;//DISABLE:CAN报文一直重传直到成功
CAN_InitStructure.CAN_RFLM = ENABLE;//EANBLE:FIFO满之后再次接收到的报文将被丢弃
        CAN_InitStructure.CAN_TXFP=ENABLE;//enable:优先级由发送请求的顺序决定
//          CAN_InitStructure.CAN_TTCM = DISABLE;
//  CAN_InitStructure.CAN_ABOM = DISABLE; //ENABLE:一旦硬件检测到128 次11位连续的隐性位,则自动退出离线状态
//  CAN_InitStructure.CAN_AWUM = DISABLE;//ENABLE硬件自动唤醒
//  CAN_InitStructure.CAN_NART = DISABLE;//DISABLE:CAN报文一直重传直到成功
//  CAN_InitStructure.CAN_RFLM = DISABLE;//EANBLE:FIFO满之后再次接收到的报文将被丢弃
//         CAN_InitStructure.CAN_TXFP=DISABLE;//enable:优先级由发送请求的顺序决定
CAN_InitStructure.CAN_Mode =CAN_Mode_Normal;//CAN_Mode_LoopBack;//
        if(36000000==SystemCoreClock)
        {
                switch (iBaud)
        {
                case 0://5K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 450;
                    break;
                case 1://10K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 225;
                    break;
                case 2: //50K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 45;
                    break;
                case 3: //100K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 10;
                    break;
                case 4://125K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 9;
                    break;
                case 5: //250K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 9;
                    break;
                case 6://500K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 3;
                    break;
                case 7: //1M
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 1;
                    break;
                default://125K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 9;
                    break;
        }
        }
        else
        {
        switch (iBaud)
        {
                case 0://5K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 450;
                    break;
                case 1://10K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 225;
                    break;
                case 2: //50K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 45;
                    break;
                case 3: //100K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 20;
                    break;
                case 4://125K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 18;
                    break;
                case 5: //250K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 9;
                    break;
                case 6://500K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 9;
                    break;
                case 7: //1M
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 3;
                    break;
                default://125K
              CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
              CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
              CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
              CAN_InitStructure.CAN_Prescaler = 18;
                    break;
        }
}
        CAN_Init(CAN1, &CAN_InitStructure);
}
void CAN_SetAddr(uint8_t addr)
{
        uint32_t  address;
        //uint32_t  addrmask;
        address=addr;
        address=address<<(13+3);
        //addrmask=(0xff<<(13+3));
        CAN_FilterInitStructure.CAN_FilterNumber=0;
        CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
        CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)address)&0xFFFF0000)>>16;
  CAN_FilterInitStructure.CAN_FilterIdLow  = (((u32)address)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0x00ff;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0x05;
        //CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0;
  //CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
        CAN_FilterInit(&CAN_FilterInitStructure);
}
void CAN_InitEx(uint8_t addr,uint8_t uBaud)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        NVIC_InitTypeDef  NVIC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIO_CAN1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
        #ifndef AMP12_CAN
        GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);
        #endif
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
        NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        CAN_DeInit(CAN1);
        CAN_SetBaudRate(uBaud);
        CAN_SetAddr(addr);
CAN_ITConfig(CAN1, CAN_IT_BOF|CAN_IT_EPV |CAN_IT_EWG | CAN_IT_ERR, ENABLE);
}
void ICAN_Reset(void)
{
          uint8_t param=*((uint8_t*)(0x1FFFF806));
        uint8_t baud=0;
        uint8_t addr=0;
        GPIO_InitTypeDef  GPIO_InitStructure;
        NVIC_InitTypeDef  NVIC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIO_CAN1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
        if(param==0xff)
        {
                baud=4;
                addr=0x1;
        }
        else
        {
                addr=0x1F¶m;
                baud=param>>5;
        }
        CAN_DeInit(CAN1);
        CAN_SetBaudRate(baud);
        CAN_SetAddr(addr);
  CAN_ITConfig(CAN1, CAN_IT_BOF|CAN_IT_EPV |CAN_IT_EWG | CAN_IT_ERR, ENABLE);
}
void CAN1_SCE_IRQHandler(void)
{
   static uint8_t error;
                if(CAN_GetFlagStatus(CAN1,CAN_FLAG_BOF) == SET)
                {
                        CAN_ClearITPendingBit(CAN1,CAN_IT_BOF);
                }
else if(CAN_GetITStatus(CAN1,CAN_IT_ERR))
        {
                CAN_ClearITPendingBit(CAN1,CAN_IT_ERR);
        }
                else if(CAN_GetFlagStatus(CAN1,CAN_FLAG_EPV) == SET)
                {
                        CAN_ClearITPendingBit(CAN1,CAN_IT_EPV);
                }
                else if(CAN_GetFlagStatus(CAN1,CAN_FLAG_EWG) == SET)
                {
                        CAN_ClearITPendingBit(CAN1,CAN_IT_EWG);
                }
                else
                {
                        CAN_ClearITPendingBit(CAN1,CAN_IT_EWG);
                        CAN_ClearITPendingBit(CAN1,CAN_IT_EPV);
                        CAN_ClearITPendingBit(CAN1,CAN_IT_BOF);
                  CAN_ClearITPendingBit(CAN1,CAN_IT_ERR);
                }
                 error=CAN_GetLastErrorCode(CAN1);
     error=error;
                ICAN_Init();

}
沙发
qq302011|  楼主 | 2012-9-17 10:23 | 只看该作者
香水城在不?能否给指点一下哈

使用特权

评论回复
板凳
IJK| | 2012-9-17 11:47 | 只看该作者
LZ需要先弄清楚CAN总线的基本问题。

CAN总线需要 至少2个模块,才能正常通信。

使用特权

评论回复
地板
qq302011|  楼主 | 2012-9-17 12:20 | 只看该作者
我现在是2个模块呀啊,一个主机模块,一个从设备模块。

使用特权

评论回复
5
qq302011|  楼主 | 2012-9-17 12:20 | 只看该作者
3# IJK 我现在是2个模块呀啊,一个主机模块,一个从设备模块。

使用特权

评论回复
6
IJK| | 2012-9-17 14:19 | 只看该作者
3# IJK 我现在是2个模块呀啊,一个主机模块,一个从设备模块。
qq302011 发表于 2012-9-17 12:20


如果有2个CAN节点 接到总线上,可以用STM32 CAN的例子,应该不会出错。

使用特权

评论回复
7
momoyouzou| | 2013-8-2 13:38 | 只看该作者
不知楼主解决了吗?我也遇到了这样的问题~~~~

使用特权

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

本版积分规则

8

主题

55

帖子

1

粉丝