嵌入式系统 实验三 定时器中断实验

(一)通用定时器 TIM2 实验

1 实验目的

1).掌握使用 STM32 的通用定时器 TIM2 实现 1s 定时的方法;
2).掌握 STM32 的定时器的中断配置方法;
3).掌握中断方式控制流水灯的原理

2 实验环境

1). 硬件:1 个空气温湿度传感器模块、1 个 ST-Link 调试器、1 根 USB2.0 方口线、1
根 USB3.0 数据线、1 台 PC 机;
2). 软件:Windows 7/XP、MDK 集成开发环境。

3 实验功能

通过使用 STM32 的通用定时器 TIM2 中断方式控制流水灯,程序成功运行后,将可以看到 Status、RS485-R、RS485-T、User1 四个指示灯每隔约一秒的时间轮流闪烁。

4 实验步骤

1.)将 USB3.0 数据线的一端连接感知执行模块的 USB3.0 调试烧写口,另一端连接
ST-Link 调试器的“Debug”接口。
2.)将 USB2.0 方口线的一端连接 PC 机的 USB 口,另一端连接 ST-Link 调试器的
“USB-232”接口,连接正确后效果如图 4.5 所示。
3.)双击打开工程文件“STM32-Timer.uvproj”。
4.)在工具栏中点击按钮 ,编译工程成功后,信息框会出现下图所示的信息。如果
编译失败,请确认相关选项是否配置正确。
5.)确认与硬件调试有关的选项已设置正确。
6.)点击按钮 ,将程序下载到温湿度传感器模块中。下载成功后,信息框显示下图
中所示的信息,表明程序下载成功并已自动运行。

5 实验程序

#include "stm32f10x.h"  
#include "stm32f10x_it.h"
#include   
	void GPIO_init(void) // GPIO 的初始化配置  
	{  
	GPIO_InitTypeDef GPIO_InitStructure; // 定义一个 GPIO_InitTypeDef 类型的结构体  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);   
	// 开启 AFIO 时钟和 GPIOB 的外设时钟  
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // 禁用 JTAG 功能  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6|GPIO_Pin_7;  
	// 选择要控制的 GPIOB 引脚  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置引脚速率为 50MHz  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置引脚模式为通用推挽输出  
	GPIO_Init(GPIOB, &GPIO_InitStructure); // 调用库函数,初始化 GPIOB  
	}  
	void TIM2_Configuration(void)  
	{  
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 定义一个定时器初始化参数结构体  
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); // 开启 APB1 的 TIM2 外设时钟  
	TIM_DeInit(TIM2); // 复位TIM2定时器,使之进入初始状态
	TIM_TimeBaseStructure.TIM_Prescaler= (7200 - 1); // 设置预分频系数为(7200-1)  
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数模式  
	TIM_TimeBaseStructure.TIM_Period=(10000-1); // 自动加载值设置,累计 10000 个时钟周期(1s)后溢出  
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  
	// 根据 TIM_TimeBaseStructure 中指定的参数初始化 TIM2 里的相关寄存器  
	 TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除溢出中断标志  
	 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); // 使能 TIM2 中断,允许更新中断  
	 TIM_Cmd(TIM2, ENABLE); // 使能 TIM2 外设  
	}  
	void TIM2_NVIC_Configuration(void)  
	{  
	 NVIC_InitTypeDef NVIC_InitStructure; // 定义 NVIC 初始化结构体  
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 选择中断优先级分组 0  
	 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 选择配置 TIM2 全局中断  
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 占先优先级为 0  
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; // 响应优先级为 1  
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能 TIM2 中断通道  
	 NVIC_Init(&NVIC_InitStructure); // 根据以上配置初始化 NVIC  
	}  
	int main()  
	{  
	  
	 GPIO_init();  
	 GPIO_SetBits(GPIOB,GPIO_Pin_4);  
	 GPIO_SetBits(GPIOB,GPIO_Pin_5);  
	 GPIO_SetBits(GPIOB,GPIO_Pin_6);  
	 GPIO_SetBits(GPIOB,GPIO_Pin_7);  
	 TIM2_NVIC_Configuration();  
	 TIM2_Configuration();  
	while(1)  
	{ }  
	}   
	  
