久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5344|回復: 3
收起左側

STM32F1 can初始化程序

[復制鏈接]
ID:264387 發表于 2019-4-8 16:46 | 顯示全部樓層 |閱讀模式
#include "can.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
        u16 i=0;
         if(tsjw==0||tbs2==0||tbs1==0||brp==0)return 1;
        tsjw-=1;//先減去1.再用于設置
        tbs2-=1;
        tbs1-=1;
        brp-=1;

        RCC->APB2ENR|=1<<2;            //使能PORTA時鐘         
        GPIOA->CRH&=0XFFF00FFF;
        GPIOA->CRH|=0X000B8000;        //PA11 RX,PA12 TX推挽輸出            
    GPIOA->ODR|=3<<11;
                                            
        RCC->APB1ENR|=1<<25;        //使能CAN時鐘 CAN使用的是APB1的時鐘(max:36M)
        CAN1->MCR=0x0000;                //退出睡眠模式(同時設置所有位為0)
        CAN1->MCR|=1<<0;                //請求CAN進入初始化模式
        while((CAN1->MSR&1<<0)==0)
        {
                i++;
                if(i>100)return 2;        //進入初始化模式失敗
        }
        CAN1->MCR|=0<<7;                //非時間觸發通信模式
        CAN1->MCR|=0<<6;                //軟件自動離線管理
        CAN1->MCR|=0<<5;                //睡眠模式通過軟件喚醒(清除CAN1->MCR的SLEEP位)
        CAN1->MCR|=1<<4;                //禁止報文自動傳送
        CAN1->MCR|=0<<3;                //報文不鎖定,新的覆蓋舊的
        CAN1->MCR|=0<<2;                //優先級由報文標識符決定
        CAN1->BTR=0x00000000;        //清除原來的設置.
        CAN1->BTR|=mode<<30;        //模式設置 0,普通模式;1,回環模式;
        CAN1->BTR|=tsjw<<24;         //重新同步跳躍寬度(Tsjw)為tsjw+1個時間單位
        CAN1->BTR|=tbs2<<20;         //Tbs2=tbs2+1個時間單位
        CAN1->BTR|=tbs1<<16;        //Tbs1=tbs1+1個時間單位
        CAN1->BTR|=brp<<0;          //分頻系數(Fdiv)為brp+1
                                                        //波特率:Fpclk1/((Tbs1+Tbs2+1)*Fdiv)
        CAN1->MCR&=~(1<<0);                //請求CAN退出初始化模式
        while((CAN1->MSR&1<<0)==1)
        {
                i++;
                if(i>0XFFF0)return 3;//退出初始化模式失敗
        }
        //過濾器初始化
        CAN1->FMR|=1<<0;                //過濾器組工作在初始化模式
        CAN1->FA1R&=~(1<<0);        //過濾器0不激活
        CAN1->FS1R|=1<<0;                 //過濾器位寬為32位.
        CAN1->FM1R|=0<<0;                //過濾器0工作在標識符屏蔽位模式
        CAN1->FFA1R|=0<<0;                //過濾器0關聯到FIFO0
        CAN1->sFilterRegister[0].FR1=0X00000000;//32位ID
        CAN1->sFilterRegister[0].FR2=0X00000000;//32位MASK
        CAN1->FA1R|=1<<0;                //激活過濾器0
        CAN1->FMR&=0<<0;                //過濾器組進入正常模式

#if CAN_RX0_INT_ENABLE
         //使用中斷接收
        CAN1->IER|=1<<1;                //FIFO0消息掛號中斷允許.            
        MY_NVIC_Init(1,0,USB_LP_CAN1_RX0_IRQn,2);//組2
