女生找对象要求有房: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,另一端是89C51与SJA1000(这部分程序绝对正确,我有一发一收测试了的,估计问题出在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后,一旦硬件检测
//到128次11位连续的隐性位,就退出离线状态。
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;//时间段1为8个时间单位
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//CAN_BS2_3tq;//CAN_BS2_7tq;//时间段2为7个时间单位
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;//给出了过滤器位宽1个32位过滤器
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:
非常感谢楼上!确实如此,实验已经通过了。