当前位置: 首页 > news >正文

【13】STM32·HAL库-正点原子SYSTEM文件夹 | SysTick工作原理、寄存器介绍 | printf函数使用、重定向

目录

  • 1.sys文件夹介绍(掌握)
  • 2.deley文件夹介绍(掌握)
    • 2.1deley文件夹函数简介
    • 2.2SysTick工作原理
    • 2.3SysTick寄存器介绍
    • 2.4delay_init()函数(F1)
    • 2.5delay_us()函数(F1)
    • 2.6delay_ms()函数(F1)
  • 3.usart文件夹介绍(掌握)
    • 3.1printf函数输出流程
    • 3.2printf的使用
      • 3.2.1常用输出控制符表
      • 3.2.2常用转义字符表
    • 3.3printf函数支持
      • 3.3.1半主机模式简介
      • 3.3.2微库法
      • 3.3.3代码法
      • 3.3.4微库法VS代码法
      • 3.3.5实现fputc函数
  • 4.总结(了解)

1.sys文件夹介绍(掌握)

  下面函数都是以sys_开头,定义在sys.c中。正点原子函数现阶段命名规则如果是在led.c中,则以led_开头。在F7/H7系列中会存在Cache配置函数,I-Cache中存储指令,D-Cache中存储数据。
在这里插入图片描述

2.deley文件夹介绍(掌握)

2.1deley文件夹函数简介

2.2SysTick工作原理

  SysTick,即系统滴答定时器,包含在M3/4/7内核里面,核心是一个24位的递减计数器(最大计数值为224=16777216)。当计数器减至0时,证明延时成功,则让COUNTFLAG置1,并将重装载寄存器中的值赋给计数器,重装载值可以自己设置,取值范围是从0开始0~16777215。
在这里插入图片描述
  每次VAL到0时,VAL自动从LOAD重载,开始新一轮递减计数。

2.3SysTick寄存器介绍

  SysTick控制及状态寄存器(CTRL)(摘自:Cortex M3权威指南(中文).pdf)。其中,CLKSOURCE并不是时钟源选择位,而是配置分频系数。
在这里插入图片描述
SysTick重装载数值寄存器(LOAD)(摘自:Cortex M3权威指南(中文).pdf),LOAD中的值会重装载到VAL寄存器中。
在这里插入图片描述

SysTick当前数值寄存器(VAL) (摘自:Cortex M3权威指南(中文).pdf
在这里插入图片描述

2.4delay_init()函数(F1)

  形参sysclk为系统时钟,单位是M,比如在F1系列中系统时钟为72MHz,则填入72。
  下列代码第一行是设置系统滴答定时器的状态控制寄存器为0,在进行dellay_init()函数之前可能会调用HAL库的初始化函数,可以将系统滴答定时器的中断以及其他设置配置好,这里需要按照我们自己的意愿来设置,所以需要将HAL库设置的清0,不会干扰后面的配置;第二行是调用HAL库的函数来选择系统滴答定时器时钟源分频系数,这里选择8分频,也就是将CTRL寄存器的位CLKSOURCE置0;第三行是定义全局变量,作为1us时基的来源,如果系统滴答定时器的计数频率为1MHz,1秒钟计数1000 000次,计数一次用1/1000 000次,F1系列的系统时钟为72Mhz,系统滴答定时器进行8分频,系统滴答定时器真正计数频率为9Mhz,用sysclk除以8得到9Mhz,得到1us需要计数多少次。1/1000 000s=1us=g_fac_us ×1/9000 000,其中g_fac_us 为达到1us需要计数的次数。

void delay_init(uint16_t sysclk) 
{ SysTick->CTRL = 0; HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8); g_fac_us = sysclk / 8; 
}

2.5delay_us()函数(F1)

  在9MHz的计数频率上得到1us,需要进行计数9次,其中g_fac_us为9,使用变量temp来判断滴答定时器是否在工作,位16是判断计数是否完成,如果计数未完成则为0。

void delay_us(uint32_t nus) 
{ uint32_t temp; SysTick->LOAD = nus * g_fac_us; 	/* 时间加载 */ SysTick->VAL = 0x00; 			/* 清空计数器 */ SysTick->CTRL |= 1 << 0 ; 		/* 开始倒数 */ do { temp = SysTick->CTRL; } while ((temp & 0x01) && !(temp & (1 << 16))); /* CTRL.ENABLE位必须为1, 并等待时间到达 */SysTick->CTRL &= ~(1 << 0) ; 		/* 关闭SYSTICK */ SysTick->VAL = 0X00; 			/* 清空计数器 */ 
}

