STM32F042和STM32F103的CAN通讯异常

2019-07-21 01:13发布

最近在做CAN的多节点实验,但是在使用STM32103和STM32F042做CAN通讯的时候无法通讯,两个STM32F103或者两个STM32F042可用正常通讯,现在用F103和F042就不能正常通讯了,初始化代码如下STM32F042初始化、中断及发送函数
[mw_shl_code=c,true]/**********************************************************
* 函数功能:CAN初始化配置
* 入口参数:CAN_ID        自身ID标识号
* 返回参数:无
*     A_Z
*                20190410
*        TX->PA12        RX->PA11
* 波特率  ->200kHz
* 采样点  ->87.50%
***********************************************************/
void CAN_Config(u16 CAN_ID)
{
    GPIO_InitTypeDef                          GPIO_InitStructure;
    NVIC_InitTypeDef                          NVIC_InitStructure;
    CAN_InitTypeDef                        CAN_InitStructure;
    CAN_FilterInitTypeDef                  CAN_FilterInitStructure;
       
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//重映射PA11、PA12之前必须打开SYSCFG时钟线
        SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;//没有库函数,只能直接寄存器映射(TSSOP20封装的STM32F042F4P6必须映射)

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//CAN_Tx
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽型
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//高速模式
    GPIO_Init(GPIOA,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//CAN_Rx
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
        GPIO_Init(GPIOA,&GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;//中断通道
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;//中断优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
    NVIC_Init(&NVIC_InitStructure);

    CAN_DeInit(CAN);
    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_InitStructure.CAN_SJW  = CAN_SJW_2tq;//指定CAN硬件为执行重新同步跳跃宽度(容错率,不参与波特率计算)(0-3)

    CAN_InitStructure.CAN_BS1  = CAN_BS1_6tq;//指定位段1中的时间量子数(0-15)
    CAN_InitStructure.CAN_BS2  = CAN_BS2_1tq;//指定位段2中的时间量子数(0-7)
    CAN_InitStructure.CAN_Prescaler = 23;//时间量长度(1-1024)
    CAN_Init(CAN,&CAN_InitStructure);//初始化CAN


    CAN_FilterInitStructure.CAN_FilterNumber = 0;//指定要初始化的FIFO
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//模式为标识符掩码模式(另一种为标识符列表模式)
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//FIFO为32位过滤器
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;//过滤器标识号高16位
    CAN_FilterInitStructure.CAN_FilterIdLow = ((u16)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA;//过滤器标志号低16位
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//过滤掩码号高16位
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0FFE;//过滤掩码号低16位
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;//将参数分配给指定FIFO
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//使能FIFO
    CAN_FilterInit(&CAN_FilterInitStructure);
    //FIFO消息挂起中断
    CAN_ITConfig(CAN,CAN_IT_FMP0,ENABLE);
       
#ifdef FIFO1
    //初始化过滤器FIFO1
    CAN_FilterInitStructure.CAN_FilterNumber = 1;//指定要初始化的FIFO
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;//模式为标识符列表模式(另一种为标识符掩码模式)
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//FIFO比例为单32位
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x2460;//过滤器标识号高16位
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;//过滤器标识号低16位
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//过滤掩码号高16位
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//过滤掩码号低16位
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 1;//将参数分配给指定FIFO
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//使能FIFO
    CAN_FilterInit(&CAN_FilterInitStructure);
    //FIFO消息挂起中断
    CAN_ITConfig(CAN,CAN_IT_FMP1,ENABLE);
#endif
}

/**********************************************************
* 函数功能:CAN发送数据函数
* 入口参数:u16 ID                ->目标ID
*           u8  *msg        ->数据指针,最大为8字节
*                        u8  len         ->数据长度,最大为8
* 返回参数:0                成功
*                        其他        失败
* 作    者:A_Z
* 时    间:20190410
***********************************************************/
u8 CAN_Send(u16 ID,u8 *msg,u8 len)
{
    u8 mbox;
    u16 i;
    CanTxMsg TxMessage;

    WDT();//喂狗
    TxMessage.StdId = 0;//标准标识符
    TxMessage.ExtId = ID;//扩展标识符
    TxMessage.IDE = CAN_ID_EXT;//扩展帧
    TxMessage.RTR = CAN_RTR_DATA;//数据帧
    TxMessage.DLC = len;//数据长度
    for(i=0; i<len; i++) //写入数据
        TxMessage.Data = msg;
    mbox = CAN_Transmit(CAN,&TxMessage);//发送数据
    while((CAN_TransmitStatus(CAN,mbox) != CAN_TxStatus_Ok)&&(i < 0xfff))i++;//等待发送完成
    if(i >= 0xfff)return 1;
    return 0;
}

/**********************************************************
* 函数功能:CAN中断接收函数
* 入口参数:无
* 返回参数:无
*     A_Z
*                20190410
**********************************************************/
void CEC_CAN_IRQHandler(void)
{
    u8 i;
    CanRxMsg RxMessage0;
#ifdef FIFO1
    CanRxMsg RxMessage1;
#endif
    if(CAN_MessagePending(CAN, CAN_FIFO0) != 0) { //FIFO0有待处理消息
        CAN_Receive(CAN,0,&RxMessage0);
        for(i=0; i<RxMessage0.DLC; i++)
            Can_Data0 = RxMessage0.Data;
    }
#ifdef FIFO1
    if(CAN_MessagePending(CAN, CAN_FIFO1) != 0) { //FIFO1有待处理消息
        CAN_Receive(CAN,1,&RxMessage1);
        for(i=0; i<8; i++)
            Can_Data1 = RxMessage1.Data;
    }
#endif
}[/mw_shl_code]

STM32F103初始化、发送及中断函数

[mw_shl_code=c,true]/*
* 函数名:CAN_GPIO_Config
* 描述  :CAN的所有配置和初始化
* 输入  :当前设备标识符ID
* 输出  : 无
    波特率:200KHz      采样点:87.5%
*/
void CAN_Config(u16 CAN_ID)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    CAN_InitTypeDef        CAN_InitStructure;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
   
    /*外设时钟设置*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    /*IO设置*/

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

    /* Configure CAN pin: TX PA12 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                         // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
     /*中断设置*/
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;           //CAN1 RX0中断
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                           //子优先级为1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
   
    /************************CAN通信参数设置**********************************/
    /*CAN寄存器初始化*/
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);
    /*CAN单元初始化*/
    CAN_InitStructure.CAN_TTCM=DISABLE;                           //MCR-TTCM  关闭时间触发通信模式使能
    CAN_InitStructure.CAN_ABOM=DISABLE;                           //MCR-ABOM  不自动离线管理
    CAN_InitStructure.CAN_AWUM=DISABLE;                           //MCR-AWUM  不使用自动唤醒模式
    CAN_InitStructure.CAN_NART=DISABLE;                           //MCR-NART  禁止报文自动重传          DISABLE-自动重传
    CAN_InitStructure.CAN_RFLM=DISABLE;                           //MCR-RFLM  接收FIFO 锁定模式  DISABLE-溢出时新报文会覆盖原有报文
    CAN_InitStructure.CAN_TXFP=DISABLE;                           //MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  //正常工作模式
    CAN_InitStructure.CAN_SJW=CAN_SJW_2tq;                   //BTR-SJW 重新同步跳跃宽度 2个时间单元
    CAN_InitStructure.CAN_BS1=CAN_BS1_6tq;                   //BTR-TS1 时间段1 占用了6个时间单元
    CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;                   //BTR-TS1 时间段2 占用了1个时间单元
    CAN_InitStructure.CAN_Prescaler =3;                  
    CAN_Init(CAN1, &CAN_InitStructure);

   
    /*CAN过滤器初始化*/
    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;                                //要过滤的ID高位
    CAN_FilterInitStructure.CAN_FilterIdLow= ((u16)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA; //要过滤的ID低位
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000;                        //过滤器高16位每位必须匹配
    CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0FFE;                //过滤器低16位每位必须匹配
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0 ;                                //过滤器被关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                        //使能过滤器
    CAN_FilterInit(&CAN_FilterInitStructure);

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

}

/**********************************************************
* 函数功能:CAN发送数据函数
* 入口参数:u16 ID                ->目标ID
*           u8  *msg        ->数据指针,最大为8字节
* 返回参数:0                成功
*                        其他        失败
* 作    者:A_Z
* 时    间:20190425
***********************************************************/
u8 CAN_Send(u16 ID,u8 *str)
{
    CanTxMsg TxMessage;                             //发送缓冲区
    u16 i,mbox;

    TxMessage.StdId = 0;
    TxMessage.ExtId = ID;                                         //使用的扩展ID
    TxMessage.IDE=CAN_ID_EXT;                                         //扩展模式
    TxMessage.RTR=CAN_RTR_DATA;                                 //发送的是数据
    TxMessage.DLC=8;                                                         //数据长度为5字节
    for(i=0;i<8;i++)
        TxMessage.Data= str;
   
    mbox = CAN_Transmit(CAN1,&TxMessage);//发送数据
    while((CAN_TransmitStatus(CAN1,mbox) != CANTXOK) && (i<0xfff))i++;//等待发送完成
    if(i>0xfff)return 1;
    return 0;
   
}
/**********************************************************
* 函数功能:CAN中断服务函数
* 入口参数:无
* 返回参数:无
* 作    者:A_Z
* 时    间:20190426
**********************************************************/

void USB_LP_CAN1_RX0_IRQHandler(void)
{
    u8 i;
    CanRxMsg RxMessage;       
   
    if(CAN_MessagePending(CAN1,CAN_FIFO0) != 0){//又待处理消息
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//接收消息
        for(i=0;i<RxMessage.DLC;i++)
            CAN_Data = RxMessage.Data;
    }
   
}
[/mw_shl_code]
现在F103向F042定时发送CAN数据,现在调试F0,在寄存器内显示的是(位填充错误和格式错误),在F1调试又显示的是(隐性位错误),请问遇到过的朋友怎么解决这个问题啊
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
way7539512
1楼-- · 2019-07-21 06:35
 精彩回答 2  元偷偷看……
fengc234
2楼-- · 2019-07-21 11:19
楼主,您的CAN通信怎么样了,我现在也在用STM32F042F6P6的CAN功能,用的是TI的SN65HVD230D收发芯片,STM32F042CAN引脚有波形输出,但是从SN65HVD230D输出引脚出来的波形已经严重失真了,不知道怎么回事

一周热门 更多>