<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于stm32的can總線徹底研究

          基于stm32的can總線徹底研究

          作者: 時(shí)間:2016-11-18 來(lái)源:網(wǎng)絡(luò) 收藏
          1、CAN總線的初始化
          void can_init(void)
          {
          CAN_InitTypeDef CAN_InitStructure;
          CAN_FilterInitTypeDef CAN_FilterInitStructure;
          /* CAN register init */
          CAN_DeInit();
          CAN_StructInit(&CAN_InitStructure);

          /* CAN cell init */
          CAN_InitStructure.CAN_TTCM=DISABLE;//禁止時(shí)間觸發(fā)通信模式
          CAN_InitStructure.CAN_ABOM=DISABLE;
          CAN_InitStructure.CAN_AWUM=DISABLE;
          CAN_InitStructure.CAN_NART=DISABLE;//CAN報(bào)文只被發(fā)送1次,不管發(fā)送的結(jié)果如何(成功、出錯(cuò)或仲裁丟失)
          CAN_InitStructure.CAN_RFLM=DISABLE;
          CAN_InitStructure.CAN_TXFP=DISABLE;
          CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
          //CAN_Mode_LoopBack
          //CAN_Mode_Normal
          CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
          CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
          CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
          CAN_InitStructure.CAN_Prescaler=2;
          CAN_Init(&CAN_InitStructure);
          #ifdef can_id_filter
          /* CAN filter init */
          CAN_FilterInitStructure.CAN_FilterNumber=0;//選擇過(guò)濾器0
          CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定過(guò)濾器被設(shè)置為標(biāo)識(shí)符屏蔽模式
          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//給出過(guò)濾器位寬為32位
          CAN_FilterInitStructure.CAN_FilterIdHigh=slave_id<<5;//過(guò)濾器標(biāo)識(shí)符
          CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;//過(guò)濾器屏蔽標(biāo)識(shí)符
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc;
          CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;//選擇FIFO0
          CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能過(guò)濾器
          CAN_FilterInit(&CAN_FilterInitStructure);//進(jìn)入初始化函數(shù)
          #else
          /* CAN filter init */
          CAN_FilterInitStructure.CAN_FilterNumber=0;//選擇過(guò)濾器0
          CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定過(guò)濾器被設(shè)置為標(biāo)識(shí)符屏蔽模式
          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//給出過(guò)濾器位寬為32位
          CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//過(guò)濾器標(biāo)識(shí)符
          CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//過(guò)濾器屏蔽標(biāo)識(shí)符
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
          CAN_ITConfig(CAN_IT_FMP0, ENABLE);//使能指定的can中斷
          }
          void CAN_DeInit(void)
          {
          /* Enable CAN reset state */
          RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, ENABLE);
          /* Release CAN from reset state */
          RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, DISABLE);
          }
          2、發(fā)送程序
          unsignedcharCAN_PushMessage(CAN_MSG *pTransmitBuf )
          {
          u8 TransmitMailbox=0;
          CanTxMsg TxMessage;
          if(pTransmitBuf -> LEN > 8)
          {
          return 1;
          }
          /* transmit */
          TxMessage.StdId=pTransmitBuf ->StdId;//用來(lái)設(shè)定標(biāo)準(zhǔn)標(biāo)識(shí)符(0-0x7ff,11位)
          TxMessage.ExtId=pTransmitBuf ->ExtId;
          TxMessage.RTR= pTransmitBuf ->RTR;//設(shè)置RTR位為數(shù)據(jù)幀
          TxMessage.IDE= pTransmitBuf ->IDE;//標(biāo)識(shí)符擴(kuò)展位,為標(biāo)準(zhǔn)幀
          TxMessage.DLC= pTransmitBuf ->LEN;//設(shè)置數(shù)據(jù)長(zhǎng)度
          //根據(jù)DLC字段的值,將有效數(shù)據(jù)拷貝到發(fā)送數(shù)據(jù)寄存器
          memcpy(TxMessage.Data, pTransmitBuf ->BUF,pTransmitBuf ->LEN);
          TransmitMailbox = CAN_Transmit(&TxMessage);
          // TxMessage.Data[1]=(data & 0xff00)>>8;
          return 1;
          }
          3、中斷接收程序
          void USB_LP_CAN_RX0_IRQHandler(void)
          {
          //清空can接收緩存
          CanRxMsg RxMessage;
          RxMessage.StdId=0x00;
          RxMessage.ExtId=0x00;
          RxMessage.IDE=0;
          RxMessage.DLC=0;
          RxMessage.FMI=0;//CAN過(guò)濾主控制寄存器
          memset( &RxMessage.Data[0],0,8);
          //can總線接收數(shù)據(jù)函數(shù)
          CAN_Receive(CAN_FIFO0, &RxMessage);
          //將接收到的數(shù)據(jù)寫(xiě)于modbus的寄存器1
          //modbus_regester[1]=(RxMessage.Data[0]<<8)|(RxMessage.Data[1]);
          // if((RxMessage.StdId==slave_id) && (RxMessage.ExtId==0x00) && (RxMessage.IDE==CAN_ID_STD))
          {
          //將can接收標(biāo)志位置1,表示從卡應(yīng)經(jīng)接收到一個(gè)can報(bào)文
          flag_can_recv=0;
          memcpy(can_rx_data,&RxMessage.Data,RxMessage.DLC);
          flag_can_recv=1;
          }
          }
          4、can總線的id過(guò)濾

          對(duì)擴(kuò)展數(shù)據(jù)幀過(guò)濾:

          本文引用地址:http://www.ex-cimer.com/article/201611/315584.htm

          CAN_FilterInitStructure.CAN_FilterNumber=0;
          CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
          CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)CAN_ID<<3)&0xFFFF0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;

          對(duì)標(biāo)準(zhǔn)數(shù)據(jù)幀過(guò)濾:

          CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)CAN_ID0<<21)&0xFFFF0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;

          假如要對(duì)標(biāo)準(zhǔn)遠(yuǎn)程幀進(jìn)行過(guò)濾,那么:

          只需要將

          CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;改成:

          CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xFFFF;

          5、can總線的幀格式

          數(shù)據(jù)幀格式:

          遠(yuǎn)程幀格式:

          6、can總線的邏輯電平

          can總線的物理連接有兩根線:CANH和CANL,以差分的形式輸出。

          (有的時(shí)候有地線,作為屏蔽線使用)

          can總線的高電平3.5v,表示邏輯0

          can總線的低電平1.5v,表示邏輯1

          7、CAN總線的波特率計(jì)算

          can時(shí)鐘是RCC_APB1PeriphClock,要注意CAN時(shí)鐘頻率
          CAN波特率=RCC_APB1PeriphClock/CAN_SJW CAN_BS1 CAN_BS2/CAN_Prescaler;
          如果CAN時(shí)鐘為8M,CAN_SJW=1,CAN_BS1=8,CAN_BS2=7,CAN_Prescaler=2
          那么波特率就是=8M/(1 8 7)/2=250K

          8、can總線的仲裁機(jī)制

          根據(jù)仲裁來(lái)判斷優(yōu)先級(jí):

          (1)若在同一時(shí)刻,標(biāo)準(zhǔn)格式的報(bào)文與擴(kuò)展格式的報(bào)文同時(shí)搶占總線,且它們的基礎(chǔ)ID相同,則發(fā)標(biāo)準(zhǔn)格式的報(bào)文節(jié)點(diǎn)就會(huì)PK成功。這是因?yàn)閿U(kuò)展格式在基本ID后,緊接著是SRR位,與IDE位,且這兩位都是隱性位。而在標(biāo)準(zhǔn)格式中,這兩位分別對(duì)應(yīng)的位為RTR與r1,其中RTR既可以為隱性位,也可以為顯性位,,但是r1必須為顯性位。由仲裁規(guī)則可以此時(shí)標(biāo)準(zhǔn)幀必定勝出。

          (2)同理,如果在同一時(shí)刻,具有相同格式,且具有相同ID的數(shù)據(jù)幀與遠(yuǎn)程幀爭(zhēng)奪總線控制權(quán),那么數(shù)據(jù)幀必定勝出。因?yàn)镽TR顯性表示數(shù)據(jù)幀,隱性表示遠(yuǎn)程幀。

          stm32的can總線的配置如下:
          CAN_InitStructure.CAN_TTCM=DISABLE;//禁止時(shí)間觸發(fā)通信模式
          CAN_InitStructure.CAN_ABOM=DISABLE;
          CAN_InitStructure.CAN_AWUM=DISABLE;
          CAN_InitStructure.CAN_NART=DISABLE;//CAN報(bào)文只被發(fā)送1次,不管發(fā)送的結(jié)果如何(成功、出錯(cuò)或仲裁丟失)
          CAN_InitStructure.CAN_RFLM=DISABLE;
          CAN_InitStructure.CAN_TXFP=DISABLE;
          CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
          //CAN_Mode_LoopBack
          //CAN_Mode_Normal
          CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
          CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
          CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
          CAN_InitStructure.CAN_Prescaler=2;

          CAN_Init(&CAN_InitStructure);
          /* CAN filter init */
          CAN_FilterInitStructure.CAN_FilterNumber=0;//選擇過(guò)濾器0
          CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定過(guò)濾器被設(shè)置為標(biāo)識(shí)符屏蔽模式
          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//給出過(guò)濾器位寬為32位
          下面根據(jù)設(shè)置的參數(shù)不同來(lái)決定can總線can總線的配置情況:
          1、對(duì)擴(kuò)展數(shù)據(jù)幀進(jìn)行過(guò)濾:(只接收擴(kuò)展數(shù)據(jù)幀)
          CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<3)&0xFFFF0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
          (注:標(biāo)準(zhǔn)幀數(shù)據(jù)幀、標(biāo)準(zhǔn)遠(yuǎn)程幀和擴(kuò)展遠(yuǎn)程幀均被過(guò)濾)
          2、對(duì)擴(kuò)展遠(yuǎn)程幀過(guò)濾:(只接收擴(kuò)展遠(yuǎn)程幀)
          CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<3)&0xFFFF0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_REMOTE)&0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
          3、對(duì)標(biāo)準(zhǔn)遠(yuǎn)程幀過(guò)濾:(只接收標(biāo)準(zhǔn)遠(yuǎn)程幀)
          CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<21)&0xffff0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xffff;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
          4、對(duì)標(biāo)準(zhǔn)數(shù)據(jù)幀過(guò)濾:(只接收標(biāo)準(zhǔn)數(shù)據(jù)幀)
          CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<21)&0xffff0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
          5、對(duì)擴(kuò)展幀進(jìn)行過(guò)濾:(擴(kuò)展幀不會(huì)被過(guò)濾掉)
          CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<3)&0xFFFF0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<3)|CAN_ID_EXT)&0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFC;
          6、對(duì)標(biāo)準(zhǔn)幀進(jìn)行過(guò)濾:(標(biāo)準(zhǔn)幀不會(huì)被過(guò)濾掉)
          CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<21)&0xffff0000)>>16;
          CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD)&0xffff;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
          CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFC;
          注:slave_id為要過(guò)濾的id號(hào)。



          關(guān)鍵詞: stm32can總

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();