当前位置:   article > 正文

蓝桥杯嵌入式-HAL库-TIM_BASE_80mhz定时器1ms定时

80mhz定时器1ms定时

实验目的

通过定时器1实现间隔100ms的双向流水灯

定时器相关知识

stm32的TIM定时器HAL库函数的使用

STM32CubeMx_HAL库使用_1_定时器与串口

HAL库 STM32CubeMX教程六----定时器中断

硬件设计

原理图

在这里插入图片描述
在这里插入图片描述

STM32CubeMX配置

1、使用PC8~PC15控制LED灯亮灭,LD1 - LD8为引脚的别名
2、使用PD2控制锁存器,LEDLOCK为PD2的别名
在这里插入图片描述
3、HSE选用石英/陶瓷谐振
4、GPIO均设置为输出模式,使用默认的GPIO配置
5、时钟配置为80MHz
6、配置定时器TIM1,时钟源选择内部时钟
在这里插入图片描述
7、配置定时时间
Prescaler=1000-1
Counter Period=80-1
定时器时钟频率为80MHZ,即80 000 000HZ
定时时间 = (Prescaler+1 ) X (Counter Period+1) X 1/ 定时器时钟频率(信号的周期)
定时时间 =1000 X 80 / 80000000=0.001s=1ms
在这里插入图片描述

知识补充:
a. APB2负责AD,I/O,高级TIM,串口1。
APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM
TIM1是高级定时器,包括了基本定时器和通用定时器的所有功能。

b. HZ是赫兹,频率单位,1MHZ(兆赫)=1000KHZ(千赫)=1000000HZ

c. 定时器发生中断时间的计算方法:
定时时间 = (Prescaler+1 ) X (Counter Period+1) X 1/ 定时器时钟频率(信号的周期)
时钟信号1KHz,Prescaler为9,Counter Period为999,定时时间?
定时时间=10x1000x1/1000=10s=10000ms=10s

Keil配置

Keil配置参考ADC篇,不赘述了
Keil配置

软件设计

1、引用头文件

main.c中添加头文件。(注:所有代码放到BEGIN和END之间,防止重新生成代码时将原来的代码覆盖掉)
在这里插入图片描述

#include "lcd.h"
  • 1

2、编写定时器回调函数

在这里插入图片描述


//实现间隔为100ms的流水灯
///
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //周期运行回调,配置定时进入中断
{
	static uint16_t led = 0x0001, i = 0, flag = 0 ,counter = 0;
	
	if(++counter == 100){  //100*1ms=100ms
		counter = 0;
		GPIOC->ODR = ~(led << (8 + i)); //通过位运算设置输出端口寄存器ODR的值,从而控制LED的亮灭
		HAL_GPIO_WritePin(LEDLOCK_GPIO_Port, LEDLOCK_Pin, GPIO_PIN_SET); //打开锁存器   GPIOD->BSRR |= GPIO_PIN_2;
		__nop();__nop();__nop(); //一个__nop()函数延时一个机器周期的时间
		HAL_GPIO_WritePin(LEDLOCK_GPIO_Port, LEDLOCK_Pin, GPIO_PIN_RESET); //关闭锁存器 GPIOD->BRR |= GPIO_PIN_2;
		
	  if(flag == 0) //flag作为流水灯方向的标志位   当flag = 0时,LD1流向LD8 ; 当flag = 1时,LD8流向LD1
	  { 
		++i;
		if(i == 7){ flag = 1; }
	  }
	  else
	  {
		 --i;
		 if(i == 0){ flag = 0; }	
	  }
	}
	HAL_TIM_Base_Start_IT(&htim1);  //使能定时器1中断
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3、全灭LED灯并锁存,开启定时器1中断

在这里插入图片描述

	HAL_GPIO_WritePin(GPIOC,LD1_Pin|LD2_Pin | LD3_Pin|LD4_Pin | LD5_Pin|LD6_Pin |LD7_Pin|LD8_Pin, GPIO_PIN_SET); //LED全灭           等价于GPIOC->ODR = 0xFFFF; 
	HAL_GPIO_WritePin(LEDLOCK_GPIO_Port, LEDLOCK_Pin, GPIO_PIN_SET); //打开锁存器                等价于GPIOD->BSRR |= GPIO_PIN_2;  
	
	__nop();__nop();__nop(); //一个__nop()函数延时一个机器周期的时间         表示空循环一个机器指令的时间,STM32中1/80M=0.0125ns ;  C51中12M中表示1us;6M中表示2us;24M中表示0.5us  STM32中1/80M=0.0125ns
	HAL_GPIO_WritePin(LEDLOCK_GPIO_Port, LEDLOCK_Pin, GPIO_PIN_RESET); //关闭锁存器        等价于GPIOD->BRR |= GPIO_PIN_2; 

	HAL_TIM_Base_Start_IT(&htim1); //使能定时器1中断
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、LCD初始化及LCD相关配置、显示字符串

在这里插入图片描述

  	LCD_Init();
	
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LCD_DisplayStringLine(Line0, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line1, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line2, (uint8_t *)"      TIM Test      ");
	LCD_DisplayStringLine(Line3, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line4, (uint8_t *)"                    ");
	
	LCD_SetBackColor(White);
	LCD_SetTextColor(Blue);

	LCD_DisplayStringLine(Line5, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line6, (uint8_t *)"     TIM1:100ms     ");
	LCD_DisplayStringLine(Line7, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line8, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line9, (uint8_t *)"                    ");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

5、tim.c文件中

可以看到配置效果
在这里插入图片描述

/* TIM1 init function */
void MX_TIM1_Init(void) //(999+1)*(79+1)/80 000 000=1000*80/80 000 000 =0.001s=1ms
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 1000-1; //设置为1000-1
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 79;        //设置为80-1
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
  sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

函数位置

TIM

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
  • 1
  • 2
  • 3

GPIO

在这里插入图片描述

void              HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
  • 1

LCD

在这里插入图片描述
在这里插入图片描述

void LCD_Init(void);
void LCD_SetTextColor(vu16 Color);
void LCD_SetBackColor(vu16 Color);
void LCD_Clear(u16 Color);
void LCD_DisplayStringLine(u8 Line, u8 *ptr);
  • 1
  • 2
  • 3
  • 4
  • 5

实验现象

可以看到双向流水灯现象,即LD1流向LD8,LD8流向LD1,如此循环下去
在这里插入图片描述

代码下载

HAL_TIM_BASE

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/912903
推荐阅读
相关标签
  

闽ICP备14008679号