女生找对象要求有房:STM32CAN与SJA1000通讯问题

来源:百度文库 编辑:中财网 时间:2024/05/05 02:44:20

备注:下文中可以获得信息或者可以借鉴的地方是

(1)、void CAN_Configuration(void) 程序中详细的备注,对于CAN的部分理解有利。

 

(2)、bit   BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)       即波特率设置程序(注意这个程序是对CAN控制器SJA1000波特率设置的,不是STM32的CAN外设)。这个是可以参考的。

             

单片机STM32F103RBT6,晶振8M,另一端是89C51SJA1000(这部分程序绝对正确,我有一发一收测试了的,估计问题出在STM32这边),通讯波特率:250K

STM32这边只是发,SJA1000这边只是收。接收程序里我也取消了标识符识别(地址)。

RCC设置:

void RCC_Configuration(void)

{

    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/    

  /* RCC system reset(for debug purpose) */

RCC_DeInit();

  /* Enable HSE */

RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

    /* Enable Prefetch Buffer */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */

FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */

RCC_HCLKConfig(RCC_SYSCLK_Div1); 

    /* PCLK2 = HCLK */

RCC_PCLK2Config(RCC_HCLK_Div1); 

    /* PCLK1 = HCLK/2 */

RCC_PCLK1Config(RCC_HCLK_Div2);  // 36MZH

    /* On STICE the PLL output clock is fixed to 48 MHz */

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */ 

RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}

    /* Select PLL as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */

while(RCC_GetSYSCLKSource() != 0x08)

{

}

}

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP |

                               RCC_APB1Periph_TIM2, ENABLE);

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIO_DISCONNECT |

       RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOB, ENABLE); 

}

 

CAN的管脚配置:

 

void GPIO_Configuration(void)

{

     GPIO_InitTypeDef GPIO_InitStructure;

 

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | 

                       RCC_APB2Periph_GPIOC  | RCC_APB2Periph_GPIOD  | RCC_APB2Periph_GPIOE, ENABLE);

 

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

 

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

 

/* USB_DISCONNECT used as USB pull-up */

     GPIO_InitStructure.GPIO_Pin = USB_DISCONNECT_PIN;

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

     GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure);

  

/* Configure SPI1 pins: SCK, MISO and MOSI ---------------------------------*/

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_7;

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//AF_PP

     GPIO_Init(GPIOA, &GPIO_InitStructure);

 

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//MISO

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

     GPIO_Init(GPIOA, &GPIO_InitStructure);

     //for LED test PA3,PA2

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//GPIO_Pin_3 | GPIO_Pin_2;

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

     GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_KEY, ENABLE);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO_Mode_IPU;

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

     GPIO_Init(GPIO_KEY, &GPIO_InitStructure);

 

  /* CAN Periph clock enable */

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);

 

 /* Configure CAN pin: RX */

     ////GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

     ////GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

     ////GPIO_Init(GPIOB, &GPIO_InitStructure);

  

     /* Configure CAN pin: TX */

     ////GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

     ////GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

     ////GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 /* Configure CAN pin: RX */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

////GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;//// GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    /* Configure CAN pin: TX */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

 

}

 

 

CAN配置:

 

void CAN_Configuration(void)

{

  CAN_InitTypeDef        CAN_InitStructure;

  CAN_FilterInitTypeDef  CAN_FilterInitStructure;

 

  //CanTxMsg TxMessage;

  //CanRxMsg RxMessage;

 

  /* CAN register init */

  CAN_DeInit();

//  CAN_StructInit(&CAN_InitStructure);

 

  /* CAN cell init */

  CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式

  CAN_InitStructure.CAN_ABOM=DISABLE;//,软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测

                                                              //12811位连续的隐性位,就退出离线状态。

  CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒

  CAN_InitStructure.CAN_NART=ENABLE;//DISABLE;CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)

  CAN_InitStructure.CAN_RFLM=DISABLE;//在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有

                                                            //的报文

  CAN_InitStructure.CAN_TXFP=DISABLE;//发送FIFO优先级由报文的标识符来决定

//  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;

  CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //CAN硬件工作在正常模式 

  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位

  CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;//CAN_BS1_11tq;//CAN_BS1_8tq;//时间段18个时间单位

  CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//CAN_BS2_3tq;//CAN_BS2_7tq;//时间段27个时间单位

  CAN_InitStructure.CAN_Prescaler = 9; //(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits设定了一个时间单位的长度9

  CAN_Init(&CAN_InitStructure);

 

  /* CAN filter init 过滤器初始化*/

  CAN_FilterInitStructure.CAN_FilterNumber=0;//指定了待初始化的过滤器0

  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定了过滤器将被初始化到的模式为标识符屏蔽位模式

  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//给出了过滤器位宽132位过滤器

  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//用来设定过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个)

  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//用来设定过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个

  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个

  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个

  

   //CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)0xaa<<21)&0xFFFF0000)>>16; 

   //CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)0xaa<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF; 

   //CAN_FilterInitStructure.CAN_FilterMaskIdHigh   = 0xFFFF; 

   //CAN_FilterInitStructure.CAN_FilterMaskIdLow    = 0xFFFF;

  

  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;//设定了指向过滤器的FIFO0

  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器

  CAN_FilterInit(&CAN_FilterInitStructure);

 

 

  //TxMessage.StdId=0xaa;//11;

  //TxMessage.RTR=CAN_RTR_DATA;

  //TxMessage.IDE=CAN_ID_STD;

  //TxMessage.DLC=8;//发送数据长度

  //TxMessage.Data[0]=0x01;TxMessage.Data[1]=0x02;TxMessage.Data[2]=0x03;TxMessage.Data[3]=0x04;

  //TxMessage.Data[4]=0x05;TxMessage.Data[5]=0x06;TxMessage.Data[6]=0x07;TxMessage.Data[7]=0x08;

 

 

 

   CAN_ClearITPendingBit(CAN_IT_FMP0);

   CAN_ClearITPendingBit(CAN_IT_TME);

/* CAN FIFO0 message pending interrupt enable */ 

CAN_ITConfig(CAN_IT_FMP0, ENABLE);

 

CAN_ITConfig(CAN_IT_TME, ENABLE);

 

 

  /* CAN FIFO0 message pending interrupt enable */ 

    //CAN_ITConfig(CAN_IT_FMP0, ENABLE);//使能指定的CAN中断

 

   //CAN_Transmit(&TxMessage);

}

 

