【STM32】F103学习笔记:SysTick

SysTick简介、功能框图讲解、SysTick定时实验讲解  
	SysTick:系统滴答定时器,24位,只能递减,存在于内核中,嵌套在NVIC中,所有的Cortex-M内核的单片机都具有这个定时器。
			(内核中的外设)
			
	功能框图:STK_CLK(72M/9M)  -》STK_VAL递减计数器  
									^
									|
								STK_LOAD重装载寄存器
	
			 递减计数器counter在时钟的驱动下,从reload初值开始往下递减计数到0,
			产生中断和置位COUNTFLAG标志了然后又从reload值开始重新递减,如此循环。

	SysTick中的几个寄存器:
		SysTick控制及状态寄存器CTRL:
		位段	名称			类型	复位值	描述
		16		COUNTFLAG		R/W		0		如果上次读取本寄存器后,SysTick已经到了0,则该位位1
		2       CLKSOURCE 		R/W		0		时钟源选择位,0=AHB/8,1=处理器时钟AHB72M
		(就是说,SysTick的CTRL寄存器中的第16位,如果为1,说明上次读取数值后Systick有到了0了,完成一次tick滴答了)
		
		SysTick重装载数值寄存器LOAD:
		位段	名称			类型	复位值	描述
		23:0	RELOAD			R/W		0		当倒数计数至0,将被重新装载赋值

		SysTick当前数值寄存器VAL:
		位段	名称			类型	复位值	描述
		23:0	CURRENT			R/W		0		读取时返回当前倒计数的值,写它则是指清零

	Systick定时时间计算:
		1-t:一个计数循环时间,跟reload和CLK有关
		2-CLK:72M或者9M,由CTRL寄存器配置
		3-RELOAD:24位,用户自己配置
			t=reload*(1/clk)
			clk=72M 时,t=72 * (1/72M) = 1us  微妙
			clk=72M 时,t=7200 * (1/72M) = 1ms 毫秒
			
			1s = 10^3ms = 10^6us = 10^9ns

	SysTick属于内核的外设,它的中断优先级和片上的外设的中断优先级相比,哪一个高?
	答:根据中断向量表查看中断优先级;
		中断优先级的分组队内核和外设同样适用。当比较的时候,
		只需要把内核外设的中断优先级的四个位按照外设的中断优先级来
		分组即可,即人为的分出【抢占优先级】和【子优先级】


	实验:编写微秒级的延时函数 LED闪烁

		固件库函数:
			/**
			 * @brief  Initialize and start the SysTick counter and its interrupt.
			 *	简述:初始化并且开启系统滴答定时器及其中断
			 * @param   ticks   number of ticks between two interrupts
				参数:  ticks :两次中断的滴答数
			 * @return  1 = failed, 0 = successful
			    返回值:1=失败,0=成功
			 *
			 * Initialise the system tick timer and its interrupt and start the
			 * system tick timer / counter in free running mode to generate 
			 * periodical interrupts.
				初始化系统计时器及其中断,并在自由运行模式下
				启动系统计时计时器/计数器,以生成周期性中断
			 */
			static __INLINE uint32_t SysTick_Config(uint32_t ticks)
			{ 
			  //判断tick的值是否大于2^24,如果大于,则不符合规则
			  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
				
			  //初始化reload寄存器的值
			  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
			  
			  //配置中断优先级,配置为15,默认为最底的优先级
			  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
			  
			  //初始化counter的值为0
			  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
			  
			  //配置systick的时钟为72M;使能中断;使能systick开始计数
			  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
							   SysTick_CTRL_TICKINT_Msk   | 
							   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
			  return (0);                                                  /* Function successful */
			}
			
		自己编写函数:
			/*
			* param:us:微妙数,us=1000,则该函数产生一个1000us的延时
			*/
			void SysTick_Delay_us(uint32_t us)
			{
				uint32_t i;
				SysTick_Config(72);
				
				for(i = 0 ;i < us;i++)
				{
					//counter会从reload的值下减到0
					//当计数器的值减小到0的时候,CTRL寄存器的16位会置1,
					//循环判断SysTick的CTRL的16位是否为1 ,如果是,则说明达到1微妙,跳出循环
					while(  !((SysTick->CTRL) & (1<<16))   );
				}
				
				//跳出循环说明时间到,SysTick清零
				SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
			}
发布了89 篇原创文章 · 获赞 68 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zDavid_2018/article/details/103783160
今日推荐