分享

can部分 6 stm32的can波特率配置

 冥冥1994 2023-09-08 发布于广东

can的波特率计算:

stm32的配置参数

CAN1_Mode_Init(CAN_SJW_1tq, CAN_BS2_6tq, CAN_BS1_7tq, 3, CAN_Mode_Normal);

其中

CAN_SJW_1tq是同步段,习惯上默认配置成1.  可以调节的节拍数. (范围1-4)

CAN_BS2_6tq是相位缓冲段2. (范围1-8)

CAN_BS1_7tq是传播段+相位缓冲段1. (范围1-16)

3,这里是预分频值. (范围1-1024)

函数原型:

/*******************************************************************************
* 函数名称  : CAN1_Mode_Init
* 描述      : can1的初始化,对can参数的配置.
* 输入      : 端口号,保存数据的数组指针
*             tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
*             tbs2:时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;
*             tbs1:时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq
*             brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
*             波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
*             mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
*             Fpclk1的时钟在初始化的时候设置为42M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);
*             则波特率为:42M/((6+7+1)*6)=500Kbps
* 输出		: 得到的字节数量DataCnt
* 返回      : 0,初始化成功; 其他,初始化失败
*******************************************************************************/
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
  	GPIO_InitTypeDef       GPIO_InitStructure;
	CAN_InitTypeDef        CAN_InitStructure;
  	CAN_FilterInitTypeDef  CAN_FilterInitStructure;

#if CAN1_RX0_INT_ENABLE
   	NVIC_InitTypeDef  NVIC_InitStructure;
#endif
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能PORTA时钟
  	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //使能CAN1时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;         //复用功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;       //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //100MHz  GPIO_Speed_100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;         //上拉
    GPIO_Init(GPIOD, &GPIO_InitStructure);               //初始化PA11,PA12

    GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_CAN1); //GPIOA11复用为CAN1
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_CAN1); //GPIOA12复用为CAN1

   	CAN_InitStructure.CAN_TTCM=DISABLE;	//非时间触发通信模式
  	CAN_InitStructure.CAN_ABOM=DISABLE;	//软件自动离线管理	,用于去除故障端点.
  	CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
  	CAN_InitStructure.CAN_NART=DISABLE;	//禁止报文自动传送, 这里是用来补发的.enable代表不补发
  	CAN_InitStructure.CAN_RFLM=ENABLE;	//接受的报文不锁定,溢出后新的覆盖旧的
  	CAN_InitStructure.CAN_TXFP=ENABLE;  //ENABLE;	//ENABLE优先级,优先级,先进入,先发送;不由报文标识符决定
  	CAN_InitStructure.CAN_Mode= mode;	//模式设置
  	CAN_InitStructure.CAN_SJW=tsjw;	    //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=tbs1;     //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=tbs2;     //Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=brp;//分频系数(Fdiv)为brp+1	,运行频率为APB的Fdiv分之一,即四分之一
  	CAN_Init(CAN1, &CAN_InitStructure);                           // 初始化CAN1

    CAN1->MCR|=(1<<6);                  // 通信自动恢复功能.

	//配置过滤器0
 	CAN_FilterInitStructure.CAN_FilterNumber=0;	                  //过滤器0  0~13
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //掩码模式
	//目的所有的ID数据通过
  	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
  	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;           //32位MASK  如果是1则代表掩码处要检查,如果是0,代表不检查.
  	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;               //32位ID
  	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
	//激活过滤器
   	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0,选择使用哪个fifo
  	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;              //激活过滤器0
  	CAN_FilterInit(&CAN_FilterInitStructure);                         //滤波器初始化

//    	//配置过滤器0
// 	CAN_FilterInitStructure.CAN_FilterNumber = 14;	                     //过滤器0  0~13
//	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;    //掩码模式
//		//目的所有的ID数据通过
//  	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;   //32位
//  	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;             //32位MASK  如果是1则代表掩码处要检查,如果是0,代表不检查.
//  	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
//		CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;                 //32位ID
//  	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
//		//激活过滤器
//   	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //过滤器0关联到FIFO0,选择使用哪个fifo
//  	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //激活过滤器0
//  	CAN_FilterInit(&CAN_FilterInitStructure);

