历史上的今天
返回首页

历史上的今天

今天是:2025年08月17日(星期日)

2021年08月17日 | 基于stm32的can总线彻底研究

2021-08-17 来源:eefocus

1、CAN总线的初始化

void can_init(void)
{
     CAN_InitTypeDef        CAN_InitStructure;
     CAN_FilterInitTypeDef  CAN_FilterInitStructure;

     /* CAN register init */
     CAN_DeInit();
     CAN_StructInit(&CAN_InitStructure);

     /* CAN cell init */
     CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
     CAN_InitStructure.CAN_ABOM=DISABLE;
     CAN_InitStructure.CAN_AWUM=DISABLE;
     CAN_InitStructure.CAN_NART=DISABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)
     CAN_InitStructure.CAN_RFLM=DISABLE;
     CAN_InitStructure.CAN_TXFP=DISABLE;
     CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
     //CAN_Mode_LoopBack
     //CAN_Mode_Normal
     CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
     CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
     CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
     CAN_InitStructure.CAN_Prescaler=2;
     CAN_Init(&CAN_InitStructure);
#ifdef can_id_filter
      /* CAN filter init */
     CAN_FilterInitStructure.CAN_FilterNumber=0;//选择过滤器0
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器被设置为标识符屏蔽模式
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//给出过滤器位宽为32位
     CAN_FilterInitStructure.CAN_FilterIdHigh=slave_id<<5;//过滤器标识符
     CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
     CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;//过滤器屏蔽标识符
     CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc;
     CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;//选择FIFO0
     CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
     CAN_FilterInit(&CAN_FilterInitStructure);//进入初始化函数
#else
     /* CAN filter init */
     CAN_FilterInitStructure.CAN_FilterNumber=0;//选择过滤器0
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器被设置为标识符屏蔽模式
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//给出过滤器位宽为32位
     CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//过滤器标识符
     CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
     CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符
     CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
     CAN_ITConfig(CAN_IT_FMP0, ENABLE);//使能指定的can中断
}


void CAN_DeInit(void)
{
 /* Enable CAN reset state */
 RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, ENABLE);
 /* Release CAN from reset state */
 RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, DISABLE);
}


2、发送程序

unsigned char CAN_PushMessage(CAN_MSG  *pTransmitBuf )
{
 u8 TransmitMailbox=0;
 CanTxMsg TxMessage;
 if(pTransmitBuf -> LEN > 8)
 {
      return  1;
 }
 /* transmit */
 TxMessage.StdId=pTransmitBuf ->StdId;//用来设定标准标识符(0-0x7ff,11位)
 TxMessage.ExtId=pTransmitBuf ->ExtId;
 TxMessage.RTR=  pTransmitBuf ->RTR;//设置RTR位为数据帧
 TxMessage.IDE=  pTransmitBuf ->IDE;//标识符扩展位,为标准帧
 TxMessage.DLC=  pTransmitBuf ->LEN;//设置数据长度
 //根据DLC字段的值,将有效数据拷贝到发送数据寄存器
 memcpy(TxMessage.Data, pTransmitBuf ->BUF,pTransmitBuf ->LEN);
 TransmitMailbox = CAN_Transmit(&TxMessage);
// TxMessage.Data[1]=(data & 0xff00)>>8;
 return 1;
}


3、中断接收程序

void USB_LP_CAN_RX0_IRQHandler(void)
{
 //清空can接收缓存
 CanRxMsg RxMessage;
 RxMessage.StdId=0x00;
 RxMessage.ExtId=0x00;
 RxMessage.IDE=0;
 RxMessage.DLC=0;
 RxMessage.FMI=0;//CAN过滤主控制寄存器
 memset( &RxMessage.Data[0],0,8);
 //can总线接收数据函数
 CAN_Receive(CAN_FIFO0, &RxMessage);
 //将接收到的数据写于modbus的寄存器1
 //modbus_regester[1]=(RxMessage.Data[0]<<8)|(RxMessage.Data[1]);
// if((RxMessage.StdId==slave_id) && (RxMessage.ExtId==0x00) && (RxMessage.IDE==CAN_ID_STD))
 {
   //将can接收标志位置1,表示从卡应经接收到一个can报文
   flag_can_recv=0;
   memcpy(can_rx_data,&RxMessage.Data,RxMessage.DLC);
     flag_can_recv=1;
 }

}


