CAN通讯在不同处理器下的实现方式

F103—固件库

配置

GPIO

  参照示例程序。

中断

  参照示例程序。

工作模式

  参照示例程序。

过滤器

  用于设置硬件过滤器,只有ID符合的数据才会进入邮箱。

发送

设置发送报文

void CAN_SetMsg(CanTxMsg *TxMessage)
{
    uint8_t ubCounter = 0;

    //TxMessage.StdId=0x00;
    TxMessage->ExtId = 0x1314;					 //使用扩展ID
    TxMessage->IDE = CAN_ID_EXT;				 //扩展模式
    TxMessage->RTR = CAN_RTR_DATA;				 //发送内容为数据
    TxMessage->DLC = 8;							 //数据长度8个字节

    for (ubCounter = 0; ubCounter < 8; ubCounter++)
    {
        TxMessage->Data[ubCounter] = ubCounter;  //设置发送的数据
    }
}

  此函数的主要作用是用来设置TxMessage,为库函数的发送做准备。

调用库发送函数

uint8_t CAN_Transmit(CAN_TypeDef *CANx, CanTxMsg *TxMessage)

  分析一下此处的结构体CAN_TypeDef ,发送函数会自动选择空闲的发送邮箱进行消息的填充,然后设置ID、DLC、数据区,最后进行发送,在实际的应用中,我们只需要把TxMessage设置好,传给库函数即可。

typedef struct
{
	 __IO uint32_t MCR;
	 __IO uint32_t MSR;
	 __IO uint32_t TSR;
	 __IO uint32_t RF0R;
	 __IO uint32_t RF1R;
	 __IO uint32_t IER;
	 __IO uint32_t ESR;
	 __IO uint32_t BTR;
	 uint32_t  RESERVED0[88];
	 CAN_TxMailBox_TypeDef sTxMailBox[3];
	 CAN_FIFOMailBox_TypeDef sFIFOMailBox[2];
	 uint32_t  RESERVED1[12];
	 __IO uint32_t FMR;
	 __IO uint32_t FM1R;
	 uint32_t  RESERVED2;
	 __IO uint32_t FS1R;
	 uint32_t  RESERVED3;
	 __IO uint32_t FFA1R;
	 uint32_t  RESERVED4;
	 __IO uint32_t FA1R;
	 uint32_t  RESERVED5[8];
	 CAN_FilterRegister_TypeDef sFilterRegister[14];
} CAN_TypeDef;

接收

  CAN信息的接收一般使用中断的方式

void CAN_RX_IRQHandler(void)
{
    CAN_Receive(CANx, CAN_FIFO0, &RxMessage);//从邮箱中读取报文
	//判断接收数据的ID
    if((RxMessage.ExtId == 0x1314) && (RxMessage.IDE == CAN_ID_EXT) && (RxMessage.DLC == 8) )
    {
        flag = 1; //RxMessage.Data即接收的应用数据					
    }
    else
    {
        flag = 0; 				
    }
}

F427—HAL库

  以横机机架板的CAN通讯为例,进行程序分层分析。

CAN的发送部分

在这里插入图片描述
  先分析一下自行构建的结构体

typedef struct _CAN_MSG
{
    UINT32 id;
    UINT8 len;
    UINT16 data[4];
} CAN_MSG;

  根据此结构体构造的函数

CANx_SendNormalData(CAN_HandleTypeDef* hcan, CAN_MSG *smsg)

  HAL库提供的函数需要填帧头、数据、邮箱编号,构建的函数入口参数更加简洁,自行构建的函数与超时判断的功能组合成上层的CAN发送函数。

CAN的接收部分

在这里插入图片描述
  中断中调用HAL_CAN_GetRxMessage函数,将自行定义的结构体赋值,根据数据判断进行相应的操作,有些消息经过判断后来不及操作,这些消息会通过can_queue_push放入队列中,上层的CAN接收消息函数就是使用can_queue_pop弹出消息。

RT1052的fsl库

发送函数

u8 CAN2_Send_Msg(u8* msg,u8 len)
{
	u8 ret=0;
	
	can2_txframe.format=kFLEXCAN_FrameFormatStandard;    //帧使用标准格式
	can2_txframe.type=kFLEXCAN_FrameTypeData;            //帧类型为数据帧
	can2_txframe.id=FLEXCAN_ID_STD(can2_rxid);           //标准ID
	can2_txframe.length=len;                             //数据长度
	
	//设置帧中的数据区域
	can2_txframe.dataByte0=msg[0];
	can2_txframe.dataByte1=msg[1];
	can2_txframe.dataByte2=msg[2];
	can2_txframe.dataByte3=msg[3];
	can2_txframe.dataByte4=msg[4];
	can2_txframe.dataByte5=msg[5];
	can2_txframe.dataByte6=msg[6];
	can2_txframe.dataByte7=msg[7];
	
	//调用库中的发送函数
	if(FLEXCAN_TransferSendBlocking(CAN2,TX_BUFFER_NUM,&can2_txframe)==kStatus_Success) 
	ret=0;		           
	else ret=1;
	  
	return ret;
}

接收函数

void CAN2_IRQHandler(void)
{
    if (FLEXCAN_GetMbStatusFlags(CAN2, 1 << RX_BUFFER_NUM))	  //判断邮箱缓冲区是否收到数据
    {
        FLEXCAN_ClearMbStatusFlags(CAN2, 1 << RX_BUFFER_NUM); //清除中断标志
        FLEXCAN_ReadRxMb(CAN2, RX_BUFFER_NUM, &can2_rxframe); //读取数据

        can2_rxcomplete = true;                               //设置标志位
    }
	
    __DSB();
}

  自行设计一个接收函数,将消息帧数据中的应用数据提取到自定义的buffer中。

u8 CAN2_Receive_Msg(u8 *buf)
{
    u8 datalen = 0;

    if(can2_rxcomplete == true) 
    {
        can2_rxcomplete = false;
        
        buf[0] = can2_rxframe.dataByte0;
        buf[1] = can2_rxframe.dataByte1;
        buf[2] = can2_rxframe.dataByte2;
        buf[3] = can2_rxframe.dataByte3;
        buf[4] = can2_rxframe.dataByte4;
        buf[5] = can2_rxframe.dataByte5;
        buf[6] = can2_rxframe.dataByte6;
        buf[7] = can2_rxframe.dataByte7;
        datalen = can2_rxframe.length;
    }
    else
    {
        datalen = 0;
    }

    return datalen;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡姆图拉夫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值