/*
int led_state=0;
void TIM2_IRQHandler(void)  
{  
if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) // 1S 时间到,检测到 TIM2 中断  
{  
led_state++; // 状态加 1  
switch (led_state)  
{  
case 1: // 状态 1:灭掉 User1,点亮 Status  
	GPIO_SetBits(GPIOB,GPIO_Pin_7);  
	GPIO_ResetBits(GPIOB,GPIO_Pin_4);  
	  
	break;  
	case 2: // 状态 2:灭掉 Status,点亮 RS485-R  
	  GPIO_SetBits(GPIOB,GPIO_Pin_4);  
	  GPIO_ResetBits(GPIOB,GPIO_Pin_5);  
	break;  
	case 3: // 状态 3:灭掉 RS485-R,点亮 RS485-T  
	  GPIO_SetBits(GPIOB,GPIO_Pin_5);  
	  GPIO_ResetBits(GPIOB,GPIO_Pin_6);  
	break;  
	case 4: // 状态 4:灭掉 RS485-T,点亮 User1  
	 GPIO_SetBits(GPIOB,GPIO_Pin_6);  
	  GPIO_ResetBits(GPIOB,GPIO_Pin_7);  
	led_state=0; // led_state 置 0,下个 1s 时间到后可再次进入状态 1  
	break;  
	}  
	TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); // 清除中断标志位  
	}  
	}*/
	

6 实验结果

程序成功运行后,将可以看到 Status、RS485-R、RS485-T、User1 四个指示灯每隔约
一秒的时间轮流闪烁,效果见下图。
嵌入式系统 实验三 定时器中断实验_第1张图片

嵌入式系统 实验三 定时器中断实验_第2张图片
嵌入式系统 实验三 定时器中断实验_第3张图片
嵌入式系统 实验三 定时器中断实验_第4张图片

7 实验心得

通过实验熟悉和掌握了如何使用 STM32 的通用定时器 TIM2 实现定时一定时间的功能,所要定时的时间=(计数器数值+1)*(预分频器数值+1)/脉冲频率。
知道了如何将中断服务程序写入文件"stm32f10x_it.c"中,而后在文件中"main.c"调用此程序

(二) TIM2闹钟实验

1 实验目的

1)掌握使用 STM32 的通用定时器 TIM2 实现 1s 定时的方法;
2)掌握如何使用 STM32 的串口发送和接收数据。

2 实验环境

1)硬件:1 个温湿度传感器模块、1 个 ST-Link 调试器、2 根 USB2.0 方口线、1 根 USB3.0 数据线、 1 台 PC 机;
2)软件:Windows 7/XP、MDK 集成开发环境

3 实验功能

通过调试口实现秒表功能,每秒显示一次

4 实验步骤

1)、将 USB3.0 数据线的一端连接感知执行模块的 USB3.0 调试烧写口,另一端连接
ST-Link 调试器的“Debug”接口。
2)、 将第 1 根 USB2.0 方口线的一端连接 PC 机的 USB 口,另一端连接 ST-Link 调试器的“USB-Debug”接口。
3)、将第 2 根 USB2.0 方口线的一端连接 PC 机的 USB 口,另一端连接 ST-Link 调试器的“USB-232”接口。
4)、双击打开【配套光盘\03-常用工具\01-硬件开发包\09-串口调试工具】目录下的串口
调试器,选择正确的端口号(可参照 1.2.2 查看串口端号),波特率设为 9600,其他均保
持默认设置,点击按钮“打开串口”即可,效果见下图。
5)、双击打开工程文件“STM32-USART.uvproj”。
6)、在工具栏中点击按钮,编译工程,编译成功后,信息框会出现下图所示的信息。如
果编译失败,请参照 1.2.1.2 中的内容,确认相关选项是否配置正确。