4、can总线的id过滤

对扩展数据帧过滤:

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<<3)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;

对标准数据帧过滤:

CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)CAN_ID0<<21)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh   = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow    = 0xFFFF;

假如要对标准远程帧进行过滤,那么:

只需要将

CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF; 改成:

CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xFFFF;


5、can总线的帧格式

数据帧格式:

远程帧格式:


6、can总线的逻辑电平

can总线的物理连接有两根线:CANH和CANL,以差分的形式输出。

(有的时候有地线,作为屏蔽线使用)

can总线的高电平 3.5v,表示逻辑0

can总线的低电平 1.5v,表示逻辑1


7、CAN总线的波特率计算


can时钟是RCC_APB1PeriphClock,要注意CAN时钟频率
CAN波特率 = RCC_APB1PeriphClock/CAN_SJW CAN_BS1 CAN_BS2/CAN_Prescaler;
如果CAN时钟为8M, CAN_SJW = 1,CAN_BS1 = 8,CAN_BS2 = 7,CAN_Prescaler = 2
那么波特率就是=8M/(1 8 7)/2=250K


8、can总线的仲裁机制


根据仲裁来判断优先级:

(1)若在同一时刻,标准格式的报文与扩展格式的报文同时抢占总线,且它们的基础ID相同,则发标准格式的报文节点就会PK成功。这是因为扩展格式在基本ID后,紧接着是SRR位,与IDE位,且这两位都是隐性位。而在标准格式中,这两位分别对应的位为RTR与r1,其中RTR既可以为隐性位,也可以为显性位,,但是r1必须为显性位。由仲裁规则可以此时标准帧必定胜出。

(2)同理,如果在同一时刻,具有相同格式,且具有相同ID的数据帧与远程帧争夺总线控制权,那么数据帧必定胜出。因为RTR显性表示数据帧,隐性表示远程帧。

推荐阅读

史海拾趣

博流(Bouffalo Lab)公司的发展小趣事

博流公司的卓越表现引起了业界的广泛关注。2019年,公司荣获了Red Herring Top 100 Asia大奖,这是对其在AIoT/边缘计算SOC芯片研发领域的快速成长和技术实力的高度认可。此外,博流还获得了多项国内外专利和荣誉,证明了公司在行业内的领先地位。

Bombardier Inc公司的发展小趣事

随着全球航空市场的不断变化,庞巴迪公司在商用航空领域也取得了显著成就。其生产的CRJ系列区域喷气客机和Q系列涡桨飞机在全球范围内广受欢迎。这些飞机配备了先进的电子设备和系统,提供了更高的安全性和舒适性。庞巴迪还推出了C系列单通道中距客机,该机型以其环保、经济和人性化的设计赢得了市场的广泛认可。

FERYSTER公司的发展小趣事

随着市场的不断扩大,FERYSTER公司意识到产品质量对于企业的重要性。因此,公司投入大量资金用于提升质量管理体系,引入国际先进的生产设备和检测仪器。同时,公司还加强了员工的质量意识培训,确保每一个环节都符合质量标准。这些措施的实施,使得FERYSTER公司的产品质量得到了显著提升,赢得了客户的广泛赞誉。

Firadec公司的发展小趣事

背景:随着全球环保意识的增强,绿色电子产品成为了市场的新宠。Firadec公司积极响应环保号召,致力于开发绿色电子产品。

发展:公司投入大量资源研发环保材料和生产工艺,成功推出了一系列符合环保标准的电子产品。同时,Firadec还建立了完善的回收体系,对废旧电子产品进行回收再利用。