2.6delay_ms()函数(F1)

  毫秒延时函数是利用us延时函数来实现的,那么就需要知道微秒延时函数的,所能延时的最大us数,F1系统时钟为72Mhz,经过8分频得到滴答定时器时钟9Mhz计数频率,计一个数为1/9000 000,可以计数224,则最大为1/9000 000 ×224≈1.864s,这是没有考虑超频,如果超频到128Mhz,经过8分频为16Mhz,1/16000 000×224≈1.048576s。那么如果延时需要超过1ms,则可以调用多次delay_us()函数,如果不超过1ms,可以直接使用delay_us()函数。
  代码第一行首先对1000取整数,将整数部分赋值给repeat 用于1s延时,小数部分赋值给remain用于小于1s的延时,用remain乘以1000是因为ms到us是相差1000倍。。

void delay_ms(uint16_t nms) 
{ uint32_t repeat = nms / 1000;	/* 这里用1000,是考虑到可能有超频应用, * 比如128Mhz的时候, delay_us最大只能延时1048576us*/ uint32_t remain = nms % 1000; while (repeat) { delay_us(1000 * 1000); 	/* 利用delay_us 实现 1000ms 延时 */ repeat--; } if (remain) { delay_us(remain * 1000); 	/* 利用delay_us, 把尾数延时(remain ms)给做了 */ } 
}

3.usart文件夹介绍(掌握)

3.1printf函数输出流程

  如果要使用printf()函数,必须包含stdio.h头文件,用工使用printf()函数,然后自动调用C标准库钟内容,最终会调用fputc()函数,此函数与硬件相关,通过屏幕或者串口来输出内容。
在这里插入图片描述

3.2printf的使用

  1. printf(“字符串\r\n”);使用\r\n实现换行,有些操作系统钟只用\n即可,为了兼容不同的操作系统推荐使用\r\n来实现换行。
printf("Hello World!\r\n");
  1. printf(“输出控制符”,输出参数);%d是输出十进制数。
uint32_t  temp = 10;
printf("%d\r\n", temp);          /* %d是输出控制符,temp是输出参数 */
  1. printf(“输出控制符1输出控制符2…”,输出参数1,输出参数2,…);%x以十六进制形式输出,则输出5A。
uint32_t  temp1 = 5;   
uint32_t  temp2 = 10;
printf("%d%x\r\n", temp1,temp2);  
  1. printf(“非输出控制符 输出控制符 非输出控制符”,输出参数);
uint32_t  temp = 10;   
printf("temp=  %d  收到over\r\n", temp);  
  1. 如何输出%、\和双引号
printf("%% \r\n");
printf("\\\r\n");
printf("\"\"\r\n");

3.2.1常用输出控制符表

在这里插入图片描述

3.2.2常用转义字符表

在这里插入图片描述

3.3printf函数支持

  1. 避免使用半主机模式:两种方法:微库法、代码法
  2. 实现fputc函数实现单个字符输出

3.3.1半主机模式简介

  用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。简单说,就是通过仿真器实现开发板在电脑上的输入和输出,一般我们不使用半主机模式。具体半主机模式的介绍可以查看参考链接。

3.3.2微库法

  在魔术棒->Target选项卡,勾选【Use Micro LIB】,即可避免半主机模式。
在这里插入图片描述

3.3.3代码法

  1个预处理、 2个定义、3个函数。

1.#pragma import(__use_no_semihosting),确保不从C库中使用半主机函数;
2.定义:__FILE结构体,避免HAL库某些情况下报错;
3.定义: FILE __stdout,避免编译报错;
4.实现:_ttywrch、_sys_exit和_sys_command_string等三个函数。
AC5和AC6不使用半主机模式稍有差异,详见源码

3.3.4微库法VS代码法

  推荐使用代码法,正点原子源码已做好。
在这里插入图片描述

/******************************************************************************************/
/* 加入以下代码, 支持printf函数, 而不需要选择use MicroLIB */#if 1#if (__ARMCC_VERSION >= 6010050)            /* 使用AC6编译器时 */
__asm(".global __use_no_semihosting\n\t");  /* 声明不使用半主机模式 */
__asm(".global __ARM_use_no_argv \n\t");    /* AC6下需要声明main函数为无参数格式,否则部分例程可能出现半主机模式 */#else
/* 使用AC5编译器时, 要在这里定义__FILE 和 不使用半主机模式 */
#pragma import(__use_no_semihosting)struct __FILE
{int handle;/* Whatever you require here. If the only file you are using is *//* standard output using printf() for debugging, no file handling *//* is required. */
};#endif/* 不使用半主机模式,至少需要重定义_ttywrch\_sys_exit\_sys_command_string函数,以同时兼容AC6和AC5模式 */
int _ttywrch(int ch)
{ch = ch;return ch;
}/* 定义_sys_exit()以避免使用半主机模式 */
void _sys_exit(int x)
{x = x;
}char *_sys_command_string(char *cmd, int len)
{return NULL;
}/* FILE 在 stdio.h里面定义. */
FILE __stdout;/* MDK下需要重定义fputc函数, printf函数最终会通过调用fputc输出字符串到串口 */
int fputc(int ch, FILE *f)
{while ((USART_UX->SR & 0X40) == 0);     /* 等待上一个字符发送完成 */USART_UX->DR = (uint8_t)ch;             /* 将要发送的字符 ch 写入到DR寄存器 */return ch;
}
#endif

