/*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);
}
}
}
|