Chinaunix首页 | 论坛 | 博客
  • 博客访问: 692194
  • 博文数量: 192
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2177
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(192)

文章存档

2024年(8)

2023年(3)

2020年(1)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: 其他平台

2014-09-26 19:19:51

STM32F103RBT6单片机使用canbus与mcp2510通信。记录备忘。

1. 将引脚配置成canbus接口

点击(此处)折叠或打开

  1. /* Configure CAN pin: RX */
  2.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  3.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  4.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  5.     /* Configure CAN pin: TX */
  6.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  7.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  8.     GPIO_Init(GPIOA, &GPIO_InitStructure);

2.STM32F103RBT6初始化canbus接口配置

点击(此处)折叠或打开

  1. void CAN_Configuration(int filterId)
  2. {
  3.   CAN_InitTypeDef CAN_InitStructure;
  4.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
  5. // CanTxMsg TxMessage;
  6. // u8 TransmitMailbox;
  7. // u8 i=0;

  8.   /* CAN register init */
  9.   CAN_DeInit();
  10.   CAN_StructInit(&CAN_InitStructure);

  11.   /* CAN cell init */
  12.   CAN_InitStructure.CAN_TTCM=DISABLE;
  13.   CAN_InitStructure.CAN_ABOM=DISABLE;
  14.   CAN_InitStructure.CAN_AWUM=DISABLE;
  15.   CAN_InitStructure.CAN_NART=DISABLE;
  16.   CAN_InitStructure.CAN_RFLM=DISABLE;
  17.   CAN_InitStructure.CAN_TXFP=DISABLE;
  18.   //CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
  19.   CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
  20.  
  21.   CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  22.   CAN_InitStructure.CAN_BS1=CAN_BS1_11tq;
  23.   CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;
  24.   CAN_InitStructure.CAN_Prescaler=18;
  25.   CAN_Init(&CAN_InitStructure);

  26.   /* CAN filter init */
  27.   CAN_FilterInitStructure.CAN_FilterNumber=1;
  28.   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  29.   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  30.  
  31.   CAN_FilterInitStructure.CAN_FilterIdHigh = (((filterId << 3) >> 16) & 0xffff);
  32.   CAN_FilterInitStructure.CAN_FilterIdLow = ((filterId << 3) & 0xFFFF);
  33.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = ((FILTER_MASK << 3) >> 16) & 0xffff;
  34.   //CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  35.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = ((FILTER_MASK << 3) & 0xffff);
  36.   //CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
  37.  
  38.   
  39.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
  40.   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  41.   CAN_FilterInit(&CAN_FilterInitStructure);

  42.   /* CAN FIFO0 and FIFO1 message pending interrupt enable */
  43.   //CAN_ITConfig(CAN_IT_FMP0, ENABLE);
  44.   CAN_ITConfig((CAN_IT_FMP0 | CAN_IT_FMP1), ENABLE);

  45. }

3.中断上下文接收canbus数据

点击(此处)折叠或打开

  1. void USB_LP_CAN_RX0_IRQHandler(void)
  2. {
  3.     CanRxMsg RxMessage;
  4.     u8 currSeq;

  5.     while(0 != CAN_MessagePending(CAN_FIFO0))
  6.     {
  7.         //memset(&RxMessage, 0, sizeof(RxMessage));
  8.         CAN_Receive(CAN_FIFO0, &RxMessage);
  9.         
  10.         g_canRevBuf.len = RxMessage.Data[1];
  11.         currSeq = RxMessage.Data[3];
  12.         
  13.         /**
  14.         * Note: 1、由于乱序的可能性较高,故而不能用入队列的标准接口
  15.         * 2、当数据接收完成后, 组装成可直接供串口发送的数据
  16.         * 3、
  17.         **/
  18.         memcpy(&g_canRevBuf.buf[currSeq << 2], &RxMessage.Data[4], 4);
  19.         //memset(&g_canRevBuf.ctrl[currSeq << 2], CTRL_CONTI, 4);
  20.         
  21.         if(0x0 != bitmap_test_set(&bmpRcvCan, currSeq))
  22.         {
  23.             ;/** warning: the frame which specified NO. had been received again **/
  24.         }
  25.         
  26.         if(bitmap_isfull(&bmpRcvCan, (g_canRevBuf.len + 3) >> 2)) /** 判断数据包结束. currpktSeq从0开始的序号, 加1后就是的1的个数 **/
  27.         {
  28.             bitmap_clean(&bmpRcvCan);
  29.             inq(&g_msgq, CMSG_CANRX);
  30.             /***************************************************************************/
  31.             GPIO_ResetBits(GPIOA, GPIO_Pin_0);
  32.             /***************************************************************************/
  33.             i_flag &= ~(1 << 4);
  34.         }
  35.         else
  36.         {
  37.             /***************************************************************************/
  38.             GPIO_SetBits(GPIOA, GPIO_Pin_0);
  39.             /***************************************************************************/
  40.             i_flag |= (1 << 4);
  41.         }
  42.     }
  43. }

