pepperking 发表于 2023-11-13 17:46:06

stc32G的can口如果没有收到ACK回复,单片机会产生什么动作


1、程序会一直重发直到进入busoff状态吗?
2、进入BUSOFF状态后,程序就跳出中断,执行之后的代码吗?
3、如果不清除BUSOFF状态,仍然操作CAN发送数据是否是无效操作?(即不产生任何中断,继续执行主程序)。

还请大佬指教

乘风飞扬 发表于 2023-11-13 17:56:06

1. 程序会一直重发直到进入bus-off状态。
2. 如果设置了错误中断,并触发了中断,中断退出后可以继续执行主程序。
3. 如果不清除bus-off状态,操作CAN发送是无效操作,可以继续执行主程序。

njrdxdz 发表于 2023-11-14 09:45:55

1、总线上只有一个节点时,该节点发送后得不到ACK,此时TEC最大到128,而不会触发BUSoff

pepperking 发表于 2023-11-14 10:12:04

本帖最后由 pepperking 于 2023-11-14 14:35 编辑

乘风飞扬 发表于 2023-11-13 17:56
1. 程序会一直重发直到进入bus-off状态。
2. 如果设置了错误中断,并触发了中断,中断退出后可以继续执行主 ...
CAN口可以配置成只发一次数据(无论成功或者失败)吗?

pepperking 发表于 2023-11-14 10:47:54

本帖最后由 pepperking 于 2023-11-14 11:48 编辑

njrdxdz 发表于 2023-11-14 09:45
1、总线上只有一个节点时,该节点发送后得不到ACK,此时TEC最大到128,而不会触发BUSoff
...
那有办法在单节点情况下,只发送一次CAN数据吗?

乘风飞扬 发表于 2023-11-14 17:39:31

pepperking 发表于 2023-11-14 10:12
CAN口可以配置成只发一次数据(无论成功或者失败)吗?

发送成功不会重发,如果发送失败时会产生总线错误中断(BEI)


此时可以设置终止当前帧的传输,就不会重发了:





pepperking 发表于 2023-11-15 15:42:36

本帖最后由 pepperking 于 2023-11-15 16:02 编辑

乘风飞扬 发表于 2023-11-14 17:39
发送成功不会重发,如果发送失败时会产生总线错误中断(BEI)



我在BEI的中断服务那加上AT置1,发生总线错误(直接把CAN接口从总线上拔下来)时标志位能正常变动(但无法跳转回主程序),总线恢复(把CAN接口插回总线)也不会恢复正常。
如果在BEI的中断服务那只是操作我的标志位,总线错误时我的标志位能正常变动(但无法跳转回主程序),总线恢复后,能够发送数据并跳转回主程序。

请问操作AT时有什么注意事项吗?

主程序如下,省略了初始化
      while(1)
      {
            CanSendMsg(&CAN1_Tx);
            if(can_isr_flag.flag2 == 1)//有发生过错误
            KLED = 1;//灭灯
      
            
      }

中断服务代码如下      

void CAN1_ISR_Handler (void) interrupt CAN1_VECTOR
{
        u8 isr;
        u8 store;
        u8 arTemp;

        arTemp = CANAR;   //先CANAR现场保存,避免主循环里写完 CANAR 后产生中断,在中断里修改了 CANAR 内容
        store = AUXR2;      //后AUXR2现场保存
       
        AUXR2 &= ~0x08;                //选择CAN1模块
        isr = CanReadReg(ISR);

        if((isr & 0x04) == 0x04)//TI
        {
                CANAR = ISR;
                CANDR = 0x04;    //CLR FLAG
      
      B_Can1Send = 0;
}       
        if((isr & 0x08) == 0x08)//RI
        {
                CANAR = ISR;
                CANDR = 0x08;    //CLR FLAG
       
                B_Can1Read = 1;
        }

        if((isr & 0x40) == 0x40)//ALI
        {
                CANAR = ISR;
                CANDR = 0x40;    //CLR FLAG
        }       

        if((isr & 0x20) == 0x20)//EWI
        {
                CANAR = MR;
                CANDR &= ~0x04;//清除 Reset Mode, 从BUS-OFF状态退出

                CANAR = ISR;
                CANDR = 0x20;    //CLR FLAG
        }       

        if((isr & 0x10) == 0x10)//EPI
        {
                CANAR = ISR;
                CANDR = 0x10;    //CLR FLAG

        }       

        if((isr & 0x02) == 0x02)//BEI
        {
                CANAR = ISR;
                CANDR = 0x02;    //CLR FLAG

//      CANAR = CMR;

//      CANDR = 0x02;
                KLED = 0;//置0时LED点亮
      can_isr_flag.flag2 = 1;//发生错误的标志位
        }       

        if((isr & 0x01) == 0x01)//DOI
        {
                CANAR = ISR;
                CANDR = 0x01;    //CLR FLAG
        }       

        AUXR2 = store;   //先AUXR2现场恢复
        CANAR = arTemp;    //后CANAR现场恢复
}

pepperking 发表于 2023-11-15 16:12:07

本帖最后由 pepperking 于 2023-11-15 16:56 编辑

pepperking 发表于 2023-11-15 15:42
我在BEI的中断服务那加上AT置1,发生总线错误(直接把CAN接口从总线上拔下来)时标志位能正常变动(但无法 ...
找到原因了
如果用的是官方的can发送库函数的话,在BEI中断里使用用AT终止发送命令,要把发送函数里的标志位(如B_Can1Send之类的)一块清掉,否则下一次调用该函数就会卡住,正常情况下这个标志位是在TI中断里清除的。

乘风飞扬 发表于 2023-11-15 17:33:30

pepperking 发表于 2023-11-15 16:12
找到原因了
如果用的是官方的can发送库函数的话,在BEI中断里使用用AT终止发送命令,要把发送函数里的标志 ...

最新的例程包里面已经在发送函数里添加超时退出功能,这样就不会卡在判断指令了。
页: [1]
查看完整版本: stc32G的can口如果没有收到ACK回复,单片机会产生什么动作