程序发送部分:

TxMessage.StdId=0x550;//11;

  TxMessage.RTR=CAN_RTR_DATA;

  TxMessage.IDE=CAN_ID_STD;

  TxMessage.DLC=8;//发送数据长度

  TxMessage.Data[0]=0x01;TxMessage.Data[1]=0x02;TxMessage.Data[2]=0x03;TxMessage.Data[3]=0x04;

  TxMessage.Data[4]=0x05;TxMessage.Data[5]=0x06;TxMessage.Data[6]=0x07;TxMessage.Data[7]=0x08;

  //CAN_Transmit(&TxMessage);

  //CAN_Transmit(&CanTxMessage); 

    TransmitMailbox=CAN_Transmit(&TxMessage);

  i = 0;

  while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK) && (i != 0xFF))

  {

    i++;

  }

  i = 0;

SJA1000设置:

 

//******************************SJA1000初始化********************//

void Sja_1000_Init(void)

{   BCAN_ENTER_RETMODEL();        //进入复位

BCAN_SET_BANDRATE(0x07);      //设置波特率250K/S

BCAN_SET_OBJECT(0xBB,0xFF);   //设置地址ID:550

BCAN_SET_OUTCLK(0xaa,0x48);   //设置输出方式,禁止COLOCKOUT输出

BCAN_QUIT_RETMODEL();         //退出复位模式

SJA_BCANAdr=REG_CONTROL;      //地址指针指向控制寄存器

*SJA_BCANAdr|=0x1e;           //开放错误\接收\发送中断

}

 

/************************************************************************

//;*函数原型:   bit   BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)       

//;*参数说明:  R7            波特率(Kbit/s BTR0     BTR1               

//;*           0             20              053H,    02FH                

//;*           1             40              087H,    0FFH                 

//;*           2             50              047H,    02FH               

//;*           3             80              083H,    0FFH                

//;*           4             100             043H,    02fH                

//;*           5             125             03H,     01cH                  

//;*           6                200             081H,    0faH               

//;*           7             250             01H,     01cH            

//;*           8             400             080H,    0faH                

//;*           9             500             00H,     01cH               

//;*           10             666             080H,    0b6H                 

//;*           11             800             00H,     016H             

//;*           12             1000            00H,     014H                  

//;*返回值:                                                               

//;*           0 ;波特率设置成功                                          

//;*           1 ;波特率设置失败                                           

//;*                                                                       

//;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ,       

//;*     其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于        

//;*     复位模式                                                            

//;************************************************************************/

unsigned  char code SJA_BTR_CODETAB[]={

    0x53,0x2F,                //;20KBPS的预设值

    0x87,0xFF,                     //;40KBPS的预设值

    0x47,0x2F,                     //;50KBPS的预设值

    0x83,0xFF,                     //;80KBPS的预设值

    0x43,0x2f,                     //;100KBPS的预设值

    0x03,0x1c,                     //;125KBPS的预设值

    0x81,0xfa,                     //;200KBPS的预设值

    0x01,0x1c,                     //;250KBPS的预设值

    0x80,0xfa,                     //;400KBPS的预设值

    0x00,0x1c,                     //;500KBPS的预设值

    0x80,0xb6,                     //;666KBPS的预设值

    0x00,0x16,                     //;800KBPS的预设值

    0x00,0x14,                      //;1000KBPS的预设值

};

 

回答1

PB8,PB9是重映射的CAN引脚。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);

回答2

非常感谢楼上!确实如此,实验已经通过了。