[5]SWM181-使用定时器

一个单片机控制系统开发应该需要有一个时间基准,我们现在看看定时器怎么使用。
通过手册可以看出,SWM181内部的定时器情况应该如下:
①1个24位系统滴答定时器
②4个通用32位定时器
③一个32位计数器
-----------------------------------------------------------------
        按老套路来走,定时器的使用流程,一般是这样:
(1)设置定时器内部计数器的时钟源
(2)设置计数器的计数方式:自加/自减
(3)设置计数器的装载缓冲器(初值):
(4)使能溢出(自加)/置零(自减)中断
(5)使能定时器运行
-----------------------------------------------------------------
看看官方例程代码是怎么初始化系统滴答定时器的:
官方的库函数配置方法就一行代码:

SysTick_Config(SystemCoreClock/4);			//每0.25秒钟触发一次中断

对应的系统滴答定时器中断代码,只需要写成以下格式便可:

void SysTick_Handler(void)
{	
	//代码
}

-----------------------------------------------------------------
问:上面这行代码为什么这样配置就可以得到"每0.25s触发一次中断"的效果呢?
        我们需要了解系统滴答定时器的输入时钟源是什么?系统滴答定时器位于M0架构内部,跟我们这款MCU的外设设计无关,想要知道具体情况,应该翻阅M0架构的相关文档。暂且不做讨论。
我们追踪代码可以得知:

#define __HSI		(24000000UL)		//高速内部时钟
uint32_t SystemCoreClock  = __HSI;
SysTick_Config(SystemCoreClock/4);          //每0.25秒钟触发一次中断
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */

  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}

从代码可以看出,ticks就是定时器初值。
而且翻阅手册,得知:SysTick定时器是一个24位自减定时器。
我们只需要将(SystemCoreClock/4)再除以250,应该就可以将系统滴答定时器,配置为1ms触发一次中断。代码如下:

SysTick_Config(SystemCoreClock/4/250);			//每1ms钟触发一次中断

中断服务程序里面放一个变量累加:

u32 gSysTick=0;       //32位可以描述49天,若非项目要求,推荐使用32位,效率较高
void SysTick_Handler(void)
{	
        gSysTick++;        	
}

编写一个函数用于获取系统滴答值。

#define SysTick_t  u64
SysTick_t GetSysTick(void)
{
	SysTick_t temp=0;
	/*关中断*/
	SysTick->CTRL &= ~(1<<1); 
	temp = gSysTick;
	/*开中断*/
	SysTick->CTRL |=  (1<<1);
	return temp;
}

定义一下系统滴答的参数结构:

typedef struct{
	SysTick_t Diff;      //时间差
	SysTick_t Old;      //旧的滴答值
	SysTick_t New;    //新的滴答值
}TimeOut_t;

某些平台申请的变量,默认值非0,我们编写一个函数用于初始化这个结构。

/*--初始化软超时结构---------------------*/
void TimeOutArgsInit(TimeOut_t *tTimeOut)
{
	tTimeOut->Diff = 0;
	tTimeOut->New = 0;
	tTimeOut->Old = 0;
}

这种结构,在使用单片机写裸机状态机程序时,非常好用。结构分明,具体后面再说。

基本框架已经定好了,忽然觉得24MHz是否有点慢了,修改工作频率,只需要修改这行代码即可。

#define SYS_CLK   	SYS_CLK_48MHz

然后官方的库函数会帮我们进行时钟初始化。
切记,千万不要修改下面三个宏,这三个宏,应该是定死的参数,官方库函数用的,如果变动,可能很多地方需要修改。

/*以下三个参数应该是不需要修改的,作为掩码一样使用,勿动*/
#define __HSI		(24000000UL)		//高速内部时钟
#define __LSI		(   32000UL)		//低速内部时钟
#define __HSE		(24000000UL)		//高速外部时钟

我们只需要使用以上结构,就可以提供一个软定时器,工程开发就很方便了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值