STM32 CAN控制器简介-寄存器简介

本文详细介绍了STM32CAN控制器中的关键寄存器,如CAN_MCR、CAN_BTR、CAN_RF0R/CAN_RF1R等,阐述了初始化流程,包括设置模式、波特率、滤波器和数据传输等内容。
摘要由CSDN通过智能技术生成

1、CAN主控制寄存器(CAN_MCR)

该寄存器的我们仅介绍下INRQ位,该位用来控制初始化请求。

设置INRQ=0,可使CAN从初始化模式进入正常工作模式。

设置INRQ=1,可使CAN从正常工作模式进入初始化模式 。

CAN初始化时,先设置INRQ=1 ,进入初始化模式,进行初始化(尤其是CAN_BTR的设置,该寄存器,必须在CAN正常工作之前设置),之后再设置INRQ=0,进入正常工作模式。

2、CAN位时序寄存器(CAN_BTR)

3、CAN接收FIFO寄存器(CAN_RF0R/CAN_RF1R)

4、CAN发送邮箱标识符寄存器(CAN_TIxR)(x=0~2)

5、CAN发送邮箱数据长度和时间戳寄存器 (CAN_TDTxR) (x=0~2)

6、CAN发送邮箱数据寄存器(CAN_TDLxR/CAN_TDHxR) (x=0~2)

图为CAN_TDLxR寄存器的描述,用于存储低4个字节的数据。CAN_TDHxR寄存器与之类似,用于存储高4个字节的数据。要发送的数据就是存储在这两个寄存器

7、CAN接收FIFO邮箱标识符寄存器(CAN_RIxR)(x=0/1)

8、CAN接收FIFO邮箱数据长度和时间戳寄存器(CAN_RDTxR) (x=0/1)

9、CAN接收FIFO邮箱邮箱数据寄存器(CAN_RDLxR/CAN_RDHxR) (x=0/1)

图为CAN_RDLxR寄存器的描述,用于存储低4个字节的数据。CAN_RDHxR寄存器与之类似,用于存储高4个字节的数据。接收到的数据就存储在这两个寄存器

10、CAN筛选器模式寄存器(CAN_FM1R)

该寄存器设置筛选器的工作模式,必须在CAN_FMR寄存器FINIT=1时配置,对于STM32F103ZET6,只有[13:0]位有效,对于互联性STM32F1或者STM32F407,则全部有效。

11、CAN筛选器尺度寄存器(CAN_FS1R)

该寄存器用于设置筛选器的位宽,必须在CAN_FMR寄存器FINIT=1时配置,对于STM32F103ZET6,只有[13:0]位有效,对于互联性STM32F1或者STM32F407,则全部有效。

12、CAN筛选器FIFO关联寄存器(CAN_FFA1R)

该寄存器设置报文通过筛选器组之后,被存入的FIFO,如果对应位为0,则存放到FIFO0;如果为1,则存放到FIFO1。该寄存器也只能在过滤器处于初始化模式( CAN_FMR 寄存器的FINIT=1 )下配置。

13、CAN筛选器激活寄存器(CAN_FA1R)

该寄存器用于设置筛选器组的开启和关闭。对对应位置1,即开启对应的筛选器组;置0则关闭该筛选器组。

14、CAN筛选器组i寄存器x(CAN_FiRx)(i=0~27,x=1/2)

每个筛选器组的CAN_FiRx都由2个32位寄存器构成,即:CAN_FiR1和CAN_FiR2。根据过滤器位宽和模式的不同设置,这两个寄存器的功能也不尽相同。关于过筛选器的映射,功能描述和屏蔽寄存器的关联,在前面已经介绍过了

15、STM32 CAN控制器简介-初始化流程

①配置相关引脚的复用功能,使能CAN时钟。

        要用CAN,先要使能CAN的时钟,CAN的时钟通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用输出,这里我们需要设置PA11为上拉输入(CAN_RX引脚)PA12为复用输出(CAN_TX引脚),并使能PA口的时钟

②设置CAN工作模式及波特率等。

        通过先设置CAN_MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位。再通过CAN_BTR设置波特率和工作模式(正常模式/环回模式)等信息。 最后设置INRQ为0,退出初始化模式。

