stm32的CAN通讯的一些笔记

CAN的帧类型:
数据帧:节点向外传送数据
遥控帧(远程帧):向远端节点请求数据
错误帧:向远端节点通知校验错误,请求重发上一个数据
过载帧:通知远端节点:本节点尚未做好接收准备
帧间隔:将数据帧、遥控帧与勤勉的帧分隔

每个CAN数据位的时间:Tbit=1Tq+Ts1+Ts2=1+(TS1[3:0]+1)+(TS2[2:0]+1)=N*Tq

位时序寄存器 CAN_BTR 的 TS1[3:0] 及TS2[2:0] 寄存器位设定 BS1 及 BS2 段的长度。

单个时间片的长度 Tq 与 CAN 外设的所挂载的时钟总线及分频器配置有关,CAN1 和 CAN2外设都是挂载在 APB1 总线上的,而位时序寄存器 CAN_BTR 中的 BRP[9:0] 寄存器位可以设置CAN 外设时钟的分频值
Tq = (BRP[9:0]+1) x Tpclk pclk为APB1时钟,默认值36MHz

CAN波特率BaudRate=1/NTq

一种配置波特率为1Mbps的方式:

SYNC_SE段固定为1Tq
BS1段设置为5Tq(实际写入的 TS1[3:0]为3
BS2段设置为3Tq(实际写入TS2[2:0]的值为2)
TpclkAPB1按默认配置为36MHz,Tpclk=1/36M
CAN外设时钟分频设置为4分频(实际写入BRP[9:0]为3)
1Tq时间长度Tq=(BRP[9:0]+1)Tpclk=41/36M=1/9M
1位的时间长度T1bit=1Tq+Ts1+Ts2=1+5+3=9Tq
波特率BaudRate=1/NTq=1/(1/9M*9)=1M`

简单来说:波特率=CAN时钟/((1+CAN_BS1+CAN_BS2)*CAN_Prescaler);

采样点计算:(BS1+1)/(1+BS1+BS2)

采样点位置在85%左右最佳。
75% 波特率>800K
80% >500K
87.5% <=500K

CAN 初始化结构体
typedef struct {  
	uint16_t CAN_Prescaler; // 配置 CAN 外设的时钟分频,可设置为 1-1024
	uint8_t CAN_Mode; // 配置 CAN 的工作模式,回环或正常模式 
	uint8_t CAN_SJW; // 配置 SJW 极限值 重新同步跳跃宽度
	uint8_t CAN_BS1; // 配置 BS1 段长度 
	uint8_t CAN_BS2; // 配置 BS2 段长度 
	FunctionalState CAN_TTCM; // 是否使能 TTCM 时间触发功能 
	FunctionalState CAN_ABOM; // 是否使能 ABOM 自动离线管理功能 (Bus off)
	FunctionalState CAN_AWUM; // 是否使能 AWUM 自动唤醒功能 (0时由软件唤醒)
	FunctionalState CAN_NART; // 是否使能 NART 自动重传功能 
	FunctionalState CAN_RFLM; // 是否使能 RFLM 锁定 FIFO 功能 (0时FIFO未被锁定)
	FunctionalState CAN_TXFP; // 配置 TXFP 报文优先级的判定方法 (发送FIFIO优先级)
} CAN_InitTypeDef;

 CAN 筛选器结构体

5 typedef struct {
6 uint16_t CAN_FilterIdHigh; /*CAN_FxR1 寄存器的高 16 位 */
7 uint16_t CAN_FilterIdLow; /*CAN_FxR1 寄存器的低 16 位 */
8 uint16_t CAN_FilterMaskIdHigh; /*CAN_FxR2 寄存器的高 16 位 */
9 uint16_t CAN_FilterMaskIdLow; /*CAN_FxR2 寄存器的低 16 位 */
10 uint16_t CAN_FilterFIFOAssignment; /* 设置经过筛选后数据存储到哪个接收 FIFO
11
12 uint8_t CAN_FilterNumber; /* 筛选器编号,范围 0-27*/
13 uint8_t CAN_FilterMode; /* 筛选器模式 */
14 uint8_t CAN_FilterScale; /* 设置筛选器的尺度 */
15 FunctionalState CAN_FilterActivation; /* 是否使能本筛选器 */
16 } CAN_FilterInitTypeDef;

CAN 发送结构体
typedef struct { 
	uint32_t StdId; /* 存储报文的标准标识符 11 位,0-0x7FF. */
	uint32_t ExtId; /* 存储报文的扩展标识符 29 位,0-0x1FFFFFFF. */
	uint8_t IDE; /* 存储 IDE 扩展标志 (标准帧扩展帧)*/
	uint8_t RTR; /* 存储 RTR 远程帧标志 (数据帧远程帧)*/
	uint8_t DLC; /* 存储报文数据段的长度,0-8 */
	uint8_t Data[8]; /* 存储报文数据段的内容 */
} CanTxMsg;

配置完成后可以先使用回环模式(CAN_Mode_LoopBack)进行测试。

筛选器可以配置成

 	 CAN_FilterInitStructure.CAN_FilterNumber = 0;
     CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
     CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
        
     CAN_FilterInitStructure.CAN_FilterIdHigh = 0x00;
     CAN_FilterInitStructure.CAN_FilterIdLow = 0x00;
     CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
     CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;

进行测试,定位通讯问题。

 	 CAN_FilterInitStructure.CAN_FilterNumber = 0;
     CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
     CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
        
     CAN_FilterInitStructure.CAN_FilterIdHigh = ((((u32)CAN_ID<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff0000)>>16;
     CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)CAN_ID<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
     CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
     CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;

CAN通讯时检测到发送完成的状态再往下走会比较好,不然连续发送时有可能会发生数据丢包等情况。

u8 mailbox,status;
void CAN1_Transmit(u16 data)
{  
   u16 i=0;
    TxMessage.StdId = CANTargetID;//
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.DLC = 4;
    TxMessage.Data[0] = data&0xff;
    TxMessage.Data[1] = (data>>8)&0xff;
    TxMessage.Data[2] = RxMessage.Data[2];//
    TxMessage.Data[3] = RxMessage.Data[3];//

    
    mailbox = CAN_Transmit(CAN1,&TxMessage);
    status=CAN_TransmitStatus(CAN1,mailbox);
  // status=0;
    while(i<0xffff)
    {
        
        if(status==0x01)
        {
            
            break;
        }
        i++;
    }
    
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值