常用初始化配置函数(不定期更新)

!!!ATTENTION:若要使LSI作为主时钟源,需要让选项字节位LSI_EN为1.
可通过修改Option Byte的配置来使能LSI时钟 (将LSI_EN位设置为LSI Clock available as CPU clock source);也可以设置相关寄存器实现主时钟源在HSI和LSI之间切换,需要注意的是在设置切换到LSI时要置位LSI_EN来使能切换,要设置前还需要解除选项字节写保护,并且还要使能OPT写操作。在设置好LSI_EN这一位后,还要恢复选项字节写保护。

void SET_LSI_EN(void)
{
	if(*(unsigned char*)0x4805!=0x08)//判断LSI_EN是否为1,不是1则将其置1
	{
		FLASH->DUKR=0xAE;
		FLASH->DUKR=0x56;//解除选项字节写保护
		while(!(FLASH->IAPSR&0x08));//等待解除成功
		FLASH->CR2=0x80;
		FLASH->NCR2=0x7f;//使能OPT写操作
		*(unsigned char*)0x4805=0x08;
		*(unsigned char*)0x4806=0xf7;//置位LSI_EN
		FLASH_IAPSR&=~0x08;
	}

//*********************************************************************************************
//函数功能:自动切换时钟源
//入口参数: 无
//返 回:无
//备 注:先判断当前时钟源后再执行自动转换
//*********************************************************************************************

void AUTO_CLOCK_SWITCH_CONFIG(void)
{
	if(CLK_GetSYSCLKSource()!=CLK_SOURCE_HSE)
	{
		while(CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO,//选择自动切换模式
								CLK_SOURCE_HSE,//切换时钟源为HSE
								DISABLE,//关闭切换中断
								CLK_CURRENTCLOCKSTATE_ENABLE)切换到时钟源后继续开启旧时钟源
								==ERROR);//等待自动切换成功
	}

//*********************************************************************************************
//函数功能:手动切换时钟源
//入口参数: 无
//返 回:无
//备 注:使能切换中断,当目标时钟震荡稳定后,切换条件成熟,产生中断,
在中断中使能切换控制位,主函数记得开总中断
//*********************************************************************************************

void HAND_CLOCK_SWITCH_CONFIG(void)
{
	CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL,//选择手动切换模式
        CLK_SOURCE_HSE,//切换时钟源为HSE
        ENABLE,//开启切换中断
        CLK_CURRENTCLOCKSTATE_ENABLE);//切换到时钟源后继续开启旧时钟源
 }

//中断函数
INTERRUPT_HANDLER(CLK_IRQHandler,2)
{
	CLK_ClearITPendingBit(CLK_IT_SWIF);//清除中断标志位
	CLK_ClockSwitchCmd(ENABLE);//使能切换标志位,完成切换
}

//*********************************************************************************************
//函数功能:写中断的步骤
//入口参数: 无
//返 回:无
//备 注:1、设置触发方式 2、设置中断优先级 3、设置I/O口引脚配置(所有用到的引脚,包括普通I/O口和中断触发引脚)4、开总中断(此处没有设置中断优先级,默认软件优先级为3)
//*********************************************************************************************

void EXTI_CONFIG(void)
{
	EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOA,EXTI_SENSITIVITY_FALL_ONLY);//I/O口A仅下降沿触发
	GPIO_Init(实际用到的端口设置);
	rim();//开总中断
}

!!!ATTENTION:在中断函数里面关闭中断,即执行asm(“SIM”)是无效的,要关闭中断可直接关闭I/O口的中断功能,即CR2相关寄存器的值写0.(PB_CR2&=~(1<<6))

//*********************************************************************************************
//函数功能:Timer1初始化配置函数
//入口参数: 无
//返 回:无
//备 注:配置八分频,向上计数,每次t
//**********************************************************************************************

void Tim1_Init()
{
  TIM1_DeInit();
  TIM1_TimeBaseInit(0x0007,TIM1_COUNTERMODE_UP,100,0x00);//八分频,t=(8/2MHz)*100,100是溢出值
  TIM1_ARRPreloadConfig(ENABLE);//使能自动重装
  TIM1_SetCounter(0x0);//设置TMI1计数器寄存器的值(初装置值)
  TIM1_ITConfig(TIM1_IT_UPDATE , ENABLE);//数据更新中断及使能
  TIM1_Cmd(ENABLE);//开定时器
}

//************************************************************************************************
//函数功能:TIM1 测量占空比跟频率的初始化函数
//入口参数: 无
//返 回:无
//备 注:
//************************************************************************************************