影响:环保和可持续发展的理念不仅提升了Firadec公司的品牌形象,也为其赢得了更多消费者的青睐。公司因此在绿色电子产品市场中占据了领先地位。

Fujitsu America公司的发展小趣事

在计算机技术发展的早期阶段,Fujitsu就展现出了强大的研发实力。1954年,Fujitsu成功研制出日本第一台电脑FACOM 100,这一里程碑式的成就不仅标志着Fujitsu在计算机领域的正式起步,也为其后续在ICT领域的发展奠定了坚实基础。Fujitsu America作为Fujitsu在全球的重要分支机构,积极将这一创新成果引入北美市场,推动了当地计算机技术的普及和应用。

Cal Crystal Lab Inc / Comclok Inc公司的发展小趣事

随着全球化的加速推进,国际化战略成为了企业发展的重要方向。Cal Crystal Lab Inc在稳固国内市场的基础上,积极实施国际化战略。公司不仅在海外设立了研发中心和生产基地,还加大了对国际市场的开拓力度。通过与当地企业的合作与交流,Cal Crystal Lab Inc不断适应国际市场的需求和变化,提升了公司在全球市场的竞争力。

这五个故事只是虚构的示例,并不代表任何真实公司的历史。实际的电子行业公司发展历程往往更加复杂和多样,受到市场、技术、政策等多种因素的影响。如果您需要了解特定公司的真实发展故事,建议查阅相关资料或咨询相关人士。

问答坊 | AI 解惑

Keil软件仿真的串口调试技巧

在单片机系统中,串口(UART,通用异步收发接口)是一个非常重要的组成部分。通常使用单片机串口通过RS232/RS485电平转换芯片与上位机连接,以进行上位机与下位机的数据交换、参数设置、组成网络以及各种外部设备的连接等。RS232/RS485串行接口总线 ...…

查看全部问答>

C语言面试题大汇总

C语言面试题大汇总.doc…

查看全部问答>

移动硬盘 读取问题

250G的移动日立硬盘,读取磁盘时发现少一个分区。 本来我分了3个区。。 现在只有2个。。。 大家帮忙看下 ,,谢谢···…

查看全部问答>

skype3.0 移植到 wince

ExecutabilityCheck查看了,相应的库都有了,可就是没法运行,说不是有效的wince程序。…

查看全部问答>

请问WINCE6.0下使用什么开源的播放器比较好

之前使用的是TCPMP,但是TCPMP在6.0下有一个很致命的问题,我用的是SIRF A4的CPU,有75%的概率会出现CRASH的问题;..这个问题又解决不了,所以现在 急着想要寻找 一个播放器,不知道哪位前辈推荐下,或者指点下解决TCPMP CRASH的问题,谢谢!…

查看全部问答>

关于机顶盒开发 help

我现在做WEB  ,但找了份做机顶盒的,工资比目前少比较多,想请教各位:   就前景和目前工资对比,我该如何选择,我不喜欢做WEB,没去这家公司不久应该也会转其他应用软件方面的公司   大家多多帮忙  谢 ...…

查看全部问答>

关于oracle查询的优化

在oracle中有一个EMP表,显示字段为F1,F2字段.但此表中有10万条记录.查寻第11到第21之间的所有记录.写出查寻语句,并考虑怎么优化查寻?…

查看全部问答>

有关开关电容滤波器

如何用分离元件实现开关电容滤波器? 关键是那个开关如何弄为好?…

查看全部问答>

用过TRF6900 的大虾请进。

TRF6900里的learn 和hold 模式,怎么用啊,有什么区别,我看了英文的PDF,这一段一点都看不懂。…

查看全部问答>

单片机定时、捕获、比较之间的区别

那位大侠能给总结一下他们之间的区别,以及他们都是用在什么场合。   在此祝愿朋友们教师节快乐、同时预祝中秋快乐。…

查看全部问答>