③设置滤波器。

        本例程,我们将使用筛选器组0,并工作在32位标识符屏蔽位模式下。先设置CAN_FMR的FINIT位,进入初始化模式,然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后激活筛选器,并退出初始化模式。

 
  1. //CAN初始化

  2. //tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq

  3. //tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq;

  4. //tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq

  5. //brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1

  6. //波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);

  7. //mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;

  8. //Fpclk1的时钟在初始化的时候设置为42M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);

  9. //则波特率为:42M/((6+7+1)*6)=500Kbps

  10. //返回值:0,初始化OK;

  11. // 其他,初始化失败;

  12. u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)

  13. {

  14. GPIO_InitTypeDef GPIO_InitStructure;

  15. CAN_InitTypeDef CAN_InitStructure;

  16. CAN_FilterInitTypeDef CAN_FilterInitStructure;

  17. #if CAN1_RX0_INT_ENABLE //中断使用 默认不使用

  18. NVIC_InitTypeDef NVIC_InitStructure;

  19. #endif

  20. //使能相关时钟

  21. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟

  22. RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟

  23. //初始化GPIO

  24. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;

  25. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

  26. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

  27. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz

  28. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

  29. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12

  30. //引脚复用映射配置

  31. GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1

  32. GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1

  33. //CAN单元设置

  34. CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式

  35. CAN_InitStructure.CAN_ABOM=DISABLE; //软件自动离线管理

  36. CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)

  37. CAN_InitStructure.CAN_NART=ENABLE; //禁止报文自动传送

  38. CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定,新的覆盖旧的

  39. CAN_InitStructure.CAN_TXFP=DISABLE; //优先级由报文标识符决定

  40. CAN_InitStructure.CAN_Mode= mode; //模式设置

  41. //设置波特率

  42. CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq

  43. CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq

  44. CAN_InitStructure.CAN_BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq

  45. CAN_InitStructure.CAN_Prescaler=brp; //分频系数(Fdiv)为brp+1

  46. CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1

  47. //配置过滤器

  48. CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器0

  49. CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //屏蔽位模式

  50. CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位宽

  51. CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID

  52. CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;

  53. CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK

  54. CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;

  55. CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0

  56. CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0

  57. CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化

  58. #if CAN1_RX0_INT_ENABLE

  59. CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.

  60. NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;

  61. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1

  62. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0

  63. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  64. NVIC_Init(&NVIC_InitStructure);

  65. #endif

  66. return 0;

  67. }

 
  1. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)

  2. //len:数据长度(最大为8)

  3. //msg:数据指针,最大为8个字节.

  4. //返回值:0,成功;

  5. // 其他,失败;

  6. u8 Can_Send_Msg(u8* msg,u8 len)

  7. {

  8. u8 mbox;

  9. u16 i=0;

  10. CanTxMsg TxMessage;

  11. TxMessage.StdId=0x12; // 标准标识符

  12. TxMessage.ExtId=0x12; // 设置扩展标示符

  13. TxMessage.IDE=CAN_Id_Standard; // 标准帧

  14. TxMessage.RTR=CAN_RTR_Data; // 数据帧

  15. TxMessage.DLC=len; // 要发送的数据长度

  16. for(i=0;i<len;i++)TxMessage.Data[i]=msg[i];

  17. mbox= CAN_Transmit(CAN1, &TxMessage);

  18. i=0;

  19. while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;//等待发送结束

  20. if(i>=0XFFF)return 1;

  21. return 0;

  22. }

 
  1. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)

  2. //len:数据长度(最大为8)

  3. //msg:数据指针,最大为8个字节.

  4. //返回值:0,成功;

  5. // 其他,失败;

  6. u8 Can_Send_Msg(u8* msg,u8 len)

  7. {

  8. u8 mbox;

  9. u16 i=0;

  10. CanTxMsg TxMessage;

  11. TxMessage.StdId=0x12; // 标准标识符

  12. TxMessage.ExtId=0x12; // 设置扩展标示符

  13. TxMessage.IDE=CAN_Id_Standard; // 标准帧

  14. TxMessage.RTR=CAN_RTR_Data; // 数据帧

  15. TxMessage.DLC=len; // 要发送的数据长度

  16. for(i=0;i<len;i++)TxMessage.Data[i]=msg[i];

  17. mbox= CAN_Transmit(CAN1, &TxMessage);

  18. i=0;

  19. while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;//等待发送结束

  20. if(i>=0XFFF)return 1;

  21. return 0;

  22. }

 
  1. //can口接收数据查询

  2. //buf:数据缓存区;

  3. //返回值:0,无数据被收到;

  4. // 其他,接收的数据长度;

  5. u8 Can_Receive_Msg(u8 *buf)

  6. {

  7. u32 i;

  8. CanRxMsg RxMessage;

  9. if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //没有接收到数据,直接退出

  10. CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //读取数据

  11. for(i=0;i<8;i++)buf[i]=RxMessage.Data[i];

  12. return RxMessage.DLC;

  13. }

STM32 CAN控制器简介-寄存器简介_can1_mode_init-CSDN博客

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值