| 
 
| /*CAN模块初始化*/ void CAN1__Init(void)
 {
 RCC->APB1ENR&=0XFDFFFFFF;
 RCC->APB1ENR|=1<<25;//使能CAN时钟
 RCC->APB2ENR&=0XFFFFFFFB;
 RCC->APB2ENR|=1<<2;//使能GPIOA时钟
 GPIOA->CRH&=0XFFF00FFF;
 GPIOA->CRH|=0X000B8000;//PA11(CAN1_RX)为上拉或下拉输入模式,PA12(CAN1_TX)为复用推挽输出模式
 
 /*设置CAN模式*/
 CAN1->MCR&=0XFFFFFFFD;//请求退出睡眠模式
 while((CAN1->MSR&0X00000002)==1);//确认退出睡眠模式
 CAN1->MSR&=~(1<<3);//删除唤醒中断挂号标志位
 CAN1->MCR|=1<<0;//进入初始化模式
 while((CAN1->MSR&0X00000001)==0);//确认进入初始化模式
 
 CAN1->BTR=0X00050011;//正常状态;禁止环回模式;SJW=0;TS2=0;TS1=5;BRP=44;波特率=36M/(1+6+1)/18=250K
 CAN1->MCR&=0XFFFFFFFE;//CAN退出初始化模式
 while((CAN1->MSR&0X00000001)==1);//确认CAN已经退出初始化模式,进入正常工作模式
 
 /*设置CAN的过滤器组1*/
 CAN1->FMR=1;//过滤器组工作在初始化模式
 CAN1->FA1R&=0XFFFFFFFD;//过滤器组1被禁止激活
 CAN1->FM1R&=0X000003FFD;//过滤器组1的2个32位寄存器工作在标识符屏蔽位模式
 CAN1->FS1R|=1<<1;      //过滤器组1的过滤器位宽为单个32位
 CAN1->sFilterRegister[1].FR1=0X80020000;//ID:0C040000--6020;10040000--8020
 CAN1->sFilterRegister[1].FR2=0XFFFFFFFF;//1关心,0不关心,32位全部匹配,到来的标识符位必须与滤波器对应的标识符寄存器位相一致。
 CAN1->FFA1R&=0XFFFFFFFD;//过滤器组1被关联到FIFO0
 CAN1->FA1R|=1<<1;       //激活过滤器组1
 CAN1->FMR&=0XFFFFFFFE;  //过滤器组退出初始化模式,进入正常工作模式
 CAN1->IER|=1<<1;        //FIFO0消息挂号中断允许(当FIFO0的FMP0[1:0]位被写入非0值时,产生中断)
 }
 
 
 /*报文使用扩展标识符发送*/
 void CAN1_Transmit(int iLongofData)
 {
 u8 TransmitMailbox = 0;
 if((CAN1->TSR&0X04000000)>>26==1)//邮箱0位空
 {
 TransmitMailbox = 0;
 }
 else if((CAN1->TSR&0X08000000)>>27==1)//邮箱1为空
 {
 TransmitMailbox = 1;
 }
 else if((CAN1->TSR&0X10000000)>>28==1)//邮箱2为空
 {
 TransmitMailbox = 2;
 }
 else
 {
 TransmitMailbox = 3;
 }
 if (TransmitMailbox != 3)
 {
 TXSFF22[0]=0x00;
 TXSFF22[1]=0x00;
 TXSFF22[2]=0x60;
 TXSFF22[3]=0x02;
 CAN1->sTxMailBox[TransmitMailbox].TIR &= 0x00000000;
 CAN1->sTxMailBox[TransmitMailbox].TIR = (u32)(TXSFF22[2]<<24 | TXSFF22[3]<<16);
 CAN1->sTxMailBox[TransmitMailbox].TIR &= 0xFFFFFFF9;        //IDR,RTR清零,
 CAN1->sTxMailBox[TransmitMailbox].TIR |= 0X00000004;        //扩展帧,数据帧
 CAN1->sTxMailBox[TransmitMailbox].TDTR &= 0xFFFFFFF0;
 CAN1->sTxMailBox[TransmitMailbox].TDTR|=iLongofData;    //发送数据报文长度iLongofData
 
 CAN1->sTxMailBox[TransmitMailbox].TDLR = (u32)(TXSFF22[4] | TXSFF22[5]<<8 | TXSFF22[6]<<16 | TXSFF22[7]<<24);
 CAN1->sTxMailBox[TransmitMailbox].TDHR = (u32)(TXSFF22[8] | TXSFF22[9]<<8 | TXSFF22[10]<<16 | TXSFF22[11]<<24);//数据高4字节
 CAN1->sTxMailBox[TransmitMailbox].TIR|=1<<0;//请求发送数据
 }
 }
 
 
 /*CAN通信的接收中断服务函数20140821*/
 void CAN1_RX0_IRQHandler(void)
 {
 if((CAN1->RF0R&0x03)==1)        //   FIFO 0报文数为1
 {
 TXSJJ22[0] =(u8) 0x07 & CAN1->sFIFOMailBox[0].RIR;
 
 IDE = (u8)0x04 & TXSJJ22[0];//IDE代表接收到的报文使用的是标准标识符还是扩展标识符
 RTR = (u8)0x02 & TXSJJ22[0]; //远程发送的是数据帧(=0)还是远程帧(=1)
 if(RTR==0x00)    //数据帧,有效
 {
 DLC = (u8)0x0F & CAN1->sFIFOMailBox[0].RDTR;          //接收到的数据长度(数据帧为0~8,远程帧恒为0)
 if(IDE==0x04)     //扩展帧或标准帧信息,1为扩展帧,0为标准帧
 {        //TXSJJ22[1]-TXSJJ22[2]保存11位标识符信息
 TXSJJ22[1] =(u8) 0xFF & (CAN1->sFIFOMailBox[0].RIR >> 24);// (ID.28~ID.21)
 TXSJJ22[2] =(u8) 0xFF & (CAN1->sFIFOMailBox[0].RIR >> 16);// (ID.20~ID.13)
 TXSJJ22[3] =(u8) 0xFF & (CAN1->sFIFOMailBox[0].RIR >> 8);
 TXSJJ22[4] =(u8) 0xF1 & (CAN1->sFIFOMailBox[0].RIR>>3 ); //(ID.4~ID.0)
 TXSJJ22[5]  =(u8) CAN1->sFIFOMailBox[0].RDLR & 0xFF;
 TXSJJ22[6]  =(u8) (CAN1->sFIFOMailBox[0].RDLR >>8 ) & 0xFF;
 TXSJJ22[7]  =(u8) (CAN1->sFIFOMailBox[0].RDLR >>16) & 0xFF;
 TXSJJ22[8]  =(u8) (CAN1->sFIFOMailBox[0].RDLR >>24) & 0xFF;
 TXSJJ22[9]  =(u8) CAN1->sFIFOMailBox[0].RDHR & 0xFF;
 TXSJJ22[10] =(u8) (CAN1->sFIFOMailBox[0].RDHR >>8 ) & 0xFF;
 TXSJJ22[11] =(u8) (CAN1->sFIFOMailBox[0].RDHR >>16) & 0xFF;
 TXSJJ22[12] =(u8) (CAN1->sFIFOMailBox[0].RDHR >>24) & 0xFF;//根据数据长度?信息获取数据
 CANJS=1;
 }
 }
 CAN1->RF0R|=1<<5;//释放FIFO输出邮箱,必须在此处释放,否则程序无法通过
 }
 }
 
 
 
 int main(void)
 {
 
 MYRCC_DeInit();//将所有时钟寄存器复位;所有中断关闭;中断向量表映射到flash区,地址为0X0000
 SystemInit();  //设置外部输入时钟、系统时钟、高速外设时钟、低速外设时
 delay_init(72);       //延时函数初始化,时钟选择系统时钟72MHZ
 CAN1__Init();
 
 NVIC_Configuration();
 
 while(1)
 {
 if(CANJS==1)
 {
 CANJS=0;
 TXSFF22[4]=0x0A;
 TXSFF22[5]=0x0B;
 TXSFF22[6]=0x0C;
 TXSFF22[7]=0x0D;
 CAN1_Transmit(4);
 }
 
 }
 }
 
 | 
 |