3、Proteus仿真STM32定时器TIM2与中断来控制流水灯的定时闪烁。

一、实验说明
本次实验建立在上两次实验上,稍加修改,通过TIM2定时器中断控制LED流水灯的闪烁时间,并且增加两个按键PA1、PA2,其中PA1控制LED流水灯的启动,8个灯先依次闪烁,时间间隔1s,然后8个灯同时闪烁且时间间隔1s,PA2控制停止,使定时器不工作,将灯保持现在状态,过程非常简单,只需几分钟搞懂。(附加上两次实验链接:
实验一中keil和Proteus所有工程文件,百度网盘链接提取码:wig1

实验1:Proteus仿真STM32流水灯实验例程、详细步骤
实验2:Proteus仿真STM32外部EXTI中断、按键中断控制led流水灯的亮灭。

公众号:希望招聘(专为大学生毕业求职而用)
在这里插入图片描述

在这里插入图片描述
二、在Proteus中配置实验所需器件
1.Proteus配置中我们就不细讲,只讲添加配置原件,具体过程自己实现,因为前两次课程大家已经非常熟悉的会用proteus了,还不熟悉的可以回看前面的实验。
2.在二次实验基础上增加以下原件,如下图所示。(增加了电源power,点击左边中断模式,然后选择power,添加到原理图中)
在这里插入图片描述
3.自己配置好以上的原理图就可以了,非常简单,下面我主要讲解代码原理,和proteus的一个小bug。
三、keil中配置代码
1.在第一次试验流水灯的基础上不需要添加任何东西,和试验二一样只是修改某部分,打开第一次实验的main.c文件,并删除main.c中的内容,将以下代码拷贝进去。(手机端可能看到的代码不全,但都在代码框中,点击进去就好)

#include "stm32f10x.h"

GPIO_InitTypeDef   GPIO_InitStructure;
EXTI_InitTypeDef   EXTI_InitStructure;
NVIC_InitTypeDef   NVIC_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

void TIM2_Config(void);//定时器TIM2配置函数
void EXTI1_EXTI2_Config(void);//按键PA1、PA2中断配置函数

int main(void)
{	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_2|	GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);

	TIM2_Config();
 	EXTI1_EXTI2_Config();
 	GPIOC->ODR=0x00ff;
 	while (1)
 	{
 	}
}
void TIM2_Config(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//proteus中的bug,用其他定时器,必须先使能TIM1。
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_TimeBaseStructure.TIM_Period = 10000;//基准为0.1ms,所以设置10000,刚好0.1ms乘以10000为1s。
	TIM_TimeBaseStructure.TIM_Prescaler = 799;//我们设置的proteus中系统时钟为8M,所以这里设置799,我们时间间隔为1s。
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	// TIM_Cmd(TIM2, ENABLE);不是使能TIM2,因为用中断,所以在PA1、PA2中断函数中分别使能和不使能。
	
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//定时器中断使能。
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}
void EXTI1_EXTI2_Config(void)
{	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line1|EXTI_Line2;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);	
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

2.选中stm32f10x_it.c文件并打开,删除stm32f10x_it.c文件所有内容,将以下代码复制进去即可。
在这里插入图片描述

#include "stm32f10x_it.h"
uint32_t i=0,j=0;
void TIM2_IRQHandler(void)
{
	if(i<8)
	{
	     if((TIM2->SR&0x0001)==0x0001)
	  {
	   TIM2->SR&=0x0000;
	   GPIOC->ODR=~(1<<i);
	   i++;
	  }
	}
	else
	{
		if(j==0)
		GPIOC->ODR=0x0000;
		if(j<16)
		{
			if((TIM2->SR&0x0001)==0x0001)
			{
		 	TIM2->SR&=0x0000;
		 	GPIOC->ODR^=0x00ff;
			j++;
			}
		}
		else
		{
	 		i=0;
			j=0;
		}
	 }
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1) != RESET)
	{
		EXTI_ClearITPendingBit(EXTI_Line1);
		TIM_Cmd(TIM2, ENABLE);
	}
}
void EXTI2_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line2) != RESET)
	{
		EXTI_ClearITPendingBit(EXTI_Line2);
		TIM_Cmd(TIM2, DISABLE);
	}
}
	

三、实验结果
1.点击左下角第一个图标运行,未点击按键时,8个灯都熄灭,如下图所示。
在这里插入图片描述
2.点击最上面的按键后,启动流水灯工作,8个led灯依次闪烁,其后8个led灯同时闪烁8次,如下图所示,并且从图中左下角可以看出时间和灯的变换,明显是一秒闪一次,大家可以在自己的电脑上运行,观察实验结果。(电脑抓屏1s时间太短,如下图)
在这里插入图片描述
在这里插入图片描述
3.点击最下面的按键后,停止流水灯工作,8个led灯不工作(不闪烁),保持原来状态(亮为亮,灭为灭)如下图,一直保持亮的状态。
在这里插入图片描述四、公众号:希望招聘
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46136508/article/details/105954758