电子商务网站建设 精品课程,中国小型加工厂网,dw做的网站怎么传到网络上去,网站域名查询什么是CAN总线协议
是一种异步半双工的通讯协议#xff0c;只有CAN_High与CAN_Low两条信号线。 有两种连接形式#xff1a;闭环总线#xff08;高速#xff09;和开环总线#xff08;远距离#xff09;
他使用的是一种差分信号来传输电信号 所谓差分信号就是两条信号线…什么是CAN总线协议
是一种异步半双工的通讯协议只有CAN_High与CAN_Low两条信号线。 有两种连接形式闭环总线高速和开环总线远距离
他使用的是一种差分信号来传输电信号 所谓差分信号就是两条信号线电平之差来传输电信号1/0,
该方式优点是抗干扰能力强、可以远距离传输因为当信号线过长的时候电阻累积过大使得传输到的电信号不准确而差分信号是使用两条信号线电平差两条信号线只要长度相似信号误差都不会很大。
电位差为0时为逻辑1电位差2.0时为逻辑0。
CAN协议的协议层原理
协议层内规定了一个数据位有四个段分别为SS段、PTS段、PBS1段、PBS2段 1Tq为1个时基单元 SS段是同步段若通讯节点检测到总线上信号的跳变沿被包含在 SS 段的范围之内则表示节点与总线的时序是同步的当节点与总线同步时采样点采集到的总线电平即可被确定为该位的电平。SS 段的大小固定为 1Tq。
PTS段是传播时间段这个时间段是用于补偿网络的物理延时时间。是总线上输入比较器延时和输出驱动器延时总和的两倍。PTS 段的大小可以为 1~8Tq。
PBS1段PBS1 译为相位缓冲段补偿SS段的误差它的时间长度在重新同步的时候可以加长如下图相位超前既ss段比预计的时间超期一个时间基准可以通过PBS1段校准。
PBS2段这是另一个相位缓冲段它的时间长度在重新同步时可以缩短补偿整个数据对齐。
CAN报文
当节点1与节点2同时发送报文时总线电平会有优先级按照ID优先级选择其1 当节点1或节点2发现自身电平和总线电平不同时会停止发送报文总线显性电平为0有1和0时总线电平取0
帧种类及用途 数据帧的结构 仲裁段0为最高优先级用于总线判断优先级 控制段
RTR位为0表示数据帧发送数据的为1表示遥控帧请求数据的IDE位为0表示标准格式为1表示为扩展格式DLE表示本报文的数据有多少个字节4个数据位不过只能写入0~8SRR 位 只存在于扩展格式它用于替代标准格式中的 RTR位。由于扩展帧中的 SRR 位为隐性位RTR 在数据帧为显性位所以在两个 ID 相同的标准格式报文与扩展格式报文中标准格式的优先级较高。
CRC 段为了保证报文的正确传输CAN 的报文包含了一段 15 位的 CRC 校验码一旦接收节点算出的CRC 码跟接收到的 CRC 码不同则它会向发送节点反馈出错信息利用错误帧请求它重新发送。CRC 部分的计算一般由 CAN 控制器硬件完成出错时的处理则由软件控制最大重发数。在 CRC 校验码之后有一个 CRC 界定符它为隐性位主要作用是把 CRC 校验码与后面的 ACK段间隔起来。
ACK 段ACK 段包括一个 ACK 槽位和 ACK 界定符位。类似 I2C 总线在 ACK 槽位中发送节点发送的是隐性位而接收节点则在这一位中发送显性位以示应答。在 ACK 槽和帧结束之间由 ACK 界定符间隔开。
STM32的CAN外设
stm32f103c8芯片中带有CAN的控制器但不带CAN的收发器所以如果想用最小系统板进行CAN外设实验需要自己连接CAN的收发器。 CAN内部框图剖析
有一下五个主要部分
CAN控制内核CAN发送邮箱CAN接收fifo验收筛选器整体控制逻辑
stm32的CAN外设寄存器
主要使用的功能
DBF调试冻结功能可设置CAN处于工作状态或者禁止收发状态静止收发时仍可访问接收FIFO的数据TTCM生成时间戳在CAN_RDTxR和CAN_TDTxR中保存ABOM自动离线管理在节点检测到它发送错误或者接收错误超过一定值时会自动进入离线状态。AWUM自动唤醒如果软件进入CAN外设的低功耗模式如果使能了该功能当CAN总线检测到活动时自动换醒。NART自动重传报文发送失败会自动重传至成功为止RFLM锁定模式使能该模式的话只有6个接收FIFO如果6个满了还未处理则第7个来时不接入FIFO否则会覆盖第一个FIFOTXFP报文发送优先级判断方法ID优先级/时序优先级
寄存器
工作模式寄存器CAN_BTR
寄存器的31位30位分别控制两个模式 31位是否静默 30位是否回环 23-20位TS2表示TSS2占用多少个时间单元TSS2Tq*(TS21) 19-15位TS1与上同理 25-24位SJW,定义每次可活动增减TS1与TS2数据位的最大值调整时序时最大增减的时间单元个数 9-0位BRP波特率分频器TqBRP1*tPCLK
其他寄存器
标识符寄存器CAN_ITxR存储发送报文的ID、扩展IDIDE位和RTR位其中的TMIDxR_TxRQ位置1即可以发送数据数据长度控制寄存器CAN_TDTxR存储待发送报文的DLC段低位数据寄存器CAN_TDLxR存储发送报文的Date0~Date3高位数据寄存器CAN_TDHxR存储发送报文的Date4~Date7
CAN的接收邮箱
每个CAN有两个接收FIFO邮箱每个邮箱有3级 两个FIFO接收邮箱公用28个筛选器组f103是14个、f105是28个
掩码模式
一个筛选器有两个寄存器在上图的掩码映射中写入1就代表ID寄存器中的这一位需要筛选如果全写入0即不筛选。
stm32的CAN代码移植使用
在hal_can.h文件中
#define GPIO_CAN_RX_Pin GPIO_Pin_8
#define GPIO_CAN_TX_Pin GPIO_Pin_9初始化CAN的GPIO重定义引脚
/****************************************************************************
**名称 hal_CAN_GPIO_Config
**功能 CAN的引脚口(PB8R/9T)
**形参 无
**返回值 无
****************************************************************************/
static void hal_CAN_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct_CAN_TX;GPIO_InitTypeDef GPIO_InitStruct_CAN_RX;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);GPIO_InitStruct_CAN_TX.GPIO_Pin GPIO_CAN_TX_Pin ;GPIO_InitStruct_CAN_TX.GPIO_Mode GPIO_Mode_AF_PP;GPIO_InitStruct_CAN_TX.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB,GPIO_InitStruct_CAN_TX);GPIO_InitStruct_CAN_RX.GPIO_Pin GPIO_CAN_RX_Pin ;GPIO_InitStruct_CAN_RX.GPIO_Mode GPIO_Mode_IPU;GPIO_InitStruct_CAN_RX.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB,GPIO_InitStruct_CAN_RX);
}初始化CAN的模式
这里需要提一下因为核心板没有CAN的接收器如果要验证功能要使用回环模式
/****************************************************************************
**名称 hal_CAN_Mode_Config
**功能 定义CAN模块的模式
**形参 无
**返回值 无
****************************************************************************/
static void hal_CAN_Mode_Config(void)
{CAN_InitTypeDef GAN_InitStruct_Mode;RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);/*CAN寄存器初始化*/CAN_DeInit(CAN1);CAN_StructInit(GAN_InitStruct_Mode);GAN_InitStruct_Mode.CAN_Mode CAN_Mode_Normal; //普通工作模式,CAN_Mode_LoopBack为回环模式GAN_InitStruct_Mode.CAN_SJW CAN_SJW_1tq; //可活动时间单元1tqGAN_InitStruct_Mode.CAN_BS1 CAN_BS1_5tq;GAN_InitStruct_Mode.CAN_BS2 CAN_BS2_3tq;/*CAN单元初始化*/GAN_InitStruct_Mode.CAN_TTCMDISABLE; //MCR-TTCM 关闭时间触发通信模式使能GAN_InitStruct_Mode.CAN_ABOMENABLE; //MCR-ABOM 自动离线管理 GAN_InitStruct_Mode.CAN_AWUMENABLE; //MCR-AWUM 使用自动唤醒模式GAN_InitStruct_Mode.CAN_NARTDISABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传GAN_InitStruct_Mode.CAN_RFLMDISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文 GAN_InitStruct_Mode.CAN_TXFPDISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符 /* CAN Baudrate 1 MBps (1MBps已为stm32的CAN最高速率) (CAN 时钟频率为 APB1 36 MHz) */GAN_InitStruct_Mode.CAN_Prescaler 4; BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(153)/41 MbpsCAN_Init(CAN1,GAN_InitStruct_Mode)
}初始化筛选器
/****************************************************************************
**名称 hal_CAN_Filter_Config
**功能 初始化CAN模块的过滤器
**形参 无
**返回值 无
****************************************************************************/
static void hal_CAN_Filter_Config(void)
{CAN_FilterInitTypeDef GAN_InitStruct_Filter0;CAN_FilterInitTypeDef GAN_InitStruct_Filter1;GAN_InitStruct_Filter0.CAN_FilterActivation ENABLE; //使能筛选器GAN_InitStruct_Filter0.CAN_FilterFIFOAssignment CAN_Filter_FIFO0 ; //筛选器被关联到FIFO0GAN_InitStruct_Filter0.CAN_FilterIdHigh (((CAN_TargetID3)|CAN_Id_Extended|CAN_RTR_Data))16;GAN_InitStruct_Filter0.CAN_FilterIdLow ((CAN_TargetID3)|CAN_Id_Extended|CAN_RTR_Data);GAN_InitStruct_Filter0.CAN_FilterMaskIdHigh 0xFFFF; //筛选器高16位每位必须匹配GAN_InitStruct_Filter0.CAN_FilterMaskIdLow 0xFF00; //筛选器低16位每位必须匹配GAN_InitStruct_Filter0.CAN_FilterMode CAN_FilterMode_IdMask; //工作在掩码模式GAN_InitStruct_Filter0.CAN_FilterNumber 0;GAN_InitStruct_Filter0.CAN_FilterScale CAN_FilterScale_32bit; //筛选器位宽为单个32位。CAN_FilterInit(GAN_InitStruct_Filter0);/*CAN通信中断使能*/GAN_InitStruct_Filter1.CAN_FilterActivation ENABLE; //使能筛选器GAN_InitStruct_Filter1.CAN_FilterFIFOAssignment CAN_Filter_FIFO1 ; //筛选器被关联到FIFO1GAN_InitStruct_Filter1.CAN_FilterIdHigh ((CAN_FIFO1_ID3)|CAN_Id_Extended|CAN_RTR_Data)16;GAN_InitStruct_Filter1.CAN_FilterIdLow ((CAN_FIFO1_ID3)|CAN_Id_Extended|CAN_RTR_Data);GAN_InitStruct_Filter1.CAN_FilterMaskIdHigh 0xFFFF; //筛选器高16位每位必须匹配GAN_InitStruct_Filter1.CAN_FilterMaskIdLow 0xFF00; //筛选器低16位每位必须匹配GAN_InitStruct_Filter1.CAN_FilterMode CAN_FilterMode_IdMask; //工作在掩码模式GAN_InitStruct_Filter1.CAN_FilterNumber 2;GAN_InitStruct_Filter1.CAN_FilterScale CAN_FilterScale_32bit; //筛选器位宽为单个32位。CAN_FilterInit(GAN_InitStruct_Filter1);/*CAN通信中断使能*/CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE);CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}这里我打开了两个接收FIFO 打开两个接收FIFO时需要注意 该筛选器关联到的FIFOGAN_InitStruct_Filter1.CAN_FilterFIFOAssignment 筛选器编号GAN_InitStruct_Filter1.CAN_FilterNumber 这里不要配置好了一个另一个就直接复制结构体导致错误了。
筛选器掩码配置要注意因为低3位是配置RTR的标志位高29位才是掩码ID配置所以一开始将掩码ID左移3位然后在或上IDE 位标志“宏 CAN_ID_EXT”以及RTR 位标 志“宏 CAN_RTR_DATA”然后再赋值入筛选器的高八位和低八位
GAN_InitStruct_Filter0.CAN_FilterIdHigh (((CAN_TargetID3)|CAN_Id_Extended|CAN_RTR_Data))16; GAN_InitStruct_Filter0.CAN_FilterIdLow ((CAN_TargetID3)|CAN_Id_Extended|CAN_RTR_Data); GAN_InitStruct_Filter0.CAN_FilterMaskIdHigh 0xFFFF; //筛选器高16位每位必须匹配 GAN_InitStruct_Filter0.CAN_FilterMaskIdLow 0xFF00; //筛选器低16位每位必须匹配
初始化CAN的外设中断NVIC
/****************************************************************************
**名称 hal_CAN_NVIC_Config
**功能 初始化CAN模块的中断
**形参 无
**返回值 无
****************************************************************************/
static void hal_CAN_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* Configure one bit for preemption priority */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/*中断设置*/NVIC_InitStructure.NVIC_IRQChannel USB_LP_CAN1_RX0_IRQn; //CAN1 RX0中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0; //抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority 0; //子优先级为0NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/*中断设置*/NVIC_InitStructure.NVIC_IRQChannel CAN1_RX1_IRQn; //CAN1 RX0中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0; //抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; //子优先级为1NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_Init(NVIC_InitStructure);
}这里要注意想要打开两个FIFO的中断是有区别的 FIFO0的中断通道名称是USB_LP_CAN1_RX0_IRQn FIFO1的中断通道名称是CAN1_RX1_IRQn
FIFO0的中断函数名称是void USB_LP_CAN1_RX0_IRQHandler(void) FIFO1的中断函数名称是void CAN1_RX1_IRQHandler(void)
CAN发送函数
/****************************************************************************
**名称 CAN_SetMsg
**功能 配置CAN的发送信箱进行发送
**形参 CanTxMsg型的结构体地址,发送的拓展ID发送的数据存放地址
**返回值 无
****************************************************************************/
void CAN_SetMsg(CanTxMsg *TxMessage,uint32_t EXT_ID ,uint8_t* Data)
{ uint8_t ubCounter 0;//TxMessage.StdId0x00; TxMessage-ExtIdEXT_ID; //使用的扩展IDTxMessage-IDECAN_ID_EXT; //扩展模式TxMessage-RTRCAN_RTR_DATA; //发送的是数据TxMessage-DLC8; //数据长度为8字节/*设置要发送的数据0-7*/for (ubCounter 0; ubCounter 8; ubCounter){TxMessage-Data[ubCounter] Data[ubCounter];}CAN_Transmit(CAN1, TxMessage);//将TMIDxR_TxRQ标志位置1发送CAN发送邮箱的报文发送出去
}接收中断函数编写
/****************************************************************************
**名称 USB_LP_CAN1_RX0_IRQHandler
**功能 CAN模块的FIFO0接收中断函数
**形参 无
**返回值 无
****************************************************************************/
void USB_LP_CAN1_RX0_IRQHandler(void)
{/*从邮箱中读出报文*/CAN_Receive(CAN1, CAN_FIFO0, RxMessage);/* 比较ID是否为0x1111 */ if((RxMessage.ExtId 0x1110) (RxMessage.IDECAN_ID_EXT) (RxMessage.DLC8) ){CAN_flag 1; //接收成功 }else{CAN_flag 0; //接收失败}
}
总结
在以上函数中我打开了两个接收FIFO希望能一次性接收6个CAN的报文但在实际实验中连续发送6个报文只能接收3个成功。 查了好久的原因还是没有解决该问题如果有大佬知道为什么希望能帮我解惑。