STM32F103 SysTick 系统嘀嗒时钟学习(二)

        通过上次学习我们实现了利用SysTick延时一段时间的Delay函数,并利用该函数实现了LED间隔1秒闪烁功能,实现Delay函数时其实是程序在不间断的查询计数标志位COUNTFLAG,这样处理器就无法干别的工作, 例如让2颗LED以不同的频率闪烁,利用Delay函数就无法实现。

        针对这个问题我们可以利用SysTick异常中断请求来实现,在SysTick 异常中断服务函数中对进入中断的次数进行累加,由于进入中断的时间是可以精确控制的(例如每间隔1毫秒进入一次SysTic异常中断),这样通过中断次数我们得到了精确的时间控制。具体实现方法如下:

配置SysTick相关参数:

SysTick_Config(SystemCoreClock/1000); //配置为1ms定时,开启SysTick中断,时钟源为AHB,计数使能

定义system_tick 来记录进入中断的次数或时间,定义tick_start来记录每次切换LED状态的时刻,首先让我们来实现1颗LED 以1秒的间隔闪烁。

static uint32_t system_tick;
static uint32_t tick_start;
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//配置时钟RCC
	GPIO_InitTypeDef GPIO_InitStructure;                	//定义GPIO初始化结构体
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    	//定义GPIO模式为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;   	//定义引脚
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;    	//定义速度
	GPIO_Init(GPIOA,&GPIO_InitStructure); 					//GPIOA初始化

	SysTick_Config(SystemCoreClock/1000);                   //配置SysTick相关参数

	while(1)
	{
        if(system_tick-tick_start>1000)    //判断自上次LED切换状态后时间是否超过1秒
	    {
		    tick_start=system_tick;        //每次超过1秒后更新tick_start的值
		    GPIO_WriteBit(GPIOA,GPIO_Pin_1,!(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)));
                                           //翻转输出电平
        } 
    }
}

//SysTick中断服务函数,需要先在stm32f10x_it.c文件中将void SysTick_Handler(void)函数注释掉避免重复定义
void SysTick_Handler(void)
{
	system_tick++;                     //每间隔1毫秒system_tick加1
}

要让第2颗LED以1.5秒间隔闪烁的话,只需再次定义一个变量记录第二个LED切换状态的时刻即可

程序如下:

static uint32_t system_tick;
static uint32_t tick_start;     //LED1状态切换间隔时间计时
static uint32_t tick_start2;    //LED2状态切换间隔时间计时
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//配置时钟RCC
	GPIO_InitTypeDef GPIO_InitStructure;                	//定义GPIO初始化结构体
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    	//定义GPIO模式为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;   	//定义引脚
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;    	//定义速度
	GPIO_Init(GPIOA,&GPIO_InitStructure); 					//GPIOA初始化

	SysTick_Config(SystemCoreClock/1000);                   //配置SysTick相关参数

	while(1)
	{
        if(system_tick-tick_start>1000)    //判断自上次LED切换状态后时间是否超过1秒
	    {
		    tick_start=system_tick;        //每次超过1秒后更新tick_start的值
		    GPIO_WriteBit(GPIOA,GPIO_Pin_1,!(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)));
                                           //翻转输出电平
        } 
        if(system_tick-tick_start2>1500)   //LED2以间隔1.5秒的时间闪烁
		{
			tick_start2=system_tick;
			GPIO_WriteBit(GPIOA,GPIO_Pin_0,!(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)));
		}
    }
}

//SysTick中断服务函数,需要先在stm32f10x_it.c文件中将void SysTick_Handler(void)函数注释掉避免重复定义
void SysTick_Handler(void)
{
	system_tick++;                     //每间隔1毫秒system_tick加1
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值