STM32

这篇笔记详述了在STM32F105RB上进行8M晶振配置、时钟树调整、系统时钟获取以及双CAN接口的驱动设置,包括GPIO配置、CAN初始化、NVIC中断设置和CAN发送与接收的实现。同时,强调了在调试CAN通信时硬件和软件的检查要点。
摘要由CSDN通过智能技术生成

STM32笔记—stm32F105RB 使用总结

一、硬件

stm32F105 最小系统
STM32F105RB

二、软件

1、晶振

STM32F105RB 默认晶振25M ,而在使用的过程中,我这边使用的是8M的晶振 ,所以需要修改两个地方

1)在stm32f10x.h头文件中把HSE_VALUE值修改为你实际晶振的值,例如修改为8000000;

2)在system_stmf10x.c中

#ifdef STM32F10X_CL
/* Configure PLLs ------------------------------------------------------*/
/* PLL2 configuration: PLL2CLK = (HSE / 8) * 8 = 8 MHz */
/* PREDIV1 configuration: PREDIV1CLK = PLL2 / 1 = 8 MHz */


RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                          RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
						  
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV8 | RCC_CFGR2_PLL2MUL8 |
                         RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV1);
/* Enable PLL2 */
RCC->CR |= RCC_CR_PLL2ON;
/* Wait till PLL2 is ready */
while((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}


/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
                        RCC_CFGR_PLLMULL9); 

2、stm32F105的时钟树

STM32F105时钟树

3、在程序中获取系统的时钟

只需要在int main(), 初始化时 加入两行代码就可以获取各个时钟,之后仿真打印。
需要添加的代码:

RCC_ClocksTypeDef get_rcc_clock;    //获取系统时钟状态
RCC_GetClocksFreq(&get_rcc_clock);  //仿真的时候就可以在结构体get_rcc_clock中看见各个外设的时钟了

仿真打印结果
时钟打印结果

4、stm32F105CAN 双CAN 驱动;

1、GPIO 配置

 void CAN1_PinInit(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;

 	/*外设时钟设置*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    /* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
 void CAN2_PinInit(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;
 	 	/*外设时钟设置*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
    /* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

2、双can 配置

void CAN1_Configuration(void)
{
	CAN_InitTypeDef        CAN_InitStructure;
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;

// CAN register init 
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);

// CAN cell init DISABLE=0,ENABLE=1
CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
CAN_InitStructure.CAN_ABOM=DISABLE;//自动离线恢复
CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除sleep位来唤醒
CAN_InitStructure.CAN_NART=ENABLE;//DISABLE;报文自动重传
CAN_InitStructure.CAN_RFLM=DISABLE;//接收溢出时,FIFO未锁定
CAN_InitStructure.CAN_TXFP=DISABLE;//发送的优先级由标示符的大小决定
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;//正常模式下

	//设置can通讯波特率为1000kbps
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_4tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;
CAN_InitStructure.CAN_Prescaler=4;
        
//   CAN_Mode_Init( CAN_SJW_1tq,CAN_BS2_4tq,CAN_BS2_3tq,4,0); // CAN 初始化  1M 
            
 CAN_Init(CAN1,&CAN_InitStructure);

// CAN filter init 
CAN_FilterInitStructure.CAN_FilterNumber=0;

CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;	/* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//CAN_FilterScale_16bit; //32bit
CAN_FilterInitStructure.CAN_FilterIdHigh= (((FlTA1)<<21)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow= (((FlTA1)<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0x0000;	 //
CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0x0000;    //


CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;   //时能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
	/*CAN通信中断使能*/
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

}

void CAN2_Configuration(void)
{
  // CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE);
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;

// CAN register init 
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);

// CAN cell init 
CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
CAN_InitStructure.CAN_ABOM=DISABLE;//自动离线恢复
CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除sleep位来唤醒
CAN_InitStructure.CAN_NART=ENABLE;//DISABLE;报文自动重传
CAN_InitStructure.CAN_RFLM=DISABLE;//接收溢出时,FIFO未锁定
CAN_InitStructure.CAN_TXFP=DISABLE;//发送的优先级由标示符的大小决定
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;//正常模式下

//        CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;//正常模式下	CAN_Mode_LoopBack          
	//设置can通讯波特率为1000kbps
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_4tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;
CAN_InitStructure.CAN_Prescaler=4;
	
CAN_Init(CAN2,&CAN_InitStructure);

CAN_FilterInitStructure.CAN_FilterNumber=14;  /* 过滤器14 */
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;	/* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//CAN_FilterScale_16bit; //32bit
CAN_FilterInitStructure.CAN_FilterIdHigh= ((FlTA2<<21)&0xffff0000)>>16;32位ID
CAN_FilterInitStructure.CAN_FilterIdLow= ((FlTA2<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0x0000;	 //
CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0x0000;  //
	
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO1;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;   //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);

    CAN_ITConfig(CAN2, CAN_IT_FMP1, ENABLE);
    CAN_ITConfig(CAN2,CAN_IT_TME,ENABLE);	
    CAN_ITConfig(CAN2,CAN_IT_BOF,ENABLE);

}
3、NVIC 配置

NVIC_InitTypeDef NVIC_InitStructure;
	/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 	/*中断设置*/
NVIC_InitStructure.NVIC_IRQChannel =CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
	       
NVIC_InitStructure.NVIC_IRQChannel =CAN2_RX1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

4、CAN 发送

void CAN_Send_Msg(u8* msg,u8 len)
{	
	u16 i=0;u8 mbox;
	CanTxMsg TxMessage;
	TxMessage.StdId=0x000;	 // 标准标识符为0
	TxMessage.ExtId=0x12;	 // 设置扩展标示符(29位)
	TxMessage.IDE=CAN_ID_STD;		  // 使用扩展标识符
	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));	//等待发送结束
	while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	//等待发送结束
}

5、CAN接收

	void CAN1_RX0_IRQHandler(void)
	{
		   	 if(CAN_GetITStatus(CAN1,CAN_IT_TME)!= RESET)
   		 	{
        		CAN_ClearITPendingBit(CAN1,CAN_IT_TME);
    		}	
    		CAN_Receive(CAN1, 0, &RxMessage);
	}	
			void CAN2_RX1_IRQHandler(void)
	{
		   	 if(CAN_GetITStatus(CAN2,CAN_IT_TME)!= RESET)
   		 	{
        		CAN_ClearITPendingBit(CAN2,CAN_IT_TME);
    		}	
    		CAN_Receive(CAN2, 0, &RxMessage);
	}	

在调试CAN 芯片时,需要注意
1、硬件
CAN芯片是都在工作,可以测量CAN芯片的VCC ,CANH,CANL,.
2、软件
CAN 被配置程过滤模式后,检查FlTA1、 FlTA2 设置是都对。
另外调试CAN时,尽量搭配CAN盒一块调试。

上面笔记有些内容是参考网上的一些资料,具体的详细链接已记不清了,资料仅供学习用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值