5 实验程序

 #include 
#include 
void gpio_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA和GPIOB的外设时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//PB7 User1指示灯
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置引脚速率
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//选择引脚模式为通用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure); //调用库函数初始化,初始化GPIOB
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//PA9 串口发送
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure); //调用库函数初始化,初始化GPIOA
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10;//PA10 串口接收
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void TIM2_Configuration(void) //定时器每 1s 产生一次中断
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 定义一个定时器初始化参数结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); // 开启 APB1 的 TIM2 外设时钟
TIM_DeInit(TIM2); // 将外设 TIM2 的寄存器重设为缺省值
TIM_TimeBaseStructure.TIM_Prescaler= (7200 - 1); // 设置预分频系数为(7200-1),计数器输入时钟频率为 10KHz
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数模式,,每 100μs 计一次数。
TIM_TimeBaseStructure.TIM_Period=(10000-1); // 自动加载值设置,累计 10000 个时钟周期(1s)后溢出
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 根据 TIM_TimeBaseStructure 中指定的参数初始化 TIM2 里的相关寄存器
 TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除溢出中断标志
 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); // 使能 TIM2 中断,允许更新中断
 TIM_Cmd(TIM2, ENABLE); // 使能 TIM2 外设
}
void TIM2_NVIC_Configuration(void) //中断配置
{
 NVIC_InitTypeDef NVIC_InitStructure; // 定义 NVIC 初始化结构体
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 选择中断优先级分组 0
 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 选择配置 TIM2 全局中断
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为 0
 NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; // 响应优先级为 1
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能 TIM2 中断通道
 NVIC_Init(&NVIC_InitStructure); // 根据以上配置初始化 NVIC
}
void USART1_Config(void)
{
	USART_InitTypeDef USART_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	USART_InitStructure.USART_BaudRate =115200;//波特率115200
	USART_InitStructure.USART_WordLength= USART_WordLength_8b;//1起始位,8数据位。共9位。
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//1个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//没有奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//失能CTS硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //使能Tx,Rx
	USART_Init(USART1, &USART_InitStructure);
	USART_Cmd(USART1,ENABLE);
}
int fputc(int ch,FILE* fp)//重定向函数 (把一个字符写到文件中)
{
	USART_SendData(USART1,(unsigned char) ch);  //unsigned char没有符号位,因此能表示的数据范围是0~255
	while (USART_GetFlagStatus(USART1 ,USART_FLAG_TXE) == RESET); //发送寄存器非空,循环等待 (USART_GetFlagStatus检测发送寄存器TXE是否非空)
	return (int)ch;
}
int main()
{
	 gpio_init();
	 GPIO_ResetBits(GPIOB,GPIO_Pin_7);//点亮User1指示灯
	 TIM2_Configuration(); //定时器每 1s 产生一次中断
   TIM2_NVIC_Configuration(); //中断配置
	 USART1_Config();
	 while(1){
							};
}



int sec=0,min=0,hour=0;
void TIM2_IRQHandler(void)//中断服务函数
{

if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) // 1S 时间到,检测到TIM2 中断
{
		sec++;
		if(sec==60){
		sec=0;        //秒计数
		min++;
		if(min==60){
		min=0;      //分计数
		hour++;
			}
		}
		if (USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET) // 等待 USART1 接收数据完毕 ((RXNE读数据寄存器非空)USART_GetFlagStatus检测该位是否为1)
		{
			printf("%d:%d:%d  \n",hour,min,sec);//输出时分秒
		} 
		
	}
	TIM_ClearFlag(TIM2 , TIM_FLAG_Update); //清楚中断标志位
}

6 实验结果

通过调试口实现秒表功能,每秒显示一次。


嵌入式系统 实验三 定时器中断实验_第5张图片

7 实验心得

通过TIM2配置实现闹钟,注意初始化,否则会影响结果的输出。注意局部变量的控制和NVIC的初始化。

你可能感兴趣的:(单片机,stm32,嵌入式硬件)