<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-24 來(lái)源:網(wǎng)絡(luò) 收藏
          #include

          #include "sys.h"
          #include "delay.h"
          #include "CAN.h"
          CAN_msg CAN_TxMsg; //發(fā)送郵箱
          CAN_msg CAN_RxMsg; //接收郵箱
          u8 CAN_TxRdy=0; //發(fā)送就緒標(biāo)志
          u8 CAN_RxRdy=0; //接收就緒標(biāo)志
          u8CAN_TDTxR_DLC; //數(shù)據(jù)長(zhǎng)度,最高為1111
          /////////////////CAN設(shè)置/////////////////////////////////////
          void CAN_setup(void)
          {
          u8 brp=20; //獲取主時(shí)鐘頻率 APB1ENR時(shí)鐘頻率為36M
          RCC->APB1ENR|=1<<25; //RCC_APB1ENR_CANEN; //開啟CAN使能時(shí)鐘
          RCC->APB2ENR|=1<<0; //RCC_APB2ENR_AFIOEN; //開啟輔助時(shí)鐘
          AFIO->MAPR&=0XFFFF9FFF;//清除復(fù)用重映射配置寄存器13,14位,
          AFIO->MAPR|=0X00004000;//配置為10;IO口重映射至PB8.PB9
          RCC->APB2ENR|=1<<3; //RCC_APB2ENR_IOPBEN;//開啟IO口B時(shí)鐘
          GPIOB->CRH&=~(0X0F<<0);//清除PB8狀態(tài)寄存器~(1111<<0)
          GPIOB->CRH|=(0X08<<0);//設(shè)定pb8上下拉輸入1000
          GPIOB->CRH&=~(0XF<<4);//清空pb9狀態(tài)寄存器
          GPIOB->CRH|=(0X0B<<4);//設(shè)定PB9推挽輸出
          MY_NVIC_Init(1,1,USB_HP_CAN_TX_IRQChannel,2);//發(fā)送中斷使能
          MY_NVIC_Init(1,1,USB_LP_CAN_RX0_IRQChannel,2);//接收中斷使能
          CAN->MCR|=1<<4;//置NART位為1,禁止自動(dòng)重傳 403
          CAN->MCR|=1<<0; //置INRQ位為1,請(qǐng)求初始化 403 (CAN_MCR_NART|CAN_MCR_INRQ);//初始化模式,禁止重傳
          CAN->IER|=1<<0;//發(fā)送郵箱空中斷允許 409
          CAN->IER|=1<<1; //FIFO0消息掛號(hào)中斷允許 409 (CAN_IER_FMPIE0|CAN_IER_TMEIE);
          //brp=(brp/18)/500000;//波特率設(shè)置500Kb/s,計(jì)算波特率分頻器值
          CAN->BTR&=~(((0X03)<<24)|((0x07)<<20)|((0x0f)<<16)|(0x1ff)); //清空BTR寄存器相關(guān)位 410 400
          CAN->BTR|=(((1&0X03)<<24)|((7&0X07)<<20)|((8&0X0F)<<16)|(brp-1));//設(shè)置BTR寄存器 410 400

          }
          //////////////從初始化模式進(jìn)入正常工作模式/////////////////////////////////////////////
          void CAN_start(void)
          {
          CAN->MCR&=0xfffffffe;
          while(CAN->MSR&(0x01));
          CAN->MCR&=0xfffffffd; //清零INRQ位,進(jìn)入正常模式
          //while(~(CAN->MSR&0x01)); //等待硬件對(duì)INAK位清零,確認(rèn)退出初始化
          }
          //////////////設(shè)置工作模式///////////////////////////////////////////
          void CAN_testmode(void)
          {
          CAN->BTR&=0x3fffffff;//清空BTR 的SILM LBKM位410
          CAN->BTR|=0XC0000000;//設(shè)置BTR 的LBKM位為高,環(huán)回模式 410

          }
          ///////////////檢測(cè)發(fā)送郵箱為空////////////////////////////////////////////////
          void CAN_waitReady(void)
          {
          while((CAN->TSR&(1<<26))==0); //檢測(cè)發(fā)送郵箱0標(biāo)志位,為1則為空,為0不為空
          CAN_TxRdy=1; //置發(fā)送就緒標(biāo)志位為1
          }
          ///////////////發(fā)送數(shù)據(jù)//////////////////////////////////////
          void CAN_wrMsg(CAN_msg *msg)
          {
          CAN->sTxMailBox[0].TIR=(u8)0; //發(fā)送郵箱標(biāo)示符寄存器復(fù)位 清零
          if(msg->format ==STANDARD_FORMAT)//如果是標(biāo)準(zhǔn)11位標(biāo)示符幀
          {msg->id=33 ;
          CAN->sTxMailBox[0].TIR|=0x4200000;//(msg->id<<21)|CAN_ID_STD; //則標(biāo)示符左移21位,高11位為標(biāo)準(zhǔn)標(biāo)示符,標(biāo)示符選擇位置0 411
          }
          else //如果是29位擴(kuò)展標(biāo)示符幀
          {
          CAN->sTxMailBox[0].TIR|=(u8)(msg->id<<3)|CAN_ID_EXT; //標(biāo)示符左移3位,高29位為標(biāo)示符(擴(kuò)展標(biāo)示符)標(biāo)示符選擇位置1 411
          }
          if(msg->type==DATA_FRAME) //如果消息為數(shù)據(jù)幀
          {
          CAN->sTxMailBox[0].TIR|=CAN_RTR_DATA;//標(biāo)示符寄存器RTR位置0,數(shù)據(jù)幀
          }
          else //如果為遠(yuǎn)程幀
          {
          CAN->sTxMailBox[0].TIR|=CAN_RTR_REMOTE;//標(biāo)示符寄存器RTR置1,遠(yuǎn)程幀
          }
          CAN->sTxMailBox[0].TDLR=(((u8)msg->data[3]<<24)|((u8)msg->data[2]<<16)|((u8)msg->data[1]<<8)|((u8)msg->data[0])); //數(shù)據(jù)位低4字節(jié)寫入發(fā)送郵箱0



          CAN->sTxMailBox[0].TDHR=(((u8)msg->data[7]<<24)|((u8)msg->data[6]<<16)|((u8)msg->data[5]<<8)|((u8)msg->data[4])); //數(shù)據(jù)位高4字節(jié)寫入發(fā)送郵箱0



          CAN->sTxMailBox[0].TDTR&=0xfffffff0;//設(shè)置消息長(zhǎng)度DLC清0
          CAN->sTxMailBox[0].TDTR|=0x00000004;//設(shè)置消息長(zhǎng)度為4個(gè)字節(jié)
          CAN->IER|=1<<0; //發(fā)送郵箱空中斷使能 409
          CAN->sTxMailBox[0].TIR|=1<<0; //發(fā)送消息411

          }
          ///////////////讀取郵箱數(shù)據(jù)并釋放//////////////////////////////////////////////////////////////
          void CAN_rdMsg(CAN_msg *msg)
          {
          if((CAN->sFIFOMailBox[0].RIR&CAN_ID_EXT)==0) //如果是11位標(biāo)準(zhǔn)標(biāo)識(shí)符
          {
          msg->format=STANDARD_FORMAT; //消息為標(biāo)準(zhǔn)格式
          msg->id=(u32)0x000007ff&(CAN->sFIFOMailBox[0].RIR>>21); //標(biāo)示符等于標(biāo)示符位右移21位與0x7ff
          }
          else //如果是29位擴(kuò)展標(biāo)識(shí)符
          {
          msg->format=EXTENDED_FORMAT; //消息格式為擴(kuò)展標(biāo)示符格式
          msg->id=(u32)0x0003ffff&(CAN->sFIFOMailBox[0].RIR>>3);//標(biāo)示符等于標(biāo)示符位右移3位與上0x3ffff
          }
          if((CAN->sFIFOMailBox[0].RIR&CAN_RTR_REMOTE)==0) //如果消息為數(shù)據(jù)幀
          {
          msg->type=DATA_FRAME;
          }
          else //數(shù)據(jù)位遠(yuǎn)程幀
          {
          msg->type=REMOTE_FRAME;
          }
          msg->len = (unsigned char)0x0000000F & CAN->sFIFOMailBox[0].RDTR; //讀取數(shù)據(jù)長(zhǎng)度

          msg->data[0] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDLR); //讀取數(shù)據(jù)低4字節(jié)
          msg->data[1] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDLR >> 8);
          msg->data[2] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDLR >> 16);
          msg->data[3] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDLR >> 24);

          msg->data[4] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDHR); //讀取數(shù)據(jù)高4字節(jié)
          msg->data[5] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDHR >> 8);
          msg->data[6] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDHR >> 16);
          msg->data[7] = (unsigned int)0x000000FF & (CAN->sFIFOMailBox[0].RDHR >> 24);

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

          CAN->RF0R |= 1<<5; //釋放接收郵箱0 407
          }
          ////////////////////////設(shè)置標(biāo)示符過(guò)濾器組/////////////////////////////////////////////////////////////////////////////

          void CAN_wrFilter (unsigned int id, unsigned char format)
          {
          static unsigned short CAN_filterIdx = 0; //標(biāo)示符設(shè)置數(shù)量索引
          unsigned int CAN_msgId = 0; //變量用于存儲(chǔ)需要設(shè)定的標(biāo)示符

          if (CAN_filterIdx > 13) //檢查CAN過(guò)濾器是否已滿,最高到13
          {
          return; //如果已滿-返回
          }
          if (format == STANDARD_FORMAT) //如果是標(biāo)準(zhǔn)幀,標(biāo)準(zhǔn)幀是11位ID(報(bào)文識(shí)別碼)
          { // Standard ID
          CAN_msgId |= (unsigned int)(id << 21) | CAN_ID_STD;//標(biāo)示符左移21位并添加幀識(shí)別碼,得到32位的標(biāo)示符字
          }
          else //如果是擴(kuò)展幀,擴(kuò)展幀是29位ID(報(bào)文識(shí)別碼)
          { // Extended ID
          CAN_msgId |= (unsigned int)(id << 3) | CAN_ID_EXT;//標(biāo)示符左移3位并添加幀識(shí)別碼,得到32位的標(biāo)示符字
          }
          // set Initialisation mode for filter banks
          //CAN過(guò)濾器組工作在初始化模式
          CAN->FMR |= 1<<0;
          // deactivate filter
          CAN->FA1R &= ~(unsigned int)(1 << CAN_filterIdx);

          // initialize filter
          // set 32-bit scale configuration
          //初始化過(guò)濾器
          //過(guò)濾器位寬為單個(gè)32位
          CAN->FS1R |= (unsigned int)(1 << CAN_filterIdx);
          // set 2 32-bit identifier list mode
          //過(guò)濾器組x的2個(gè)32位寄存器工作在標(biāo)識(shí)符列表模式
          CAN->FM1R |= (unsigned int)(1 << CAN_filterIdx);
          // 32-bit identifier
          //32位標(biāo)識(shí)符
          CAN->sFilterRegister[CAN_filterIdx].FR1 = CAN_msgId;
          // 32-bit identifier
          //32位標(biāo)識(shí)符
          CAN->sFilterRegister[CAN_filterIdx].FR2 = CAN_msgId;
          // assign filter to FIFO 0
          //過(guò)濾器被關(guān)聯(lián)到FIFO0
          CAN->FFA1R &= ~(unsigned int)(1 << CAN_filterIdx);
          // activate filter
          //過(guò)濾器被激活
          CAN->FA1R |= (unsigned int)(1 << CAN_filterIdx);
          // reset Initialisation mode for filter banks
          //CAN過(guò)濾器組工作在正常模式
          CAN->FMR &= ~(1<<0); // 該位置0為正常模式 415
          // increase filter index
          //設(shè)置的過(guò)濾器數(shù)量增加
          CAN_filterIdx += 1;
          }


          上一頁(yè) 1 2 下一頁(yè)

          關(guān)鍵詞: STM32CAN總線通信程

          評(píng)論


          技術(shù)專區(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); })();