详解CAN通信的步骤与流程

CAN通讯的实现步骤:

1.CAN初始化,其中包括:a.配置CAN时钟,配置IO;

                                          b.使能CAN中断向量;

                                          c.CAN硬件寄存器配置初始化;

                                          d.过滤器初始化;

                                          e.打开CAN中断。

2.CAN发送函数

3.CAN接收函数

4.中断函数

  依据上面的CAN通讯的实现步骤,开始编写代码,注意,我使用的是库函数。

一.CAN初始化

  1 void CAN_Init(void)
  2 
  3 {
  4 
  5   GPIO_InitTypeDef GPIO_InitStructure;
  6 
  7   NVIC_InitTypeDef NVIC_InitStructure;
  8 
  9   CAN_InitTypeDef CAN_InitStructure;
 10 
 11   CAN_FilterInitTypeDef CAN_FilterInitStructure;
 12 
 13   //a.1.配置CAN时钟和对应的IO时钟
 14 
 15   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);  //使能CAN1的时钟,注意:CAN1是挂载在APB1上,不要用错函数!
 16 
 17   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);  //使能GPIO
 18 
 19   //a.2.初始化CAN1_Tx(PA12)和CAN1_Rx(PA11)的IO
 20 
 21   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  //PA12 —>CAN1_Tx
 22 
 23   GIOP_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 24 
 25   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 26 
 27   GPIO_Init(GPIOA,&GPIO_InitStructure);  //初始化PA12
 28 
 29  
 30 
 31   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  //PA11 -> CAN1_RX
 32 
 33   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉输入,注意:Rx必须使用上拉输入模式
 34 
 35   GPIO_Init(GPIOA,&GPIO_InitStructure);  //初始化PA11
 36 
 37   //b.使能中断向量
 38 
 39   NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;  //我这使用的是CAN1的接收中断,实际上,CAN1还有发送中断:USB_HP_CAN1_TX_IRQn。注意,CAN1中断是和USB是共用的,所以如果你打开了CAN1中断,就不能再用USB中断了。
 40 
 41   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   //抢占优先级 = 0
 42 
 43   NVIC_InitStructure.NVIC_IRQChannelPreemPreemptionPriority = 3;  //子优先级 = 3
 44 
 45   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 46 
 47   NVIC_Init(&NVIC_InitStructure);
 48 
 49   //c.CAN硬件寄存器配置初始化
 50 
 51   CAN_DeInit(CAN1);
 52 
 53   CAN_InitStructure.CAN_TTCM = DISABLE;//失能时间触发通讯模式
 54 
 55   CAN_InitStructure.CAN_ABOM = DISABLE;//失能自动离线管理模式
 56 
 57   CAN_InitStructure.CAN_AWUM = DISABLE;//失能自动唤醒模式
 58 
 59   CAN_InitStructure.CAN_NART = DISABLE;//失能非自动重传输模式
 60 
 61   CAN_InitStructure.CAN_RFLM = DISABLE;//失能接收FIFO锁定模式
 62 
 63   CAN_InitStructure.CAN_TXFP = DISABLE;//失能发送FIFO优先级
 64 
 65   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//CAN硬件工作在正常模式;
 66 
 67   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位;
 68 
 69   CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;//时间段1为9个时间单位;
 70 
 71   CAN_InitStructure.CAN_BS2  = CAN_BS2_8tq;//时间段2为8个时间单位;
 72 
 73   CAN_InitStructure.CAN_Prescaler = 3;//1个时间单位的长度为3
 74 
 75   CAN_Init(CAN1&CAN_InitStructure);
 76 
 77   //d.过滤器初始化
 78 
 79   CAN_FIlterInitStructure.CAN_FilterNumber = 0;//制订带初始化的过滤器为0
 80 
 81   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//标识符列表模式,该模式下屏蔽寄存器也被当作标识符寄存器使用,接收报文标识符的每一位都必须跟过滤器标识符相同
 82 
 83   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//32位过滤器
 84 
 85   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;//过滤器标识符高段位:0x0000;
 86 
 87   CAN_FilterInitStructure.CAN_FIlterIdLow = 0x0000;//过滤器标识符低段位:0x0000;
 88 
 89   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//过滤器标识符高段位
 90 
 91   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//过滤器屏蔽标识符低段位
 92 
 93   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//使能过滤器
 94 
 95   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIlterFIFO0;//指向过滤器的FIFO0;
 96 
 97   CAN_FilterInit(&CAN_FilterInitStructe);
 98 
 99   //e.打开CAN中断
100 
101   CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE)//FIFO0消息挂号中断屏蔽
102 
103 }

二.CAN发送函数

 1   void can_SendData(CanTxMsg* TxMessage)
 2 
 3 {
 4 
 5   unsigned char i = 0;
 6 
 7   unsigned char TransmitMailbox;
 8 
 9   TransmitMailbox = CAN_Transmit(CAN1,TxMessage);//发送数据,返回邮箱号
10 
11   while((CAN_TransmitStatus(CAN1,TransmitMailbox) != CANTXOK)&&(i != 0xff))
12 
13    {//查看是否发送完成
14 
15       i++;
16 
17    }
18 
19   i = 0;
20 
21   while((CAN_MessagePendding(CAN1,CAN_FIFO0)<1)&&(i != 0xff))
22 
23   {//查看被挂起的报文是否为0
24 
25     i++;
26 
27   }
28 
29 }

三.接收数据

     今天不想写。。。。迟点补上蛤~~~~

四.中断函数

 1 CanRxMsg RxMessage;
 2 
 3   void USB_LP_CAN1_RX0_IRQHandler(void)
 4 
 5 {
 6 
 7   CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);//接收数据,存储到RxMessage中
 8 
 9   。。。。。//自行脑补
10 
11 }
12 
13  

因为我这篇文章是自己一个一个字敲进去的,可能会出现单词拼写错误~~~~~

欢迎指错蛤~~~~~~

物联沃分享整理
物联沃-IOTWORD物联网 » 详解CAN通信的步骤与流程

发表评论