STMF103XX时钟选择和delay介绍

在stm32f10xx的启动文件中(startup_stm32f10x_xx.s),我们可以找到SystemInit

 跳转之后在函数最下发有一个 SetSysClock(); 

 再次跳转之后,选择对应的函数,默认为SetSysClockTo72(),因为定义了宏SYSCLK_FREQ_72MHz

 再次跳转之后: 

 在此函数中,我们需要选择时钟源,stm32f10xx默认选择外部时钟(HSE)作为时钟源,如果没有外部时钟可以根据需求修改这里

时钟源选择(公司板子没有外部晶振,所以此截图中,我选择了RCC_CR_HSION作为时钟源)

设置片上外设的时钟:

AHB不分频,APB1进行2分频,APB2进行4分频

 stm3部分时钟系统:

 最后设置:

对高速内部时钟进行2分频,然后9倍频得到36MHZ的时钟,因此需要修改宏#define SYSCLK_FREQ_72MHz 36000000

 以上即为对stm32时钟源的设置和选择

================================================================================

SYSTEM下的delay相关函数介绍:

 函数SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8)例程中介绍是选择外部时钟,个人理解为选择时钟源进行8分频,并没有什么外部时钟,从时钟系统图中可以看出,我们有两种选择,可以进行8分频也可以不进行分频 。因此我们需要进行除以8000000来得到1us的时间需要多个计数,因为我设置了36MHZ,所以/8只是取模,因此delay时间也是不准确的,如果一定要准确的delay延时,可以将时钟倍频到8的整数倍,比如40MHZ,48MHZ,之前我倍频的只有9,所有只有36MHZ,倍频的倍数从时钟系统图可以看出最大也就16倍

如果你不想分频,可以如下做(不含系统):

void delay_init()
{
	u32 reload;
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLK
	fac_us=SystemCoreClock/1000000;				//不论是否使用OS,fac_us都需要使用
	fac_ms=fac_us*1000;

    //此时fac_us=36;fac_ms=36000;
    //当使用delay_ms时,传入参数最大值为:0xFFFFFF/36000=466,如果需要更长延时,需要多次调用
    //如果时钟频率更大,能传入的参数的值就更小
}

以上对delay_init的初始化中,都是不带系统的,所以delay时间都是直接使用SysTick,但是如果我们使用了系统的话,系统的时钟节拍也是用SysTick,那么就会导致SysTick错乱,所以在存在系统的时候,SysTick中计数器值前后两次相减的值最终大于等于我们传入的参数,即得到我们需要的延时时间,因此不对SysTick进行操作,SysTick不会错乱

其中这个几个函数意思大概如下:

#define configTICK_RATE_HZ	(1000)

//fac_us:36    1us需要36个计数
//fac_ms:1     
//reload:36000000/1000=36000,也就是1ms,下方开启SYSTICK中断,reload是36000
//所以SYSTICK是一直以1ms为单位无限的循环下去,同时1ms也是作为系统的时钟节拍

//systick中断服务函数,使用ucos时用到
//开启了SYSTICK中断,这个是中断函数,在xPortSysTickHandler函数中有xTaskIncrementTick
//系统的时钟节拍变量就是一直在这个函数中累加的
void SysTick_Handler(void)
{	
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
    {
        xPortSysTickHandler();	
    }
}


void delay_init()
{
	u32 reload;
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLK
	fac_us=SystemCoreClock/1000000;				//不论是否使用OS,fac_us都需要使用
	reload=SystemCoreClock/1000000;				//每秒钟的计数次数 单位为M  
	reload*=1000000/configTICK_RATE_HZ;			//根据configTICK_RATE_HZ设定溢出时间
	fac_ms=1000/configTICK_RATE_HZ;				//代表OS可以延时的最少单位   
	SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   	//开启SYSTICK中断
	SysTick->LOAD=reload; 						//每1/configTICK_RATE_HZ秒中断一次	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   	//开启SYSTICK    
}

//当前这样设置,系统用1ms作为最小单位,也是时钟节拍这样运行
//如果我们修改了宏configTICK_RATE_HZ 100
//那么时钟节拍就变成了10ms,也是最小单位,因为进入SYSTICK中断变成了10ms才会产生
//那么在使用delay_ms(9)等小于10的参数的时候,就不会产生任务调度

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值