当前位置:首页 > 单片机 > 单片机
[导读] 首先简单介绍一下CAN总线,关于CAN总线是谁发明的,CAN总线的历史,CAN总线的发展,CAN总线的应用场合,这些,通通不说。这里只是以我个人理解,简单说说CAN通信。CAN总线的端点没有地址(除非自己在帧

首先简单介绍一下CAN总线,关于CAN总线是谁发明的,CAN总线的历史,CAN总线的发展,CAN总线的应用场合,这些,通通不说。这里只是以我个人理解,简单说说CAN通信。CAN总线的端点没有地址(除非自己在帧里定义地址),CAN总线通信不用地址,用标识符,不是单独的谁发给谁,而是,你总是发送给整个网络。然后每个节点都有过滤器,对网络上的传播的帧的标识符进行过滤,自己想要什么样的帧,可以设置自己的过滤器,接收相关的帧信息。如果两个节点同时发送怎么办?这个不用我们担心,CAN控制器会自己仲裁,让高优先级的帧先发。

然后我们可以了解一下stm32的CAN控制器。


如上图所示,stm32有两个can控制器,can1(主),和can2(从),其中过滤器的设置是通过can1来设置,其他工作模式,波特率等,可以各自设置。每个控制器有三个发送邮箱,两个fifo,每个fifo有三个接收邮箱。


发送:选择一个空的发送邮箱,把帧信息写到该发送邮箱的寄存器里,请求发送,控制器就会根据标识符的优先级把帧先后发送出去。


接收:如果接收到的帧的标识符能过过滤表的一系列过滤,该帧信息就会保存在fifo接收邮箱的寄存器里。

fifo1,每组都包括两个32位存储器,可以配置成一个32位有位屏蔽功能的标识符过滤器,或者两个32位完全匹配的标识符过滤器,或者两个16位有位屏蔽功能的标识符过滤器,或者四个16位完全匹配的标识符过滤器。如下图所示:



我所说的完全匹配的意思是,接收到的帧的标识符每一位都要跟过滤器对应的位一样,才能过得了这个过滤器。有位屏蔽功能的意思是一个寄存器放标识符,一个放屏蔽掩码,屏蔽掩码为1的位对应的接收到的帧的标识符的位与对应的放标识符的寄存器的位一致,就能通过。


传输一位的时间和波特率的计算:

CAN控制器的波特率是由APB时钟线和CAN位时序寄存器CAN_BTR的TS2[3:0]、TS1[2:0]和BRP[9:0]确定的,其中,TS1[2:0]定义了时间段1占用多少个时间单元,TS2[3:0]定义了时间段2占用多少个时间单元,BRP[9:0]定义对APB1时钟的分频。

PS:设置波特率为1M


其中Tpclk为APB1的时钟周期,假设为

Tpclk = 1/42M

0≦TS1≦7

0≦TS2≦15

0≦BRP≦1021

根据以上数据,有

(TS2+TS1+3)(BRP+1)=42

令BRP=2,有

TS2+TS1=11

令TS1=8,TS2=3


设置步骤:

1.设置中断优先级分组(如果之前没有设置),这个最好一个程序里只在开头设置一次。

2.使能相关GPIO时钟。

3.选择相关GPIO引脚的复用功能。

4.设置相关GPIO引脚为复用模式。

5.设置相关GPIO引脚的速度,方式。

6.设置主控制寄存器MCR,进入初始化模式

7.等待进入初始化模式

8.设置波特率。

9.其他设置。

10.如果要用到中断,在中断使能寄存器IER中使能相关中断响应。

11.如果要用到中断,设置相关中断优先级(NVIC_IP)。

12.如果要用到中断,使能相关中断(NVIC_ISER)。

13.设置主控制寄存器MCR,进入正常工作模式。

14.设置FMR,使过滤器组工作在初始化模式。

15.设置FMR的CAN2SB,确定CAN2的过滤器组从哪一组开始。

16.设置用到的过滤器组的工作方式。

17.设置用到的过滤器组的位宽。

18.给fifo0和fifo2划分(关联)过滤组。

19.禁用用到的过滤器组。

20.设置过滤器组的标识符,帧类型等。

21.使能相关过滤器组。

22.设置FMR,使过滤器组工作在正常模式。

23.如果要用中断,编写中断服务函数(函数名是固定的)。

24.中断服务函数里检查是哪个中断。

25.编写相应服务程序。


程序:

/************************************

标题:操作CAN的练习

软件平台:IAR for ARM6.21

硬件平台:stm32f4-discovery

主频:168M

描述:通过硬件收发器连接CAN1,CAN2

组成一个两个端点的网络

CAN1循环发出数据帧

CAN2接收过滤数据帧

用uart把CAN2接收到

的数据帧发到超级终端

author:小船

data:2012-08-14

*************************************/

#include

#include "MyDebugger.h"

#define RECEIVE_BUFFER_SIZE 20

u32 CAN2_receive_buffer[RECEIVE_BUFFER_SIZE][4];

u8 UART_send_buffer[1800];

u8 Consumer = 0;

u8 Producer = 0;

u32 Gb_TimingDelay;

void Delay(uint32_t nTime);

void TIM7_init();//定时1s

u32 get_rece_data();

void CAN_GPIO_config();

void main ()

{

u32 empty_box;

SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断

SCB->AIRCR = 0x05FA0000 " 0x400; //中断优先级分组 抢占:响应=3:1

MyDebugger_Init();

TIM7_init();

MyDebugger_Message( "nrtesting......nr" ,

sizeof("nrtesting......nr")/sizeof(char) );

CAN_GPIO_config();

RCC->APB1ENR |= ((1<<25)|(1<<26));//使能CAN1、CAN2时钟

CAN1->MCR = 0x00000000;

/*

请求进入初始化模式

禁止报文自动重传

自动唤醒模式

*/

CAN1->MCR |= ((1<<0)|(1<<4)|(1<<5));

CAN1->MCR &= ~(1<<16);//在调试时,CAN照常工作

while(!(CAN1->MSR & 0xfffffffe)) //等待进入初始化模式

{

MyDebugger_LEDs(orange, on);

}

MyDebugger_LEDs(orange, off);

/*

正常模式

重新同步跳跃宽度(1+1)tq

TS2[2:0]=3

TS1[3:0]=8

BRP[9:0]=2

ps:

tq = (BRP[9:0] + 1) x tPCLK,

tBS2 = tq x (TS2[2:0] + 1),

tBS1 = tq x (TS1[3:0] + 1),

NominalBitTime = 1 × tq+tBS1+tBS2,

BaudRate = 1 / NominalBitTime

波特率设为1M

*/

CAN1->BTR = ((0<<30)|(0x01<<24)|(3<<20)|(8<<16)|(2<<0));

CAN1->MCR &= ~(0x00000001);//正常工作模式

CAN2->MCR = 0x00000000;

/*

请求进入初始化模式

禁止报文自动重传

自动唤醒模式

*/

CAN2->MCR |= ((1<<0)|(1<<4)|(1<<5));

CAN2->MCR &= ~(1<<16);//在调试时,CAN照常工作

while(!(CAN2->MSR & 0xfffffffe)) //等待进入初始化模式

{

MyDebugger_LEDs(orange, on);

}

MyDebugger_LEDs(orange, off);

/*

正常模式

重新同步跳跃宽度(1+1)tq

TS2[2:0]=3

TS1[3:0]=8

BRP[9:0]=2

ps:

tq = (BRP[9:0] + 1) x tPCLK,

tBS2 = tq x (TS2[2:0] + 1),

tBS1 = tq x (TS1[3:0] + 1),

NominalBitTime = 1 × tq+tBS1+tBS2,

BaudRate = 1 / NominalBitTime

波特率设为1M

*/

CAN2->BTR = ((0<<30)|(0x01<<24)|(3<<20)|(8<<16)|(2<<0));

CAN2->IER &= 0x00000000;

/*

FIFO1消息挂号中断使能

FIFO1满中断使能

FIFO1溢出中断使能

*/

CAN2->IER |= ((1<<4)|(1<<5)|(1<<6));

NVIC->IP[65] = 0xa0; //抢占优先级101,响应优先级0

NVIC->ISER[2] |= (1<<1); //使能中断线65,也就是can2_rx1中断

CAN2->MCR &= ~(0x00000001);//正常工作模式

//总共有28组过滤器

CAN1->FMR |= 1; //过滤器组工作在初始化模式

CAN1->FMR &= 0xffffc0ff;//CAN2的过滤器组从14开始

CAN1->FMR |= (14<<8);

CAN1->FM1R |= (1<<14);//过滤器组14的寄存器工作在标识符列表模式

//位宽为16位,2个32位

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