STM32G0x0系列-软件定时器解决HAL_Delay问题

news2024/9/21 2:38:44

目录

HAL_Delay函数源码

软件定时器

创建工程试验

1.将对应文件移动到项目位置

2.添加现有文件放到工程中 

 3.重定向printf

3.验证自己的软件定时器

4.查看现象


        

HAL_Delay函数使用了中断机制来实现延时功能,当在中断函数中调用HAL_Delay函数需要考虑中断优先级问题。这样无疑让开发难度增加,我们可以通过分析HAL_Delay的源代码写出一个自己的软件定时器,来解决这个问题。

HAL_Delay函数源码

__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();//获取当前时间存储到开始时间
  uint32_t wait = Delay;//计时时间

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while ((HAL_GetTick() - tickstart) < wait)//当前时间与开始时间差值小与计数时间
  {
  }
}

上面代码牵扯到了函数HAL_GetTick

__weak uint32_t HAL_GetTick(void)//获取当前uwTick值
{
  return uwTick;
}

我们可以参照程序源码的思想书写自己的软件定时器

软件定时器

声明文件

#ifndef __SOFTTIME__H__
#define __SOFTTIME__H__

#include "stm32g0xx_hal.h"

typedef struct time
{
uint32_t start;//存储当前时间
uint32_t delay;//存储定时时间
}MyTime;

void SetTime(MyTime *timer,uint32_t delayms);//设置初始时间和定时时间
uint32_t competaTime(MyTime *timer);//比较时间
#endif

定义文件

#include "softtime.h"
void SetTime(MyTime *timer,uint32_t delayms)//设置初始时间和定时时间
{
timer->start = HAL_GetTick();
timer->delay = delayms;
}
uint32_t competaTime(MyTime *timer)//比较时间
{
if(HAL_GetTick()-timer->start>=timer->delay)
{
return 1;
}else
{
return 0;
}
}

创建工程试验

1.将对应文件移动到项目位置

 

2.添加现有文件放到工程中 

 

 3.重定向printf

 

 将fputc重写,此时printf随着改变

int fputc(int ch,FILE*f)
{
	while(!(USART1->ISR&(1<<7)));
	USART1->TDR=ch;
	return ch;
}

