初级会员 
  
	- 积分
 - 56
 
        - 金钱
 - 56 
 
       - 注册时间
 - 2022-5-11
 
      - 在线时间
 - 6 小时
 
 
 
 | 
 
1金钱 
我调用的CAN1是PA11(rx)和PA12(tx),其他代码照抄原子例程,发现can1初始化只能使用回环模式,不能用正常模式。求大佬指点!!! 以下是例程: 
 
 
//CAN初始化 
 
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode) 
{ 
 
          GPIO_InitTypeDef GPIO_InitStructure;  
          CAN_InitTypeDef        CAN_InitStructure; 
          CAN_FilterInitTypeDef  CAN_FilterInitStructure; 
 
    //使能相关时钟 
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                     
 
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟         
                 
          //引脚复用映射配置 
          GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1 
          GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1 
           
    //初始化GPIO 
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能 
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12 
         
          //CAN单元设置 
           CAN_InitStructure.CAN_TTCM=DISABLE;        //非时间触发通信模式    
          CAN_InitStructure.CAN_ABOM=DISABLE;        //软件自动离线管理           
          CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位) 
          CAN_InitStructure.CAN_NART=ENABLE;        //禁止报文自动传送  
          CAN_InitStructure.CAN_RFLM=DISABLE;        //报文不锁定,新的覆盖旧的   
          CAN_InitStructure.CAN_TXFP=DISABLE;        //优先级由报文标识符决定  
          CAN_InitStructure.CAN_Mode= mode;         //模式设置  
          CAN_InitStructure.CAN_SJW=tsjw;        //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq 
          CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq 
          CAN_InitStructure.CAN_BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~        CAN_BS2_8tq 
          CAN_InitStructure.CAN_Prescaler=brp;  //分频系数(Fdiv)为brp+1         
          CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1  
 
                //配置过滤器 
           CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0 
          CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;  
          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位  
          CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID 
          CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK 
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
           CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0 
          CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0 
          CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化 
         
        return 0; 
}    
 
 
//***************************************************************************** 
//功能:can发送试验. 
//***************************************************************************** 
 
 
u8 CAN1_Send_Msg(u32 ID,u8* msg,u8 len) 
{         
  u8 mbox; 
  u16 i=0; 
  CanTxMsg TxMessage; 
  TxMessage.StdId=0x12;         // 标准标识符为0 
  TxMessage.ExtId=ID;         // 设置扩展标示符(29位) 
  TxMessage.IDE=CAN_Id_Extended;  // 使用扩展标识符 
  TxMessage.RTR=CAN_RTR_Data;                  // 消息类型为数据帧,一帧8位 
  TxMessage.DLC=len;                                                        // 发送两帧信息 
  for(i=0;i<len;i++) 
  TxMessage.Data[i]=msg[i];                                 // 第一帧信息           
  mbox= CAN_Transmit(CAN1, &TxMessage);    
  i=0; 
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;        //等待发送结束 
  if(i>=0XFFF)return 1; 
  return 0;                 
 
} 
 
 
//***************************************************************************** 
//功能:读取CAN数据. 
//***************************************************************************** 
u8 CAN1_RX(u8 *Buf) 
{ 
        CanRxMsg RxMe; 
        u8 i; 
         
        if (CAN_MessagePending(CAN1,CAN_FIFO0)==0) 
        { 
                return(0); 
        } 
        CAN_Receive(CAN1,CAN_FIFO0,&RxMe); 
        for(i=0;i<RxMe.DLC;i++) 
  { 
                *Buf=RxMe.Data[i]; 
                Buf++; 
  } 
        return(RxMe.DLC); 
} 
 
int main(void) 
{  
 
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 
        delay_init(168);    //初始化延时函数 
        a1=1; 
        a1=CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_Normal);//CAN初始化正常模式,波特率500Kbps             
//        a2=CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);//CAN初始化环回模式,波特率500Kbps             
//   注释a1,不注释a2.环回模式下CAN1正常发送数据,但无法接收;注释a2,正常模式下CAN1发送16次8位的单个字节以后直接摆烂,仿真里面怎么跑,逻辑分析仪也没反应了  
while(1) 
        { 
                 
                a1=CAN1_Send_Msg(1,da,8); 
                delay_ms(10); 
                a1=CAN1_RX(db); 
                delay_ms(10); 
                a1=1; 
                delay_ms(10); 
        }  
         
} 
 
//end 
 
 |   
 
 
最佳答案
查看完整内容[请看2#楼] 
行了,已解决。
答案是在我不熟悉407的io口工作模式。这是407的io口设置和103的不同之处。
stm32f103xx的io口,只能在“推挽”“浮空”“开漏”“复用推挽”等等8个中选一个。
stm32f407xx的io口,却能在选择“复用”和“普通模式下”,再选择“推挽”/“开漏”和“浮空”/“上拉”/“下拉”里面选2个。也就是可以既选“推挽”又选“上拉”。
也就是407代码里面的:
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    ... 
 
 
 
 
 
 
 |