can.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /***************************************************************
  2. * file name : can.c
  3. * Description : 1.CAN初始化配置
  4. 2.发送数据初始化
  5. 3.中断入口及接收数据判断
  6. * Author : zc
  7. * Version : 0.1
  8. * Date : 2014.9.26
  9. * History :
  10. ***************************************************************/
  11. #include <string.h>
  12. #include "includes.h"
  13. //#include "can.h"
  14. #define CAN_RX0_INT_ENABLE 1
  15. u8 can_buf[8] = {0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
  16. u8 rec_buf[8] = {0};
  17. /**
  18. *@function CAN初始化
  19. *@param
  20. * tsjw: 重新同步跳跃时间单元,范围:CAN_SJW_1tq~ CAN_SJW_4tq
  21. * tbs2: 时间段2的时间单元,范围:CAN_BS2_1tq~CAN_BS2_8tq;
  22. * tbs1: 时间段1的时间单元,范围:CAN_BS1_1tq ~CAN_BS1_16tq
  23. * brp : 波特率分频器,范围:1~1024; tq=(brp)*tpclk1
  24. * 波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
  25. * mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
  26. * Fpclk1的时钟在初始化时设置为36M,如果设置CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
  27. * 则波特率:36M/((8+9+1)*4)=500Kbps
  28. *@return 0,初始化成功;
  29. * 其他,初始化失败;
  30. */
  31. u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
  32. {
  33. GPIO_InitTypeDef GPIO_InitStructure;
  34. CAN_InitTypeDef CAN_InitStructure;
  35. CAN_FilterInitTypeDef CAN_FilterInitStructure;
  36. #if CAN_RX0_INT_ENABLE
  37. NVIC_InitTypeDef NVIC_InitStructure;
  38. #endif
  39. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/* 使能PORTA时钟 */
  40. RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);/* 使能CAN1时钟 */
  41. /* CAN IO口设置 */
  42. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  43. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  44. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 复用推挽 */
  45. GPIO_Init(GPIOA, &GPIO_InitStructure); /* PA12----CAN_TX */
  46. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  47. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* 上拉输入 */
  48. GPIO_Init(GPIOA, &GPIO_InitStructure); /* PA11----CAN_RX */
  49. /* CAN单元设置 */
  50. CAN_InitStructure.CAN_TTCM=DISABLE;
  51. CAN_InitStructure.CAN_ABOM=DISABLE;
  52. CAN_InitStructure.CAN_AWUM=DISABLE;
  53. CAN_InitStructure.CAN_NART=ENABLE;
  54. CAN_InitStructure.CAN_RFLM=DISABLE;
  55. CAN_InitStructure.CAN_TXFP=DISABLE;
  56. CAN_InitStructure.CAN_Mode= mode;
  57. /* 波特率设置 */
  58. CAN_InitStructure.CAN_SJW=tsjw;
  59. CAN_InitStructure.CAN_BS1=tbs1;
  60. CAN_InitStructure.CAN_BS2=tbs2;
  61. CAN_InitStructure.CAN_Prescaler=brp;
  62. CAN_Init(CAN1, &CAN_InitStructure); /* 初始化CAN1 */
  63. CAN_FilterInitStructure.CAN_FilterNumber=0; /* 过滤器0 */
  64. CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; /* 屏蔽位宽模式 */
  65. CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; /* 32位宽 */
  66. CAN_FilterInitStructure.CAN_FilterIdHigh=0x0020; /* 主机的32位ID*/
  67. CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  68. CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0020; /* 32位MASK */
  69. CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  70. CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; /* 过滤器关联到FIFO0 */
  71. CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; /* 激活过滤器 */
  72. CAN_FilterInit(&CAN_FilterInitStructure); /* 过滤器初始化 */
  73. #if CAN_RX0_INT_ENABLE /* 如果使能RX0中断 */
  74. CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); /* FIFO消息挂号中断允许 */
  75. NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  76. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 主优先级为1 */
  77. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* 次优先级为0 */
  78. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  79. NVIC_Init(&NVIC_InitStructure);
  80. #endif
  81. return 0;
  82. }
  83. #if CAN_RX0_INT_ENABLE /* 如果使能RX0中断 */
  84. void USB_LP_CAN1_RX0_IRQHandler(void)
  85. {
  86. CanRxMsg RxMessage;
  87. CAN_Receive(CAN1, 0, &RxMessage);
  88. data_dump("can int recv", RxMessage.Data, sizeof(RxMessage.Data));
  89. }
  90. #endif
  91. /**
  92. *@function can发送一组数据
  93. *固定格式:ID,标准帧,数据帧
  94. *@param
  95. * len:数据长度(max 8)
  96. * msg:数据指针,最大8个字节
  97. *@return
  98. * 0----成功
  99. * 其他----失败
  100. */
  101. u8 Can_Send_Msg(u8* msg,u8 len,u32 ID)
  102. {
  103. u8 mbox;
  104. u16 i=0;
  105. CanTxMsg TxMessage;
  106. TxMessage.StdId=(ID >> 21); /* 标准标识符 */
  107. TxMessage.ExtId=((ID >> 3)&0x3ffff); /* 设置扩展标识符 */
  108. TxMessage.IDE=CAN_Id_Standard; /* 标准帧 */
  109. TxMessage.RTR=CAN_RTR_Data; /* 数据帧 */
  110. TxMessage.DLC=len; /* 要发送的数据长度 */
  111. for(i=0;i<len;i++)
  112. TxMessage.Data[i]=msg[i];
  113. mbox= CAN_Transmit(CAN1, &TxMessage);
  114. i=0;
  115. while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++; /* 等待数据发送 */
  116. if(i>=0XFFF)return 1;
  117. return 0;
  118. }
  119. /**
  120. *@function CAN接收数据查询
  121. *@param
  122. * buf:数据缓存区
  123. *@return
  124. * 0----无数据
  125. * 其他----接收到的数据长度
  126. */
  127. u8 Can_Receive_Msg(u8 *buf)
  128. {
  129. u32 i;
  130. CanRxMsg RxMessage;
  131. if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; /* 判断是否接收到数据 */
  132. CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); /* 读取数据 */
  133. for(i=0;i<8;i++)
  134. {
  135. buf[i]=RxMessage.Data[i];
  136. }
  137. return RxMessage.DLC;
  138. }
  139. int can_test(void)
  140. {
  141. int key = 0;
  142. CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_Normal);
  143. while(1)
  144. {
  145. Can_Send_Msg(can_buf,8,0x20000000);
  146. if(CAN_RX0_INT_ENABLE == 0) {
  147. memset(rec_buf, 0, sizeof(rec_buf));
  148. key = Can_Receive_Msg(rec_buf);
  149. if(key!=0) {
  150. data_dump("can recv", rec_buf, sizeof(rec_buf));
  151. }
  152. }
  153. delay_ms(1000);
  154. }
  155. }