找回密码
 立即注册
查看: 3402|回复: 3

CAN未能进入中断服务程序,求解

[复制链接]
  • TA的每日心情
    开心
    11 小时前
  • 签到天数: 137 天

    [LV.7]常住居民III

    12

    主题

    98

    回帖

    1398

    积分

    金牌会员

    积分
    1398
    发表于 2023-3-13 21:51:33 | 显示全部楼层 |阅读模式
    本帖最后由 gzlai 于 2023-3-13 21:56 编辑

    CAN配置如下:

    void CAN_config(void)
    {
            CAN_InitTypeDef        CAN_InitStructure;                                        //结构定义


            CAN_InitStructure.CAN_Enable = ENABLE;                //CAN功能使能   ENABLE或DISABLE
            CAN_InitStructure.CAN_IMR = CAN_ALLIM;        //CAN中断寄存器         CAN_DOIM,CAN_BEIM,CAN_TIM,CAN_RIM,CAN_EPIM,CAN_EWIM,CAN_ALIM,CAN_ALLIM,DISABLE
            CAN_InitStructure.CAN_SJW = 0;                                        //重新同步跳跃宽度  0~3
            CAN_InitStructure.CAN_SAM = 0;                                        //总线电平采样次数  0:采样1次; 1:采样3次


                                                                                                            //CAN总线波特率=Fclk/((1+(TSG1+1)+(TSG2+1))*(BRP+1)*2)
            CAN_InitStructure.CAN_TSG1 = 2;                                        //同步采样段1       0~15
            CAN_InitStructure.CAN_TSG2 = 1;                                        //同步采样段2       1~7 (TSG2 不能设置为0)
            CAN_InitStructure.CAN_BRP = 15;                                        //波特率分频系数    0~63
                                                                                                            //24000000/((1+3+2)*16*2)=125KHz


            CAN_InitStructure.CAN_ACR0 = 0x00;                        //总线验收代码寄存器 0~0xFF
            CAN_InitStructure.CAN_ACR1 = 0x00;
            CAN_InitStructure.CAN_ACR2 = 0x00;
            CAN_InitStructure.CAN_ACR3 = 0x00;
            CAN_InitStructure.CAN_AMR0 = 0xff;                        //总线验收屏蔽寄存器 0~0xFF
            CAN_InitStructure.CAN_AMR1 = 0xff;
            CAN_InitStructure.CAN_AMR2 = 0xff;
            CAN_InitStructure.CAN_AMR3 = 0xff;
            CAN_Inilize(CAN1, &CAN_InitStructure);                        //CAN1 初始化


            NVIC_CAN_Init(CAN1, ENABLE, Priority_1);                //中断使能, CAN1/CAN2; ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    }

    我的任务函数是利用CAN发送轮询,具体如下:

    portTASK_FUNCTION(vDCUTask, pvParameters)
    {
            unsigned int DCUID = 0;//板内DCU编号
            unsigned int PICID;//存放功能码+地址码
            unsigned char sr;        
            unsigned char timeout_limit;
            unsigned char timeout_count = 0;
            unsigned char temp[11];
            unsigned char i;


            UNUSED(pvParameters);


            while (1)
            {
                    while (DCUID < DCU_COUNT)//逐个DCU轮询
                    {
                            PICID = 0x0004;//加入DCU实时数据读取功能码
                            PICID = (PICID << 7) + DCUID + 1ul;//加入DCU地址码
                            CANSEL = CAN1;                //选择CAN1模块
                            sr = CanReadReg(SR);//获取CAN状态
                            if (sr & 0x01)                //判断是否有 BS:BUS-OFF状态
                            {
                                    CANAR = MR;
                                    CANDR &= ~0x04;  //清除 Reset Mode, 从BUS-OFF状态退出
                            }
                            else
                            {
                                    B_Can1Send = 1;
                                    CMDFromPEDCToDCU(PICID);//发送轮询命令
                                    while (B_Can1Send)//等待轮询命令发送完毕
                                    {
                                            taskYIELD();
                                            P20 = 0;
                                    }
                                    P20 = 1;
                                    timeout_limit = DCU_TIMEOUT_LIMIT;//设置等待反馈时间上限
                                    while (timeout_limit--)//等待DCU反馈
                                    {
                                            if (((sr & 0x88) == 0x80))//接收空闲并且接收BUFFER有数据帧
                                            {
                                                    break;//直接退出等待
                                            }
                                            vTaskDelay(1);
                                    }
                                    if (timeout_limit == 0)//本次轮询反馈超时
                                    {
                                            DCU_Timeout_Count[DCUID]++;//
                                           
                                    }
                                    else
                                    {
                                            DCU_Timeout_Count[DCUID] = 0;
                                            CanReadFifo(temp);  //读取清除接收BUFFER
                                            for (i = 0; i < 8; i++)//接收到的数据放入DCU状态数组
                                            {
                                                    DCU_State[DCUID] = temp[i + 3];
                                            }
                                    }
                            }
                            DCUID++;//启动下一个DCU轮询
                    }
                    DCUID = 0;//复位轮询
            }
    }


    利用屠龙刀核心板调试上述代码时,发现发送数据的CAN1一直未能进入中断服务函数,在中断服务函数里设了断点也验证了程序未进入中断服务函数,请问是哪里漏了什么步骤吗?
    CAN未能进入中断服务程序,求解-1.png







    FreeRTOS-PEDC.zip

    2.59 MB, 下载次数: 46

    回复 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    9 小时前
  • 签到天数: 119 天

    [LV.6]常住居民II

    26

    主题

    1226

    回帖

    3841

    积分

    论坛元老

    积分
    3841
    发表于 2023-3-14 10:19:22 | 显示全部楼层
    我在你的代码中断函数里面加一个IO口翻转,通过示波器可以测出IO口翻转信号,说明进入中断是正常的。

    此外,使用CAN总线测试工具也能抓到发送的轮询命令:
    1.png
    通过硬件仿真在中断函数里面加断点也能正常停止:
    2.png
  • TA的每日心情
    奋斗
    9 小时前
  • 签到天数: 119 天

    [LV.6]常住居民II

    26

    主题

    1226

    回帖

    3841

    积分

    论坛元老

    积分
    3841
    发表于 2023-3-14 10:27:41 | 显示全部楼层
    此外,CAN总线收发函数后来进行了优化,在官网STC32G库函数例程包、STC32G实验箱例程包里面的CAN总线例子上都已经进行了更新。
    建议将新的方法移植过来,可提高收发效率,减少丢包可能。
  • TA的每日心情
    开心
    11 小时前
  • 签到天数: 137 天

    [LV.7]常住居民III

    12

    主题

    98

    回帖

    1398

    积分

    金牌会员

    积分
    1398
     楼主| 发表于 2023-3-14 22:44:21 | 显示全部楼层
    今天把例程里的STC32G_CAN.h、STC32G_CAN.c、STC32_CAN_Isr.c全部替换到我自己的工程里,修改、测试完了,功能正常,非常感谢:handshake
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-4-20 20:45 , Processed in 0.070782 second(s), 43 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表