打印
[STM32F1]

用STM32F107,CAN扩展帧,用USB_CAN助手和PC通信,板子无法返回数据

[复制链接]
1060|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
汤火|  楼主 | 2015-12-23 18:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*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);
  }

}
}
沙发
gejigeji521| | 2015-12-23 23:59 | 只看该作者
https://bbs.21ic.com/icview-348466-1-1.html
参考这个帖子。

板子A 和板子B通讯,分别按下板A的的按键,通过CAN通讯,板B收到数据后,点亮板B上相应的LED灯。

发送.zip (345.75 KB, 下载次数: 282)
接收.zip (371.52 KB, 下载次数: 247)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

22

帖子

1

粉丝