#endif
        return 0;
}   
u8 CAN_Tx_Msg(u32 id,u8 ide,u8 rtr,u8 len,u8 *dat)
{           
        u8 mbox;         
        if(CAN1->TSR&(1<<26))mbox=0;                //郵箱0為空
        else if(CAN1->TSR&(1<<27))mbox=1;        //郵箱1為空
        else if(CAN1->TSR&(1<<28))mbox=2;        //郵箱2為空
        else return 0XFF;                                        //無空郵箱,無法發送
        CAN1->sTxMailBox[mbox].TIR=0;                //清除之前的設置
        if(ide==0)        //標準幀
        {
                id&=0x7ff;//取低11位stdid
                id<<=21;                  
        }else                //擴展幀
        {
                id&=0X1FFFFFFF;//取低32位extid
                id<<=3;                                                                           
        }
        CAN1->sTxMailBox[mbox].TIR|=id;                 
        CAN1->sTxMailBox[mbox].TIR|=ide<<2;         
        CAN1->sTxMailBox[mbox].TIR|=rtr<<1;
        len&=0X0F;//得到低四位
        CAN1->sTxMailBox[mbox].TDTR&=~(0X0000000F);
        CAN1->sTxMailBox[mbox].TDTR|=len;        //設置DLC.
        //待發送數據存入郵箱.
        CAN1->sTxMailBox[mbox].TDHR=(((u32)dat[7]<<24)|
                                                                ((u32)dat[6]<<16)|
                                                                 ((u32)dat[5]<<8)|
                                                                ((u32)dat[4]));
        CAN1->sTxMailBox[mbox].TDLR=(((u32)dat[3]<<24)|
                                                                ((u32)dat[2]<<16)|
                                                                 ((u32)dat[1]<<8)|
                                                                ((u32)dat[0]));
        CAN1->sTxMailBox[mbox].TIR|=1<<0;         //請求發送郵箱數據
        return mbox;
}
u8 CAN_Tx_Staus(u8 mbox)
{        
        u8 sta=0;                                            
        switch (mbox)
        {
                case 0:
                        sta |= CAN1->TSR&(1<<0);                //RQCP0
                        sta |= CAN1->TSR&(1<<1);                //TXOK0
                        sta |=((CAN1->TSR&(1<<26))>>24);//TME0
                        break;
                case 1:
                        sta |= CAN1->TSR&(1<<8)>>8;                //RQCP1
                        sta |= CAN1->TSR&(1<<9)>>8;                //TXOK1
                        sta |=((CAN1->TSR&(1<<27))>>25);//TME1           
                        break;
                case 2:
                        sta |= CAN1->TSR&(1<<16)>>16;        //RQCP2
                        sta |= CAN1->TSR&(1<<17)>>16;        //TXOK2
                        sta |=((CAN1->TSR&(1<<28))>>26);//TME2
                        break;
                default:
                        sta=0X05;//郵箱號不對,肯定失敗.
                break;
        }
        return sta;
}
u8 CAN_Msg_Pend(u8 fifox)
{
        if(fifox==0)return CAN1->RF0R&0x03;
        else if(fifox==1)return CAN1->RF1R&0x03;
        else return 0;
}

void CAN_Rx_Msg(u8 fifox,u32 *id,u8 *ide,u8 *rtr,u8 *len,u8 *dat)
{           
        *ide=CAN1->sFIFOMailBox[fifox].RIR&0x04;        //得到標識符選擇位的值  
         if(*ide==0)//標準標識符
        {
                *id=CAN1->sFIFOMailBox[fifox].RIR>>21;
        }else           //擴展標識符
        {
                *id=CAN1->sFIFOMailBox[fifox].RIR>>3;
        }
        *rtr=CAN1->sFIFOMailBox[fifox].RIR&0x02;        //得到遠程發送請求值.
        *len=CAN1->sFIFOMailBox[fifox].RDTR&0x0F;        //得到DLC
         //*fmi=(CAN1->sFIFOMailBox[FIFONumber].RDTR>>8)&0xFF;//得到FMI
        //接收數據
        dat[0]=CAN1->sFIFOMailBox[fifox].RDLR&0XFF;
        dat[1]=(CAN1->sFIFOMailBox[fifox].RDLR>>8)&0XFF;
        dat[2]=(CAN1->sFIFOMailBox[fifox].RDLR>>16)&0XFF;
        dat[3]=(CAN1->sFIFOMailBox[fifox].RDLR>>24)&0XFF;   
        dat[4]=CAN1->sFIFOMailBox[fifox].RDHR&0XFF;
        dat[5]=(CAN1->sFIFOMailBox[fifox].RDHR>>8)&0XFF;
        dat[6]=(CAN1->sFIFOMailBox[fifox].RDHR>>16)&0XFF;
        dat[7]=(CAN1->sFIFOMailBox[fifox].RDHR>>24)&0XFF;   
          if(fifox==0)CAN1->RF0R|=0X20;//釋放FIFO0郵箱
        else if(fifox==1)CAN1->RF1R|=0X20;//釋放FIFO1郵箱         
}