3.3.5实现fputc函数

  在fputc函数中,第一行等待上一个字符发送完成,也就是检查串口状态寄存器SR的位6是否为1,为1则发送成功;第二行是将要发送的字符写入到串口的数据寄存器DR。如果注释掉第一行,print()函数发送的数据会乱码,因为fputc()函数是实现一个字符的输出,printf()输出很多个字符时,注释掉第一行代码将不再等待上一字符发送完成,将会一直发送叠加,导致乱码。使用微库法时,不能屏蔽掉fputc函数,只需要屏蔽1个预处理、 2个定义、3个函数。

/* MDK下需要重定义fputc函数, printf函数最终会通过调用fputc输出字符串到串口 */
int fputc(int ch, FILE *f)
{while ((USART_UX->SR & 0X40) == 0);     /* 等待上一个字符发送完成 */USART_UX->DR = (uint8_t)ch;             /* 将要发送的字符 ch 写入到DR寄存器 */return ch;
}
#endif

4.总结(了解)

在这里插入图片描述

相关文章:

【13】STM32·HAL库-正点原子SYSTEM文件夹 | SysTick工作原理、寄存器介绍 | printf函数使用、重定向

目录 1.sys文件夹介绍&#xff08;掌握&#xff09;2.deley文件夹介绍&#xff08;掌握&#xff09;2.1deley文件夹函数简介2.2SysTick工作原理2.3SysTick寄存器介绍2.4delay_init()函数&#xff08;F1&#xff09;2.5delay_us()函数&#xff08;F1&#xff09;2.6delay_ms()函…...

ansible配置文件案例

案例一 控制主机上的普通用户控制受控主机 控制端1台&#xff0c;受控端两台 1.将两台受控主机添加到/etc/hosts文件中 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhos…...

【大数据】Flink 从入门到实践(一):初步介绍

Flink 从入门到实践&#xff08;一&#xff09;&#xff1a;初步介绍 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在 无边界 和 有边界 数据流上进行 有状态 的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任意规模进行计算。 1.架构 1…...

大数据课程F4——HIve的其他操作

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 掌握HIve的join&#xff1b; ⚪ 掌握HIve的查询和排序 ⚪ 掌握HIve的beeline ⚪ 掌握HIve的文件格式 ⚪ 掌握HIve的基本架构 ⚪ 掌握HIve的优化&#xff1b; 一、jo…...

React Native详解和代码实例

目录 一、React Native 的主要特点二、React Native 的工作原理三、React Native 的优缺点四、React Native 代码示例 React Native 是一个用于构建原生移动应用程序的 JavaScript 框架。它使用 React 库&#xff0c;允许开发者使用 JavaScript 编写应用程序的 UI 和逻辑&#…...

CAD随机球体颗粒过渡区3D插件

插件介绍 CAD随机球体颗粒&过渡区3D插件可用于在AutoCAD软件内生成随机分布的球体及球体外侧过渡区部件&#xff0c;适用于科研绘图、有限元建模如混凝土细观、颗粒增强复合材料、随机三维骨料及过渡区等方面的应用。 插件可指定的参数有模型的长、宽、高&#xff1b;球…...

【项目 进程12】2.25 sigprocmask函数使用 2.26sigaction信号捕捉函数 2.27SIGCHILD信号

文章目录 2.25 sigprocmask函数使用2.26 sigaction信号捕捉函数内核实现信号捕捉的过程信号捕捉特性 2.27SIGCHILD信号 2.25 sigprocmask函数使用 阻塞信号集有时称作信号掩码。 联想&#xff1a;fcntl函数可以修改fd属性。 ./sigprocmask & //将程序设置为后台运行&…...

【无标题】面试题 02.07. 链表相交

面试题 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 方法一&#xff1a;遍历headA&#xff0c;将每个节点add到HashSet中&#xff1b;然后遍历headB&#xf…...

Zotero ubuntu2023安装 关联 ubuntu文献翻译

一、准备下载的软件&#xff1a; Zotero | Downloads 1. Zotero-6.0.26_linux-x86_64.tar.bz2 下面是插件 zotfile-5.1.2-fx.xpi zotero-pdf-translate.xpi jasminum-v0.2.6.xpi 2.2.5 Tampermonkey 4.11.crx 所准备的文件&#xff0c;都已经在这个链接的压缩包下面 …...

