在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于STM32的CAN總線通信程序

            基于STM32的CAN總線通信程序

            作者: 時(shí)間:2016-11-24 來源:網(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ù)長度,最高為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

            }
            ///////////////檢測發(fā)送郵箱為空////////////////////////////////////////////////
            void CAN_waitReady(void)
            {
            while((CAN->TSR&(1<<26))==0); //檢測發(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è)置消息長度DLC清0
            CAN->sTxMailBox[0].TDTR|=0x00000004;//設(shè)置消息長度為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ù)長度

            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.biyoush.com/article/201611/320933.htm

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

            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過濾器是否已滿,最高到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過濾器組工作在初始化模式
            CAN->FMR |= 1<<0;
            // deactivate filter
            CAN->FA1R &= ~(unsigned int)(1 << CAN_filterIdx);

            // initialize filter
            // set 32-bit scale configuration
            //初始化過濾器
            //過濾器位寬為單個(gè)32位
            CAN->FS1R |= (unsigned int)(1 << CAN_filterIdx);
            // set 2 32-bit identifier list mode
            //過濾器組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ān)聯(lián)到FIFO0
            CAN->FFA1R &= ~(unsigned int)(1 << CAN_filterIdx);
            // activate filter
            //過濾器被激活
            CAN->FA1R |= (unsigned int)(1 << CAN_filterIdx);
            // reset Initialisation mode for filter banks
            //CAN過濾器組工作在正常模式
            CAN->FMR &= ~(1<<0); // 該位置0為正常模式 415
            // increase filter index
            //設(shè)置的過濾器數(shù)量增加
            CAN_filterIdx += 1;
            }


            上一頁 1 2 下一頁

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

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