【蓝桥杯嵌入式】【HAL库】三、SysTick定时器控制LED

原理图、实现功能分析

LED原理图,第一节已经介绍,在此不再叙述。

在这里插入图片描述
我们这次要通过SysTick定时器实现每500ms,8个LED依次点亮。

STM32CubeMX配置

GPIO配置:
在这里插入图片描述

时钟配置:
在这里插入图片描述
系统时钟配置:
在这里插入图片描述
我们可以看到,系统自动以Systick定时器作为系统时钟来源,我们也可以变为其他的定时器如:TIM1,在此我们使用Systick。
时钟数配置:
注:我们一般全都是使用最高频率,关于定时器的分频后续会涉及,但我们都是以最高频率进行配置的,如此开发板的:80MHz
在这里插入图片描述
然后是生成工程,不再叙述。

代码

首先在main函数处打开锁存器:
在这里插入图片描述

然后就是在SysTick定时器的中断函数里编写中断程序,位置如下:
在这里插入图片描述

我们首先要知道,该中断函数多久进入一次,在这里博主直接给出大家答案:1ms进入一次!并且HAL_Delay()函数就是根据SysTick定时器进行封装的,HAL_Delay(1000)实现的功能也就是大家熟悉的一秒!底层实现代码大家自行查阅资料了解。(事实是我目前也没搞明白,呜呜呜,等明白了再补充在这)

中断函数代码:
解析已经在注释写的很明白辽。

unsigned int count = 0;//用来记录进入中断的次数
unsigned char i = 8;   //寄存器数据的移动位数
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	count++;//每进入一次中断加一
	if(count == 500)//中断记满500次,也就是500ms
	{
		GPIOC->ODR = ~(0x0001 << i);//将16位数据向左移i位,移动的位数8~15对应LD1~LD8,因为led是低电平点亮,要进行取反操作
		i++;
		count = 0;//计数器清零,重新计数
		
		if(i == 16)//已经到LD8了,重新回到LD1,因为移位后又进行了一次i++,所以对应的最终值是15+1
		{
			i = 8;
		}
	}
  /* USER CODE END SysTick_IRQn 1 */
}

代码中是通过对寄存器操作来实现点灯的,需要查阅数据手册。额…我这是参考的例程,所以我也没查(懒狗一个),不过也可以用函数来实现,直接if判断i的值,然后选择要点哪个灯就行了。

版权声明:本文为CSDN博主「学不会又咋了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/FORWARDGOOD/article/details/122598885

原理图、实现功能分析

LED原理图,第一节已经介绍,在此不再叙述。

在这里插入图片描述
我们这次要通过SysTick定时器实现每500ms,8个LED依次点亮。

STM32CubeMX配置

GPIO配置:
在这里插入图片描述

时钟配置:
在这里插入图片描述
系统时钟配置:
在这里插入图片描述
我们可以看到,系统自动以Systick定时器作为系统时钟来源,我们也可以变为其他的定时器如:TIM1,在此我们使用Systick。
时钟数配置:
注:我们一般全都是使用最高频率,关于定时器的分频后续会涉及,但我们都是以最高频率进行配置的,如此开发板的:80MHz
在这里插入图片描述
然后是生成工程,不再叙述。

代码

首先在main函数处打开锁存器:
在这里插入图片描述

然后就是在SysTick定时器的中断函数里编写中断程序,位置如下:
在这里插入图片描述

我们首先要知道,该中断函数多久进入一次,在这里博主直接给出大家答案:1ms进入一次!并且HAL_Delay()函数就是根据SysTick定时器进行封装的,HAL_Delay(1000)实现的功能也就是大家熟悉的一秒!底层实现代码大家自行查阅资料了解。(事实是我目前也没搞明白,呜呜呜,等明白了再补充在这)

中断函数代码:
解析已经在注释写的很明白辽。

unsigned int count = 0;//用来记录进入中断的次数
unsigned char i = 8;   //寄存器数据的移动位数
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	count++;//每进入一次中断加一
	if(count == 500)//中断记满500次,也就是500ms
	{
		GPIOC->ODR = ~(0x0001 << i);//将16位数据向左移i位,移动的位数8~15对应LD1~LD8,因为led是低电平点亮,要进行取反操作
		i++;
		count = 0;//计数器清零,重新计数
		
		if(i == 16)//已经到LD8了,重新回到LD1,因为移位后又进行了一次i++,所以对应的最终值是15+1
		{
			i = 8;
		}
	}
  /* USER CODE END SysTick_IRQn 1 */
}

代码中是通过对寄存器操作来实现点灯的,需要查阅数据手册。额…我这是参考的例程,所以我也没查(懒狗一个),不过也可以用函数来实现,直接if判断i的值,然后选择要点哪个灯就行了。

版权声明:本文为CSDN博主「学不会又咋了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/FORWARDGOOD/article/details/122598885

生成海报
点赞 0

学不会又咋了

我还没有学会写个人说明!

暂无评论

相关推荐

蓝桥杯STM32G431——普通输入捕获模式测量PWM频率

输入捕获 输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输入信号的脉宽和测量 PWM 输入信号的频率和占空比这两种 输入捕获分为普通输入捕获模式和PWM输入模式 输入捕获的两大核心功能