void Tim1_INIT(void)
{ 
	TIM1_DeInit(); 
	TIM1_PWMIConfig(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING,
	TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x00);
	TIM1_SelectInputTrigger(TIM1_TS_TI1FP1);//选择触发信号
	TIM1_SelectSlaveMode(TIM1_SLAVEMODE_RESET);//复位触发
	TIM1_ClearFlag(TIM1_FLAG_CC1);                         //指定要清除的标志
	TIM1_ClearFlag(TIM1_FLAG_CC2);                         //指定要清除的标志
	TIM1_UpdateRequestConfig(TIM1_UPDATESOURCE_REGULAR);//设置产生中断的条件 
	TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);//使能更新中断
	TIM1_ITConfig(TIM1_IT_CC1, ENABLE);
	TIM1_ITConfig(TIM1_IT_CC2, ENABLE);
	TIM1_CCxCmd(TIM1_CHANNEL_1, ENABLE);                   //使能输入捕获通道1 
	TIM1_CCxCmd(TIM1_CHANNEL_2, ENABLE);                   //使能输入捕获通道2
	TIM1_Cmd(ENABLE);//开TIM1
}

//************************************************************************************************
//函数功能:TIM2 PWM输出波形
//入口参数: 无
//返 回:无
//备 注:输出波形频率为1KHz(16MHz/16)/(999+1)=1KHz
//************************************************************************************************

void Timer2_PWM_Output(void)//输出频率为1kHz,占空比为75%的方波
{
	TIM2_DeInit(); 
	TIM2_TimeBaseInit(TIM2_PRESCALER_16, 999);//(此处的主时钟为16MHz)预分频为16,自动装载值为999
	 //PWM模式1,启用输出比较,脉冲宽度为750,输出比较极性为高电平
	TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 750,TIM2_OCPOLARITY_HIGH);
	TIM2_OC1PreloadConfig(ENABLE); //输出比较1预装载使能
	TIM2_ARRPreloadConfig(ENABLE);//允许自动预装载
	TIM2_Cmd(ENABLE);  //开定时器2
}

//************************************************************************************************
//函数功能:SPI通信初始化配置函数
//入口参数: 无
//返 回:无
//备 注:无
//************************************************************************************************

void SPI_Config(void)
{
	SPI_DeInit();//恢复SPI寄存器到默认值
	/*SPI初始化:	高位在前;
			波特率为主时钟的1/2;
			主机模式;
			空闲状态时SCK保持低电平;
			数据采样从第一个时钟边沿开始;
			双线单向数据模式;
			禁止软件从设备管理;
			CRC多项式*/
	SPI_Init(	SPI_FIRSTBIT_MSB,
 			SPI_BAUDRATEPRESCALER_2,
 			SPI_MODE_MASTER,
 			SPI_CLOCKPOLARITY_LOW,
 			SPI_CLOCKPHASE_1EDGE,
 			SPI_DATADIRECTION_2LINES_FULLDUPLEX,
 			SPI_NSS_SOFT,
 			0x00);
	SPI_ITConfig(SPI_IT_TXE, ENABLE);
	SPI_Cmd(ENABLE);
}

//*************************************************************************************************
//函数功能:串口初始化配置函数
//入口参数: 无
//返 回:无
//备 注:此处没有配置fmaster,默认为8分频的HSI(2MHz)
//***********************************************************************************************

void UART1_Config(void)
{
	CLK_DeInit();//恢复默认设置
	UART1_Init((u32)9600,//设置波特率为9600
			 UART1_WORDLENGTH_8D,//8位数据位
			 UART1_STOPBITS_2,//2位停止位
			 UART1_PARITY_NO,//无奇偶校验
			 UART1_SYNCMODE_CLOCK_DISABLE, //禁用同步模式
			 UART1_MODE_TXRX_ENABLE//发送接收使能
			 );
	UART1_Cmd(DISABLE);//启用UART1
}

//*****************************************************************************************************
//函数功能:打印函数重定向
//入口参数: putchar的参数是待发送的字节c
//返 回:一个字符c
//备 注:重定向后可直接使用PRINTF,GETCHAR等函数进行通信
!!!使用前一定要在main()中进行初始化,int getchar(void);int putchar(int c);
//******************************************************************************************************

int getchar(void)
{
       int c=0;
       /*等待读缓冲区非空标志置一(RxNE==1)*/
       while(UART1_GetFlagStatus(UART1_FLAG_RXNE)==RESET);
       c=UART1_ReceiveData8();
       return(c);

}

