首页 > 编程知识 正文

stm32f103can通信,stm32串口通信can

时间:2023-05-03 17:41:09 阅读:172567 作者:3100

STM32 CAN通信(一) STM32 CAN配置由于STM32 CAN控制器需要配置的参数较多,本文按照SAE J1939 协议数据单元配置STM32 CAN。

CAN的GPIO配置/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gpio配置* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * staticvoidcacadcacacacadacacacad //外围设备时钟设置RCC _ AP B2 periphclockcmd (RCC _ AP B2 per iph _ afio|RCC _ AP B2 per iph _ gpioa,ENABLE ); RCC _ AP B1 periphclockcmd (RCC _ AP B1 per iph _ can 1,ENABLE ); //rxpa 11 gpio _ init structure.gpio _ pin=gpio _ pin _ 11; gpio _ init structure.gpio _ speed=gpio _ speed _ 50m Hz; gpio _ init structure.gpio _ mode=gpio _ mode _ IPU; gpio_init(gpioa,GPIO_InitStructure ); //txpa 12 gpio _ init structure.gpio _ pin=gpio _ pin _ 12; gpio _ init structure.gpio _ speed=gpio _ speed _ 50m Hz; gpio _ init structure.gpio _ mode=gpio _ mode _ af _ PP; gpio_init(gpioa,GPIO_InitStructure ); } CAN的NVIC配置/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * can的NVIC配置1 .发送中断由3个发送邮箱中的任意一个为空组成。 2、接收中断分为FIFO0和FIFO1的中断,接收FIFO接收新的消息或消息溢出触发器。 * * * * * * * * * * * * * * * * * * * * * * * * nvic _ init structure.nvic _ IRQ channel=USB _ LP _ can 1 nvic _ init structure.nvic _ irqchannelpreemptionpriority=2; //抢占优先级2n vic _ init structure.nvic _ irqchannelsubpriority=3; //响应优先级3n vic _ init structure.nvic _ irqchannelcmd=enable; //IRQ信道使能NVIC_init(NVIC_initstructure ); can_itconfig(can1,CAN_IT_FMP0,ENABLE ); //使能CAN接收中断} CAN的模式配置/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * can的模式配置* * * * * * * * * * * * * * * * * * * * * * * * * * * can _ de init (can 1; can _ struct init (can _ init structure; can _ init structure.can _ ttcm=disable; //关闭时间触发通信模式后,can _ init structure.can _ abom=enable; //自动脱机管理CAN_InitStructure.CAN_AWUM

= ENABLE; //自动唤醒模式CAN_InitStructure.CAN_NART = DISABLE; //禁止报文自动重传 DISABLE = 自动重传CAN_InitStructure.CAN_RFLM = DISABLE; //接收 FIFO 锁定模式 DISABLE = 溢出时新报文会覆盖原有报文CAN_InitStructure.CAN_TXFP = DISABLE; //发送 FIFO 优先级 DISABLE = 优先级取决于报文标识符CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //正常工作模式CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;//重新同步跳跃宽度为2个时间单位CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; //时间段1 占用6个时间单元CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; //时间段2 占用3个时间单元CAN_InitStructure.CAN_Prescaler = 30; //波特率分频器 定义了时间单元的长度 36/(1+6+3)/30 = 0.12MbpsCAN_Init(CAN1,&CAN_InitStructure);}

CAN波特率配置
波特率 = APB1Clock/(1+CAN_BS1+CAN_BS2)/CAN_Prescaler

(PS:CAN_SJW 表示重新同步跳跃宽度,不参与波特率的计算,其值可以编程为1到4个时间单元,表示该总线对波特率范围的容差度。公式中1表示同步段固定为一个单位时间。)

尽可能地把采样点设置为 CAN 组织 CiA 推荐的值:

CiA波特率75%>800K80%>500K87.5%<=500K

CAN 波特率与传输距离
标准波特率可以参考如下对应关系:

速率(Kbps)1000500250125100502010距离(m)40130270530620130033006700

其它波特率也可以使shu用该公式:50/波特率(KBbps)10000.8 = 距离(m)