3.验证自己的软件定时器

 

 

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "softtime.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE*f)
{
	while(!(USART1->ISR&(1<<7)));
	USART1->TDR=ch;
	return ch;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	MyTime time1; //将结构体实例化
	SetTime(&time1,1000);//设置时间为1000ms
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(competaTime(&time1) == 1)//比较时间
		{
			printf("SouthernBird\n");
			SetTime(&time1,1000);//重置时间
			
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

4.查看现象

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《操作系统》by李治军 | 实验5.pre - copy_process 代码详解

目录 【前言】 代码分析 1. 申请子进程 PCB 空间 2. 找到子进程的内核栈 3. 父子进程共用同一内存、堆栈和数据代码块 4. 相关寄存器入栈 5. switch_to 返回位置 6. 响应 switch_to 的弹栈工作 7. 更新子进程 PCB 8. 子进程切换流程 【前言】 在李治军老师的《操作系…

MyBatis——缓存

是一种临时存储少量数据至内存或者是磁盘的一种技术.减少数据的加载次数,可以降低工作量,提高程序响应速度 缓存的重要性是不言而喻的。mybatis的缓存将相同查询条件的SQL语句执行一遍后所得到的结果存在内存或者某种缓存介质当中&#xff0c;当下次遇到一模一样的查询SQL时候…

Yolov8涨点神器:ODConv+ConvNeXt提升小目标检测能力

1.涨点神器结合,助力YOLO 1.1 ICLR 2022涨点神器——即插即用的动态卷积ODConv 论文:Omni-Dimensional Dynamic Convolution 论文地址:Omni-Dimensional Dynamic Convolution | OpenReview ODConv通过并行策略引入一种多维注意力机制以对卷积核空间的四个维度学习更灵活的…

项目所需的Python版本+国内源+虚拟环境+用Conda创建环境

文章目录 &#xff08;一&#xff09;Python&#xff08;1.1&#xff09;国内源&#xff08;1.2&#xff09;设置源&#xff08;全局&#xff09;&#xff08;1.3&#xff09;使用源&#xff08;单次&#xff09; &#xff08;二&#xff09;Python环境&#xff08;2.1&#xf…

【数据结构与算法】力扣:栈和队列(一)

1 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开…

vue diff算法与虚拟dom知识整理(13) 手写patch子节点更新换位策略

上一文中我们编写了 patch中新旧节点都有子节点的 插入节点的逻辑 但旧节点的子节点发生顺序 或数量变化 我们还没有处理 那我们现在继续 我们先来看看 原本是怎么写的 我们打开我们的案例 找到 node_modules 下面的snabbdom/src下面的 init.ts文件 我们在里面找到一个 updat…

Openai+Deeplearning.AI: ChatGPT Prompt Engineering(六)

想和大家分享一下最近学习的Deeplearning.AI和openai联合打造ChatGPT Prompt Engineering在线课程.以下是我写的关于该课程的前五篇博客&#xff1a; ChatGPT Prompt Engineering(一)ChatGPT Prompt Engineering(二)ChatGPT Prompt Engineering(三)ChatGPT Prompt Engineering…

QML Text 元素

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在 QML 中,Text 和 Label 是两种常用的元素(Label 继承于 Text),用于显示文本内容。虽然它们看起来很相似,但在使用和功能上有一些不同。 对于 Text 元素,比较重要的是 text 与 font 属性,一旦指定了…

Linux常见IO模型-3

在前两篇博客中&#xff0c;我们讲述了常见的IO模型&#xff0c;并对多路转接模型中的select模型进行了细致介绍和具体的代码实现。那么接下来&#xff0c;我们在本篇博客中将对剩余的多路转接模型中的&#xff1a;poll和epoll进行介绍。 目录 1.poll 1.1操作流程 1.2代码实…

硬件系统工程师宝典(27)-----MOSFET、BJT搭配,干活不累

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。上篇我们说到场效应管的原理是通过“监测”栅极和源极间电压来实现控制漏极-源极之间电流的目的。今天我们来讲讲场效应管如何和BJT搭配设计控制电路…

【P44】JMeter 模块控制器(Module Controller)

文章目录 一、模块控制器&#xff08;Module Controller&#xff09;参数说明二、测试计划设计 一、模块控制器&#xff08;Module Controller&#xff09;参数说明 提供了一种在运行时将测试计划片段替换为当前测试计划的机制&#xff1b;模块控制器的目标是为增加脚本的复用…

springboot+vue实验室预约设备报修管理系统

本实验室管理系统管理员功能有个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;公告信息管理&#xff0c;知识库管理&#xff0c;实验课程管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#xff0c;实验设备管理&#xff0c;采购记录管理&#xff0…

addon.MediaStream,erizo::MediaStream 还有addon.MediaXXX,erizo::MediaXXX

9. MediaStream 和erizo::MediaStream 类的继承关系 erizo::MediaStream source/agent/webrtc/rtcConn/erizo/src/erizo/MediaStream.h source/agent/webrtc/rtcConn/erizo/src/erizo/MediaDefinitions.h erizo::MediaSource source/agent/webrtc/rtcConn/erizo/src/erizo/…

【C++进阶4-AVLTree】尽可能条理清晰地为你讲解比普通BST更强的——AVLTree

今天&#xff0c;带来AVLTree的讲解。文中不足错漏之处望请斧正&#xff01; 是什么 AVLTree是一种自平衡的二叉搜索树。 它通过控制左右子树的高度差不超过1来调节平衡&#xff0c;从而提高搜索&#xff0c;插入和删除的效率。 实现 结构 AVLTree为了能自动调节平衡&#…

第十四章行为性模式—策略模式

文章目录 命令模式解决的问题结构实例存在的问题适用场景 JDK源码解析 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。行为型模式分为类行为模式…

Java阶段三Day07

Java阶段三Day07 文章目录 Java阶段三Day07Spring Security自定义UserDetails密码加密授权 JDK包结构文档注释规范JDK APIString APIString是不可变对象String常量池内存编码及长度使用indexOf实现检索使用substring获取子串trim去除两侧空白charAtstartsWith和endsWith大小写变…

3.1 矩阵连乘问题

博主简介&#xff1a;一个爱打游戏的计算机专业学生博主主页&#xff1a; 夏驰和徐策所属专栏&#xff1a;算法设计与分析 学习目标&#xff1a; 如果我要学习动态规划中的矩阵连乘问题&#xff0c;我会采取以下学习方法&#xff1a; 1. **理解问题的背景和目标&#xff1a;首…

pytorch中分布式Collective通信API学习

随着各种大模型的不断迭出&#xff0c;感觉现在的NLP领域已经来到了大模型的时代。那么怎么来训练一个大模型呢&#xff1f;其中比较关键的一个技术基础就是分布式训练。在阅读GLM源码的时候&#xff0c;感觉其中的分布式训练代码不是很熟悉&#xff0c;看起来有点吃力&#xf…

【Nature 2023】Computational approaches streamlining drug discovery

今天为大家介绍的是一篇发表于“Nature”上面的综述文章“Computational approaches streamlining drug discovery”&#xff0c; Computer-aided drug discovery has been around for decades, although the past few years have seen a tectonic shift towards embracing com…