CAN_Transmit(CAN1, &TxMessage);返回CAN_TxStatus_NoMailBox

2019-07-21 06:17发布

单片机芯片:STM32F103ZET6
CAN收发芯片:ISO1050隔离式收发芯片

程序定时通过CAN发送数据。在上电运行后,能正常收发通讯,并用示波器检测到信号波形。运行过程中,断开CAN收发芯片电源然后又重新接上。发现程序不能发送数据,经调试发现CAN_Transmit(CAN1, &TxMessage);发送数据后返回0x04 = (CAN_TxStatus_NoMailBox)。请问各位大神是什么导致该现象产生?另外,程序需要做什么处理才能继续收发数据?

CAN初始化:CAN1_Init(CAN_SJW_1tq, CAN_BS2_8tq, CAN_BS1_9tq, 4, CAN_Mode_Normal);//CAN初始化为正常模式,波特率为:500Kbps

[mw_shl_code=c,true]
void CAN1_Init(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode)
{
        GPIO_InitTypeDef                                GPIO_InitStructure;
        CAN_InitTypeDef                                        CAN_InitStructure;
        CAN_FilterInitTypeDef                CAN_FilterInitStructure;
        NVIC_InitTypeDef                                NVIC_InitStructure;
       
        //使能GPIOA、CAN1的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
       
        //CAN1_RX                        GPIOA.11
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PA11
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.11
       
        //CAN1_TX                        GPIOA.12
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//PA12
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.12
       
        //CAN参数配置
        CAN_InitStructure.CAN_TTCM = DISABLE;                //非时间触发通信模式
        CAN_InitStructure.CAN_ABOM = DISABLE;                //软件自动离线管理
        CAN_InitStructure.CAN_AWUM = DISABLE;                //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
        CAN_InitStructure.CAN_NART = ENABLE;                //禁止报文自动传送
        CAN_InitStructure.CAN_RFLM = DISABLE;                //报文不锁定,新的覆盖旧的
        CAN_InitStructure.CAN_TXFP = DISABLE;                //优先级由报文标识符决定
        CAN_InitStructure.CAN_Mode = mode;                        //模式设置:mode:0,普通模式;1,回环模式;
        //设置波特率
        CAN_InitStructure.CAN_SJW = tsjw;                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位        CAN_SJW_1tq ~ CAN_SJW_4tq
        CAN_InitStructure.CAN_BS1 = tbs1;                //Tbs1 = tbs1+1个时间单位                CAN_BS1_1tq ~ CAN_BS1_16tq
        CAN_InitStructure.CAN_BS2 = tbs2;                //Tbs2 = tbs2+1个时间单位                CAN_BS2_1tq ~ CAN_BS2_8tq
        CAN_InitStructure.CAN_Prescaler = brp;//分频系数(Fdiv)为brp+1
        CAN_Init(CAN1, &CAN_InitStructure);        //初始化CAN1
       
        //过滤器参数配置
        CAN_FilterInitStructure.CAN_FilterNumber = 0;        //使用过滤器0
        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//32位宽
        CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;        //32位ID_高16位
        CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;                //32位ID_低16位
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//32位MASK_高16位
        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//32位MASK_低16位
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;//过滤器0关联到FIFO0
        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//激活过滤器0
        CAN_FilterInit(&CAN_FilterInitStructure);//初始化过滤器组
       
        //接收中断参数配置
        CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);//FIFO0消息挂号中断允许
        NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子优先级0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//接收IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);//初始化接收中断配置
}
[/mw_shl_code]


[mw_shl_code=c,true]
u8 Can_Send_Message(u8 stdID, u8 extID, u8 * msg, u8 len)
{
        u8 retMsgBox;//返回邮箱号
        u16 i = 0;
        CanTxMsg TxMessage;
       
        //填充数据包
        TxMessage.StdId = stdID;                //标准标识符,低11位有效
        TxMessage.ExtId = extID;                //拓展标识符,低29位有效
        TxMessage.IDE = CAN_ID_STD;//标准帧
        TxMessage.RTR = CAN_RTR_DATA;//数据帧
        TxMessage.DLC = len;//发送数据长度
        for(i = 0; i < len; i++)
        {
                TxMessage.Data = msg;
        }
        //发送数据包
        retMsgBox = CAN_Transmit(CAN1, &TxMessage);
        i = 0;
        while((CAN_TransmitStatus(CAN1, retMsgBox) == CAN_TxStatus_Failed)&&(i < 0xFFF))//等待发送结束
        {
                i++;
        }
        if(i >= 0xFFF)
        {
                return 1;//超时失败返回
        }
        return 0;//成功返回
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。