4.向canbus总线发送数据

点击(此处)折叠或打开

  1. /*******************************************************************************
  2.  * prototype: int send2can(canFrame_queue_t *dest, X10RevData_t *src)
  3.  *
  4.  * descriptor: 将收到的数据转换成等待发送的canbus数据
  5.  *
  6.  * input: src
  7.  * output: dest
  8.  * return: none
  9.  *
  10.  * Note: the data come from USART2, the format: len + [data ..] + 0xff
  11.  *******************************************************************************/
  12. u8 g_ucCanseq = 0;
  13.    
  14. int send2can(canFrame_queue_t *dest, const X10RevData_t *src)
  15. {
  16.     int i;
  17.     CanTxMsg TxMessage;
  18.     unsigned char tmpbuf[16];
  19.     unsigned char ucAddr = 0;
  20.     unsigned char ucFunc = 0;
  21.     unsigned int tmpVal;

  22.     /* transmit */
  23.     TxMessage.StdId = 0x0; /** destination **/
  24.     TxMessage.ExtId = (0x80 | (g_channel & 0x7f)) | (TxMessage.StdId << 18); /** source **/
  25.     TxMessage.RTR = CAN_RTR_DATA;
  26.     //TxMessage.IDE = CAN_ID_STD;
  27.     TxMessage.IDE = CAN_ID_EXT;
  28.     TxMessage.DLC = 8;

  29.     TxMessage.Data[0] = 0x80 | (g_channel & 0x7f); /** destination **/
  30.     TxMessage.Data[1] = 16; /** get length first **/
  31.  
  32.     if((g_ucCanseq + 4) >= 255){g_ucCanseq = 0;} else {g_ucCanseq += 2;}
  33.     
  34.     /** clear the buff **/
  35.     for(i = 0; i < 16; i++)tmpbuf[i] = 0;

  36.     /** address **/
  37.     if((src->flags & 0x01) == 1)    /** the address is valid **/
  38.     {    
  39.         tmpVal = src->addrCode;
  40.         for(i = 0; i < 8; i++)
  41.         {
  42.             ucAddr <<= 1;
  43.             ucAddr |= ((tmpVal & 0x30000) == 0x20000);
  44.             tmpVal <<= 2;
  45.         }
  46.         /** keyCode **/
  47.         tmpbuf[0] = (ucAddr & 0x0f);
  48.         tmpbuf[0] = (key2num(tmpbuf[0]) + 1);
  49.         /** houseCode **/
  50.         tmpbuf[1] = ((ucAddr >> 4) & 0x0f);
  51.         tmpbuf[1] = house2num(tmpbuf[1]);
  52.     }
  53.     else
  54.     {
  55.         //ucAddr = g_destAddr;
  56.         tmpbuf[0] = (g_destAddr & 0x0f);
  57.         tmpbuf[1] = ((g_destAddr >> 4) & 0x0f);
  58.     }
  59.         
  60.     /** function **/
  61.     tmpVal = src->funcCode;
  62.     for(i = 0; i < 5; i++)
  63.     {
  64.         ucFunc <<= 1;
  65.         ucFunc |= ((tmpVal & 0x300) == 0x200);
  66.         tmpVal <<= 2;
  67.     }

  68.     /** tmpbuf[10]: cmd, it depends on the funcionCode **/
  69.     if((ucFunc == 0x1b) || (ucFunc == 0x1d))    /** 收到状态回复 **/
  70.     {
  71.         tmpbuf[10] = 0x43;
  72.         /** 由于是响应回复, 所以数据帧中的地址应该是源设备地址 **/
  73.         tmpbuf[4] = tmpbuf[0];
  74.         tmpbuf[5] = tmpbuf[1];
  75.         
  76.         tmpbuf[0] = 0;
  77.         tmpbuf[1] = 0;
  78.         
  79.         tmpbuf[6] = CDEV_TYPE;
  80.     }
  81.     else if(ucFunc == 0x1f)                /** 收到状态查询(可能以后用得上) **/
  82.     {
  83.         tmpbuf[10] = 0x41;
  84.     }
  85.     else                                /** 收到状态设定(可能以后用得上) **/
  86.     {
  87.         tmpbuf[10] = 0x42;
  88.     }
  89.     
  90.     tmpbuf[11] = 0x01;            /** protocal **/
  91.     tmpbuf[12] = (ucFunc & 0x1f);
  92.     tmpbuf[15] = makeCrc8(0, tmpbuf, 15);
  93.     
  94.     for(i = 0; i <= 15;
阅读(1238) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~