#if CAN1_RX0_INT_ENABLE

	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);                        //FIFO0消息挂号中断允许.
  	NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     // 主优先级为1
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);
#endif
	return 0;
}

先按照波特率定义中的各个参数,进行计算:

计算出各个变量.

然后再选出最优的变量组合.

然后再用选好的变量,推算出stm32的寄存器赋值.

第一个参数:

Q,一个位切分成的份数.(范围 3-25 越大越好)

BRP是用于将APB的时钟分频到CAN时钟.

BRP=APB/(Q*Baudrate) ,

根据上面公式

APB,已知=42M

Baudrate,已知=1000000Kbps=1M

那么,Q和BRP就可以计算出来.

(这里会有很多组满足条件的,然后Q范围限制在3-25,且越大越好,所以选出最优的一组)

(最终定下 Q=14 )

(最终定下 BRP=3)

举例: 42M/(14*3)=1000Kbps=1M的波特率

Q的参数就是越大越好.

Q就是一个bit,一个位所被分成的节拍数.

Q是总的节拍数,要分给各个段.

Q=Tss+Tps+Tpbs1+Tpbs2=14

那么1M波特率就是1us传输1位数据.

Q等于14,就是把1us分成了14份,每份约0.07142us  (次值就是时间节拍Tq).

然后,下面计算Tss,Tps,Tpbs1,Tpbs2各占多少份

第二个参数:

Tss

按照习惯,通常占一拍.

即Tss=1

第三个参数:

Tps

其物理意义是传播段时间长度.

信号在总线上来回传输所消耗的时间.

设一次单向传输的延时为包括:

1.发送节点从生产信号到把信号发送到总线上,T1.

2.信号在总线上传输的时间T2.

3.接收节点从总线获取信号的时间T3.

因为是来回传输,所以要乘以2.

Tps>=2*(T1+T2+T3)

举例:

Tps是由设备性能和总线长度决定的.通常总线延时可按5.5ns/米计.单个节点收

发延迟可按75ns计.假如有线长12m,则Tps=2*(12*5.5+75)=141ns.根据上一步的Q值

(想要的波特率和时钟分频得到),计算出节拍时间Tq 这个已知约0.07142us=71.42ns 在上面计算过.

Tps=141/71.42=1.974约为2

即Tps=2

第四个参数,第五个参数

Tpbs1,Tpbs2

根据Q值-1-Tps(Tss一般默认为1),就得到Tpbs1和Tpbs2两数之和,

Q-Tss-Tps=Tpbs1+Tpbs2

由于上面计算

Q已知=14

Tss已知=1

Tps已知=2

那么Tpbs1和Tpbs2就能计算出来.

Tpbs1+Tpbs2=11

然后除以2,就得到了分别的值.如果是奇数则Tpbs2比Tpbs1多1个.

Tpbs2=6

Tpbs1=5

至此,上面的所有参数都得到了.

然后,开始根据上面的参数,计算stm32的参数.

根据表格:

1,stm32单片机中的第一个参数:即:CAN_SJW_1tq

CAN_SJW_1tq 就是1

2,stm32单片机中的第二个参数:即:CAN_BS2_6tq=6

Tpbs2是stm32单片机中的Ts2;

stm32_Ts2=Tpbs2=6

3,stm32单片机中的第三个参数:即:CAN_BS1_7tq=7

Tps和Tpbs1相加构成stm32单片机中的Ts1;

stm32_Ts1=Tps+Tpbs1=2+5=7

4,stm32单片机中的第四个参数:3

BRP=3

总结:

其实,CAN的波特率实际是多个参数决定的.

这样更加确定了采样点的位置.

还可以通过一些软件进行配置波特率

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多