can.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "can.h"
  2. #include "global.h"
  3. #include <string.h>
  4. #define MASK_ID 0x18CE00EF
  5. CanRxMsg RxMessageImportant;
  6. CanRxMsg RxMessageNormal;
  7. CanData_TypeDef CanDataImportant; // 重要数据
  8. extern SqQueue CanQueueImportant;
  9. // extern _declare_box8(can1_mpool, BlockSizeCan1, BlockCountCan1);
  10. // extern os_mbx_declare (can1_mailbox, sizeof(can1_mpool)/sizeof(CanRxMsg));//声明消息邮箱 读取can1数据
  11. // CAN初始化
  12. // tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
  13. // tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq;
  14. // tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq
  15. // brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
  16. // 波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
  17. // mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
  18. // Fpclk1的时钟在初始化的时候设置为42M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);
  19. // 则波特率为:42M/((6+7+1)*6)=500Kbps
  20. u32 result;
  21. u8 CAN2_Mode_Init(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode)
  22. {
  23. GPIO_InitTypeDef GPIO_InitStructure;
  24. CAN_InitTypeDef CAN_InitStructure;
  25. CAN_FilterInitTypeDef CAN_FilterInitStructure;
  26. NVIC_InitTypeDef NVIC_InitStructure;
  27. u32 mask_id = MASK_ID;
  28. // 使能相关时钟
  29. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能PORTA时钟
  30. RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // 使能CAN1时钟
  31. // 初始化GPIO
  32. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
  33. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能
  34. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
  35. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
  36. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
  37. GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PA11,PA12
  38. // 引脚复用映射配置
  39. GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1); // GPIOB11复用为CAN1
  40. GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1); // GPIOB12复用为CAN1
  41. // CAN单元设置
  42. CAN_InitStructure.CAN_TTCM = DISABLE; // 非时间触发通信模式
  43. CAN_InitStructure.CAN_ABOM = DISABLE; // 软件自动离线管理
  44. CAN_InitStructure.CAN_AWUM = DISABLE; // 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
  45. CAN_InitStructure.CAN_NART = DISABLE; // 禁止报文自动传送
  46. CAN_InitStructure.CAN_RFLM = DISABLE; // 报文不锁定,新的覆盖旧的
  47. CAN_InitStructure.CAN_TXFP = DISABLE; // 优先级由报文标识符决定
  48. CAN_InitStructure.CAN_Mode = mode; // 模式设置
  49. CAN_InitStructure.CAN_SJW = tsjw; // 重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  50. CAN_InitStructure.CAN_BS1 = tbs1; // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  51. CAN_InitStructure.CAN_BS2 = tbs2; // Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
  52. CAN_InitStructure.CAN_Prescaler = brp; // 分频系数(Fdiv)为brp+1
  53. CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
  54. // 配置过滤器0
  55. CAN_FilterInitStructure.CAN_FilterNumber = 0; // 过滤器0
  56. CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  57. CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 32位
  58. CAN_FilterInitStructure.CAN_FilterIdHigh = (u16)((mask_id << 3) >> 16); // 0xFFFF;
  59. CAN_FilterInitStructure.CAN_FilterIdLow = (u16)((mask_id << 3) | (1 << 2)); // 0xFFFF;
  60. CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFF0; // 0x0000;//32位MASK
  61. // CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfff8; // 最后3位不管
  62. CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x07FF; // 0; // 最后3位不管
  63. CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; // 过滤器0关联到FIFO0
  64. CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; // 激活过滤器0
  65. CAN_FilterInit(&CAN_FilterInitStructure); // 滤波器初始化
  66. CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); // FIFO0消息挂号中断允许.
  67. NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  68. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; // 主优先级为
  69. // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0
  70. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  71. NVIC_Init(&NVIC_InitStructure);
  72. ////////////////////////////////////////////////
  73. return 0;
  74. }
  75. /**********************************************************************************************************
  76. * 函 数 名: CAN1_Init
  77. * 功能说明: CAN1初始化
  78. * 形 参: 无
  79. * 返 回 值: 无
  80. **********************************************************************************************************/
  81. void can_init(void)
  82. {
  83. #if defined(__CAN_BAUD_500K)
  84. CAN2_Mode_Init(CAN_SJW_1tq, CAN_BS2_6tq, CAN_BS1_7tq, 6, CAN_Mode_Normal); // CAN1初始化环回模式,波特率500Kbps
  85. #elif defined(__CAN_BAUD_250K)
  86. CAN2_Mode_Init(CAN_SJW_1tq, CAN_BS2_6tq, CAN_BS1_7tq, 12, CAN_Mode_Normal); // CAN1初始化环回模式,波特率250Kbps
  87. #else
  88. // #error no can baud macro!;
  89. #endif
  90. }
  91. //(固定格式:ID为0X12,标准帧,数据帧)
  92. // len:数据长度(最大为8)
  93. // msg:数据指针,最大为8个字节.
  94. // 返回值:0,成功;
  95. // 其他,失败;
  96. /****************************************************
  97. * 函数功能:can1发送一组数据
  98. * 入口参数:msg 数据 len 数据长度 can_id CAN id
  99. * 说 明:group_id 从1开始
  100. *****************************************************/
  101. u8 can_send_msg(u8 *msg, u8 len, u32 can_id)
  102. {
  103. u16 mbox, i;
  104. CanTxMsg TxMessage;
  105. TxMessage.StdId = 0x00; // 标准标识符为0
  106. TxMessage.ExtId = can_id; // 设置扩展标示符(29位)
  107. TxMessage.IDE = CAN_Id_Extended; // 使用扩展标识符
  108. TxMessage.RTR = CAN_RTR_Data; // 消息类型为数据帧
  109. TxMessage.DLC = len; // 发送两帧信息
  110. for (i = 0; i < len; i++)
  111. TxMessage.Data[i] = msg[i]; // 第一帧信息
  112. mbox = CAN_Transmit(CAN1, &TxMessage);
  113. i = 0;
  114. while ((CAN_TransmitStatus(CAN1, mbox) == CAN_TxStatus_Failed) && (i < 0XFFF))
  115. i++; // 等待发送结束
  116. if (i >= 0XFFF)
  117. return 1;
  118. return 0;
  119. }
  120. // CAN1中断服务函数
  121. void CAN1_RX0_IRQHandler(void)
  122. {
  123. // 1.6us ucos时间戳、示波器测量都是1.6us
  124. CAN_Receive(CAN1, CAN_FIFO0, &RxMessageImportant);
  125. memcpy(CanDataImportant.buf, RxMessageImportant.Data, RxMessageImportant.DLC);
  126. CanDataImportant.can_id = RxMessageImportant.ExtId;
  127. if (InsertQueue(&CanQueueImportant, CanDataImportant) == ERROR) // 队列插入数据
  128. {
  129. }
  130. }