Stable Diffusion教程(7) - PS安装AI绘画插件教程

配套教程视频&#xff1a;https://v.douyin.com/Uyux9F6/ 1. 前置条件 安装了stable diffusion 还没安装的从知识库安装 阿超的AI绘画知识库 语雀 安装了ps2023 还没安装的从网盘下载Win版 PS 2023【必须win10、11】.rar官方版下载丨最新版下载丨绿色版下载丨APP下载-12…...

如何学技术

#​如何学习技术​ 今天在学习redis时&#xff0c;看到了一位大佬写的如何学习技术的方法论&#xff0c;个人觉得很不错&#xff0c;这里分享给大家。 --- - 领先一步&#xff1a;保持好奇心 不给自己设限 真正走出舒适区之后&#xff0c;我看到了自己的飞速成长和进步&#…...

【云存储】使用OSS快速搭建个人网盘教程(阿里云)

使用OSS快速搭建个人网盘 一、基础概要1. 主要的存储类型1.1 块存储1.2 文件存储1.3 对象存储 2. 对象存储OSS2.1 存储空间2.2 地域2.3 对象2.4 读写权限2.5 访问域名&#xff08;Endpoint&#xff09;2.6 访问密钥2.7 常用功能&#xff08;1&#xff09;创建存储空间&#xff…...

微信小程序iconfont真机渲染失败

解决方法&#xff1a; 1.将下载的.woff文件在transfonter转为base64&#xff0c; 2.打开网站&#xff0c;导入文件&#xff0c;开启base64按钮&#xff0c;下载转换后的文件 3. 在下载解压后的文件夹中找到stylesheet.css&#xff0c;并复制其中的base64 4. 修改index.wxss文…...

万界星空/推出生产制造执行MES系统/开源MES/免费下载

免费MES系统介绍 什么是MES系统呢&#xff1f;MES系统主要功能就是解决“如何生产”的问题。通过实施MES系统&#xff0c;一站式解决您所困扰的所有生产制作流程问题。 普通的免费MES系统只提供简单的基本功能让客户体验&#xff0c;而万界星空MES系统运用低代码的形式开发&a…...

【VxWorks】Vxworks、QNX、Xenomai、Intime、Sylixos、Ucos等实时操作系统的性能特点

目录 1.VxWorks操作系统 2.QNX操作系统 3.Xenomai操作系统 4.INtime操作系统 5.SylixOS操作系统 5.1.SylixOS官网...

17、YML配置文件及让springboot启动时加载我们自定义的yml配置文件的几种方式

YML配置文件及加载自定义配置文件的几种方式 ★ YAML配置文件 其实本质和.properties文件的是一样的。 Spring Boot默认使用SnakeYml工具来处理YAML配置文件&#xff0c;SnakeYml工具默认就会被spring-boot-starter导入&#xff0c;因此无需开发者做任何额外配置。 YAML本质…...

18、springboot默认的配置文件及导入额外配置文件

springboot默认的配置文件及导入额外配置文件 ★ Spring Boot默认加载的配置文件&#xff1a; (1) 类加载路径&#xff08;resources目录&#xff09;application.properties|yml &#xff08;相当于JAR包内&#xff09;optional: classpath:/ &#xff08;2&#xff09;类加…...

Conda换源(Linux)

目录 一、相关命令 1.添加软件包渠道 2.查看已添加的渠道 3.删除不想要的渠道 4.显示从哪个渠道安装软件包 二、添加其他源 1.添加conda源 2.添加tuna源 3.添加ali源 一、相关命令 1.添加软件包渠道 conda config --add channels conda-forge 2.查看已添加的渠道 …...

【C语言学习】数据类型转换

一、自动类型转换 1.当运算符两边的数据类型不同时&#xff0c;C语言会帮我们将其转换为较大的类型。即将数据转换成表达范围更大的类型。 将前一种类型转换为后一种类型 char --> short --> int --> long --> long long int --> float --> double2.对于…...

深入了解PostgreSQL:高级查询和性能优化技巧

在当今数据驱动的世界中&#xff0c;数据库的性能和查询优化变得尤为重要。 POSTGRESQL作为一种开源的关系型数据库管理系统&#xff0c;在处理大规模数据和复杂查询时表现出色。 但随着数据量和查询复杂性的增加&#xff0c;性能问题可能会显现出来。 本文将深入探讨POSTGR…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

接口 RESTful 中的超媒体:REST 架构的灵魂驱动

在 RESTful 架构中&#xff0c;** 超媒体&#xff08;Hypermedia&#xff09;** 是一个核心概念&#xff0c;它体现了 REST 的 “表述性状态转移&#xff08;Representational State Transfer&#xff09;” 的本质&#xff0c;也是区分 “真 RESTful API” 与 “伪 RESTful AP…...