CAN 的 Filter 配置 /********************************************************************************** * 函数名:CAN_Filter_Config * 描述 :CAN 的 Filter 配置 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 * 说明 :(过滤器)配置,id 中目标地址为本机地址,接收时标识符完全相同才保存数据1: 在各种过滤器模式下,CAN ID与寄存器相应位置一定要匹配;2:在屏蔽方式下,屏蔽码寄存器某位为1表示接收到的CAN ID对应的位必须对验证码寄存器对应的位相同。**********************************************************************************/static void CAN_Filter_Config(void){CAN_FilterInitTypeDef CAN_FilterInitStructure; //过滤器组0,只接受广播信息(PF = 240 - 255)CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //过滤器位宽为单个32位CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)0xf000<<3)&0xffff0000)>>16;//要过滤的ID高位CAN_FilterInitStructure.CAN_FilterIdLow = ((u32)0xf000<<3)&0xffff; //要过滤的ID低位CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0007; //过滤器高16位 (MaskId << 3) >>16 左移3位--寄存器低3位为 保留位、RTR、IDECAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x1f00; //过滤器低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器被关联到FIFO0CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器CAN_FilterInit(&CAN_FilterInitStructure);//过滤器组1,只接受全局地址(CAN_GLOBAL_ADDRESS)CAN_FilterInitStructure.CAN_FilterNumber = 1; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //过滤器位宽为单个32位CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)CAN_Address<<11)&0xffff0000)>>16;//要过滤的ID高位CAN_FilterInitStructure.CAN_FilterIdLow = ((u32)CAN_Address<<11)&0xffff; //要过滤的ID低位CAN_AddressCAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0007; //过滤器高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x1f00; //过滤器低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器被关联到FIFO0,即通过过滤器的消息存储到FIFO0CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器CAN_FilterInit(&CAN_FilterInitStructure);} /********************************************************************************** * 函数名:Port_SetAddressFilter * 描述 :CAN 的 Filter 配置 * 输入 :Address 要过滤的地址 * 输出 :无 * 返回 :无 * 调用 :内部调用 * 说明 :随着程序的运行,将改变滤波器2,来适应程序逻辑。**********************************************************************************/void Port_SetAddressFilter(u8 Address){CAN_FilterInitTypeDef CAN_FilterInitStructure; //过滤器组2,只接受全局地址(CAN_GLOBAL_ADDRESS)CAN_FilterInitStructure.CAN_FilterNumber = 2; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //过滤器位宽为单个32位CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)Address<<11)&0xffff0000)>>16;//要过滤的ID高位CAN_FilterInitStructure.CAN_FilterIdLow = ((u32)Address<<11)&0xffff;//要过滤的ID低位CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0007; //过滤器高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x1f00; //过滤器低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器被关联到FIFO0CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器CAN_FilterInit(&CAN_FilterInitStructure);}

SAE J1939 只用扩展帧格式全面定义了标准化通信。

SAE J1939 协议数据单元结构

PDU优先权保留位数据页PDU格式PDU特定域源地址数据域域PRDPPFPSSADATA位3118880-64

定义:P 是优先级,R 是保留位,DP 是数据页,PF 是 PDU 格式,PS 是特定 PDU,SA 是源地址
PS : 目标地址(即接收机地址)
SA : 源地址(即发送机地址)

STM32 CAN ID过滤器
根据 SAE J1939 协议数据单元结构采用位宽为32位的屏蔽模式
CAN_FilterIdHighCAN_FilterIdLow 为要过滤的 ID 高位与低位。
CAN_FilterMaskIdHighCAN_FilterMaskIdLow 为屏蔽位的高位与低位。

比如,我们要配置为只接收与本机源地址一致的数据
发送机 SA = 0x01
接收机 SA = 0x02
则接收机的过滤器配置如下:

PDU优先权保留位数据页PDU格式PDU特定域源地址数据域FilterId00000000000000000001000000000DATAMaskId000000000000011111111000000000- 64

FilterId = (0x02 << 8) << 3;
FilterMaskId = (0xff << 8) << 3;
左移3位寄存器低3位为:保留位、RTR、IDE

接收到的帧 ID 与 MaskId 中为1的位所对应的 FilterId 必须完全相同才将接收到的数据存入 FIFO 中。在这里即接收到的 ID 帧的PDU特定域必须为00000010,即接收机的源地址 0x02

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。