int putchar(int c)
{
       /*向UART1写入一个字节*/
       UART1_SendData8(c);
       /*等待发送缓冲区空标志置一(TxE==1)*/
       while(UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET);
       return(c);
}

//*******************************************************************************************************
//函数功能:I2C初始化
//入口参数: 无
//返 回:无
//备 注:
//*******************************************************************************************************

void I2C_Config(void)
{
	/*1、设置时钟*/
	CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C,ENABLE);//启用I2C外围时钟
	/*2、初始化I2C*/
	I2C_Init(100000,		      //通信速度(Hz)范围在100k~400k之间
			0xA0,		     //本机地址
			I2C_DUTYCYCLE_2,    //快速模式下时钟信号的占空比(1/2或9/16,此处是1/2)
			I2C_ACK_CURR,	   //应答方式(此处是本次数据应答)
			I2C_ADDMODE_7BIT, //7位从机地址模式
			16               //I2C输入时钟频率(MHz)
			);
	/*3、开启中断*/
	I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_EVT|I2C_IT_BUF),ENABLE);//开启I2C缓冲和事件中断
}

在这里插入图片描述

//*********************************************************************************************
//函数功能:独立看门狗初始化
//入口参数: 无
//返 回:无
//备 注:250ms后喂狗,LSI控制
//********************************************************************************************

static void IWDG_Config(void)
{
	//需要硬件启动LSI时钟
	AccessCmd(IWDG_WriteAccess_Enable);//使能IWDG_PR和IWDG_RLR写操作
	IWDG_SetPrescaler(IWDG_Prescaler_128);//对LSI时钟128分频
  	/*250ms后喂狗需要设置的数值
  	Counter Reload Value = 250ms/IWDG counter clock period
                         	    = 250ms /(1/ (LSI/128))
                         	    = 0.25s /(1/(LsiFreq/128))
                         	    =lsiFreq/(128 *4)
                         	    =lsiFreq/512     */
	IWDG_SetReload((uint8_t)(LsiFreq/512));//设置重载值,250ms后重载
	IWDG_ReloadCounter();//重载计数器
	IWDG_Enable();//启动独立看门狗
}

//********************************************************************************************************
//函数功能:窗口看门狗初始化
//入口参数: 无
//返 回:无
//备 注:0到43.008ms内喂狗失败,43.008~2519ms喂狗成功,主时钟HSI八分频(2MHz)控制
//*********************************************************************************************************


static void WWDG_Config(void) 
{
  /*
	WWDG configuration: WWDG is clocked by SYSCLK = 2MHz */
	CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);//对HSI进行八分频
  /*
	WWDG timeout is equal to 251,9 ms */
 /*
	Watchdog Window = (COUNTER_INIT - 63) * 1 step
                        = 41 * (12288 / 2Mhz)
                        = 251,9 ms
  */
  /*
	Non Allowed Window = (COUNTER_INIT - WINDOW_VALUE) * 1 step
                       			   = (104 - 97) * 1 step
                       		 	   =  7 * 1 step 
                       			   =  7 * (12288 / 2Mhz) 
                       			   =  43.008 ms
   */
  /*
	在0~43.008ms之间喂狗,则喂狗失败;在43.008ms到2519ms之间喂狗则喂狗成功 */	
	WWDG_Init(COUNTER_INIT, WINDOW_VALUE);//COUNTER_INIT=104,WINDOW_VALUE=97
}

//********************************************************************************************************************
//函数功能:喂(窗口看门)狗
//入口参数: 无
//返 回:无
//备 注:0到43.008ms内喂狗失败,43.008~2519ms喂狗成功,fcpu=HSI八分频(2MHz)控制
//********************************************************************************************************************

void Refresh_WWDG_Window(void)
{
	u8 CounterValue;//计数器中的值
	/*WINDOW_INIT 窗口值  ,  COUNTER_INIT 计数器初始值*/
	CounterValue = (u8)(WWDG_GetCounter() & 0x7F);    //读取WWDR->CR中的7位计数器中的值
	if(CounterValue < WINDOW_INIT)    
	{
		WWDG_SetCounter( COUNTER_INIT);  //进行设置WWDG的计数器值,喂狗
	 }
}
	/*提前喂狗
	if(CounterValue>WINDOW_INIT)
	{	
		WWDG_SetCounter(COUNTER_INIT);//进行设置WWDG的计数器值,喂狗,提前喂狗,喂狗会失败
	}
	*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值