#if CAN_RX0_INT_ENABLE        //使能RX0中斷
//中斷服務函數                           
void USB_LP_CAN1_RX0_IRQHandler(void)
{
        u8 rxbuf[8];
        u32 id;
        u8 ide,rtr,len;     
         CAN_Rx_Msg(0,&id,&ide,&rtr,&len,rxbuf);
    printf("id:%d\r\n",id);
    printf("ide:%d\r\n",ide);
    printf("rtr:%d\r\n",rtr);
    printf("len:%d\r\n",len);
    printf("rxbuf[0]:%d\r\n",rxbuf[0]);
    printf("rxbuf[1]:%d\r\n",rxbuf[1]);
    printf("rxbuf[2]:%d\r\n",rxbuf[2]);
    printf("rxbuf[3]:%d\r\n",rxbuf[3]);
    printf("rxbuf[4]:%d\r\n",rxbuf[4]);
    printf("rxbuf[5]:%d\r\n",rxbuf[5]);
    printf("rxbuf[6]:%d\r\n",rxbuf[6]);
    printf("rxbuf[7]:%d\r\n",rxbuf[7]);
}
#endif
u8 CAN_Send_Msg(u8* msg,u8 len)
{        
        u8 mbox;
        u16 i=0;                                                                          
    mbox=CAN_Tx_Msg(0X12,0,0,len,msg);
        while((CAN_Tx_Staus(mbox)!=0X07)&&(i<0XFFF))i++;//等待發送結束
        if(i>=0XFFF)return 1;                                                        //發送失敗?
        return 0;                                                                                //發送成功;
}
u8 CAN_Receive_Msg(u8 *buf)
{                                      
        u32 id;
        u8 ide,rtr,len;
        if(CAN_Msg_Pend(0)==0)return 0;                        //沒有接收到數據,直接退出         
          CAN_Rx_Msg(0,&id,&ide,&rtr,&len,buf);         //讀取數據
    if(id!=0x12||ide!=0||rtr!=0)len=0;                //接收錯誤           
        return len;        
}


本文章參考正點原子的CAN 通信實驗!!

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:486587 發表于 2019-6-17 03:31 | 顯示全部樓層
謝謝樓主分享
回復

使用道具 舉報

ID:433680 發表于 2019-6-17 15:44 | 顯示全部樓層

感謝分享
回復

使用道具 舉報

ID:229010 發表于 2019-6-24 14:08 | 顯示全部樓層
非常有用的資料。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久久av | 伊大人久久 | 久久久精品久 | 精品国产一区一区二区三亚瑟 | 久久久久久网站 | 欧美精品一区二区免费 | 91美女在线观看 | 嫩草国产 | 九九热在线视频观看这里只有精品 | 在线观看视频h | 久久精品小短片 | 四虎影视免费观看 | 99re在线视频观看 | 久久国产视频网 | 少妇久久久久 | 成人久久久 | 一级毛片播放 | 国产三级一区二区三区 | 欧美成人精品一区二区三区 | 亚洲精品免费观看 | 日韩国产在线观看 | 欧美成人高清视频 | 欧美精品综合在线 | 婷婷国产一区二区三区 | 在线播放中文字幕 | 国产精品亚洲一区 | 伊人网在线播放 | 亚洲九色 | 国产亚洲一区二区三区 | 精品国产成人 | 91精品国产自产在线老师啪 | 国产成人精品久久二区二区91 | 影音先锋男 | 动漫www.被爆羞羞av44 | 国产精品99久久久久久www | 国产一区在线免费 | 国产精品视频在线播放 | 久久久久久国产免费视网址 | 欧美日韩精品 | 午夜视频一区 | 精品国产乱码久久久久久88av |