STM32-- 调试- 延时、编译空循环

编译对空循环的处理,会影响堵塞延时效果,具体怎么处理的还不知道,只知道结果和现象。

模拟串口输出字符,用到延时函数,同样的延时函数,会有正常和不正常输出的情况;具体现象如下,

//这部分函数是可以正常输出串口数据的
//使用stm32f103vct6,逻辑分析仪测出来脉冲长度是8.5us,电脑端设置115200,可以正常接收到发送的数据#define RCC_TX_PIN  RCC_APB2Periph_GPIOD
#define TX_PIN  GPIO_Pin_2
#define GPIO_PORT_TX GPIOD
#define RCC_RX_PIN  RCC_APB2Periph_GPIOC
#define RX_PIN  GPIO_Pin_8
#define GPIO_PORT_RX GPIOC// #define BAUD_RATE 115200
// #define BIT_PERIOD_US (1000000 / BAUD_RATE) // 比特周期 (微秒)#define BIT_PERIOD_US (80) // 约延时8.5us,// 简单的延时函数
void delay_us(uint32_t us) {// uint32_t count = (SystemCoreClock / 1000000) * us / 5;while (us--) {__NOP();}// for(int i=0;i<us;i++)// {}  // int i;// while (i<us) {//     __NOP();// i++;// }
}int cnt;
int Get_SysTimeMs__(){return cnt++;
}
int delay_us__(uint16_t us) {// uint32_t start = Get_SysTimeMs(); // 获取当前计数值Get_SysTimeMs__();//for(int i=0;i<us;i++)//{} // int a=cnt++;// return a;// 等待指定的时间// while ((Get_SysTimeMs() - start) < us);
}// 初始化 GPIO
void USART_SIM_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStructure={0};// I2C_InitTypeDef I2C_InitStructure;// 使能I2C1和GPIOB时钟// RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);RCC_APB2PeriphClockCmd(RCC_TX_PIN, ENABLE);RCC_APB2PeriphClockCmd(RCC_RX_PIN, ENABLE);// 配置I2C1引脚 - PB6(SCL)和PB7(SDA)GPIO_InitStructure.GPIO_Pin = TX_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 输出GPIO_Init(GPIO_PORT_TX, &GPIO_InitStructure);// 配置I2C1引脚 - PB6(SCL)和PB7(SDA)GPIO_InitStructure.GPIO_Pin = RX_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  // 输入GPIO_Init(GPIO_PORT_RX, &GPIO_InitStructure);// 默认 TX 高电平(空闲状态)GPIO_SetBits(GPIO_PORT_TX,TX_PIN);}// 模拟串口发送一个字节
void UART_SendByte(uint8_t byte) {// 起始位:低电平// HAL_GPIO_WritePin(GPIO_PORT_TX, TX_PIN, GPIO_PIN_RESET);GPIO_ResetBits(GPIO_PORT_TX,TX_PIN);delay_us(BIT_PERIOD_US);// 数据位:逐位发送for (uint8_t i = 0; i < 8; i++) {if (byte & (1 << i)) {// HAL_GPIO_WritePin(GPIO_PORT_TX, TX_PIN, GPIO_PIN_SET); // 发送1GPIO_SetBits(GPIO_PORT_TX,TX_PIN);} else {// HAL_GPIO_WritePin(GPIO_PORT_TX, TX_PIN, GPIO_PIN_RESET); // 发送0GPIO_ResetBits(GPIO_PORT_TX,TX_PIN);}delay_us(BIT_PERIOD_US);}// 停止位:高电平// HAL_GPIO_WritePin(GPIO_PORT_TX, TX_PIN, GPIO_PIN_SET);GPIO_SetBits(GPIO_PORT_TX,TX_PIN);delay_us(BIT_PERIOD_US);
}int fputc(int ch, FILE *p) {// 调用自定义的模拟串口发送函数UART_SendByte((uint8_t)ch);// 模拟串口中无需等待 TXE 标志位,因此省略// 如果模拟串口有类似机制,可以插入相关等待逻辑return ch;
}

发送:

printf("Ahello02\n");

printf("中文\n");

情况一

使用for循环,不需要Get_SysTimeMs__和delay_us__函数就能正常发送串口数据。

// 简单的延时函数

void delay_us(uint32_t us) {

    for(int i=0;i<us;i++)

    {}  

}

对应的汇编函数:

    delay_us

        0x08003b50:    2100        .!      MOVS     r1,#0

        0x08003b52:    e000        ..      B        0x8003b56 ; delay_us + 6

        0x08003b54:    1c49        I.      ADDS     r1,r1,#1

        0x08003b56:    4281        .B      CMP      r1,r0

        0x08003b58:    d3fc        ..      BCC      0x8003b54 ; delay_us + 4

        0x08003b5a:    4770        pG      BX       lr

此时延时正常,串口发送正常。

情况二

使用while循环,有Get_SysTimeMs__函数也不能正常发送串口数据。

只有delay_us函数,使用while循环,发送串口数据更是乱码。

// 简单的延时函数

void delay_us(uint32_t us) {

    while (us--) {

        __NOP();

    }

}

int cnt;

int Get_SysTimeMs__(){

    return cnt++;

}

对应的汇编函数

    delay_us

        0x08003b50:    e000        ..      B        0x8003b54 ; delay_us + 4

        0x08003b52:    bf00        ..      NOP      

        0x08003b54:    1e40        @.      SUBS     r0,r0,#1

        0x08003b56:    1c41        A.      ADDS     r1,r0,#1

        0x08003b58:    d1fb        ..      BNE      0x8003b52 ; delay_us + 2

        0x08003b5a:    4770        pG      BX       lr

    Get_SysTimeMs__

        0x08003b5c:    4a49        IJ      LDR      r2,[pc,#292] ; [0x8003c84] = 0x200000b4

        0x08003b5e:    6810        .h      LDR      r0,[r2,#0]

        0x08003b60:    1c41        A.      ADDS     r1,r0,#1

        0x08003b62:    6011        .`      STR      r1,[r2,#0]

        0x08003b64:    4770        pG      BX       lr

不能正常串口数据,乱码

[19:16:49.820]收←◆羑ello02

中文

[19:16:51.334]收←◆夾he靗o02

中文

[19:16:52.847]收←◆Ahello?

中文

[19:16:54.360]收←◆Ah錶lo02

中文

[19:16:55.873]收←◆Ahello?

中文

[19:16:57.387]收←◆Ahello?

中文

[19:16:58.900]收←◆Ahello02娭形?

[19:17:00.413]收←◆Ah錶lo0?

中文

情况三

使用while循环,后面紧接着Get_SysTimeMs__和delay_us__函数,可以正常发送串口函数。

// 简单的延时函数

void delay_us(uint32_t us) {

    while (us--) {

        __NOP();

    }

}

int cnt;

int Get_SysTimeMs__(){

    return cnt++;

}

int delay_us__(uint16_t us) {

    Get_SysTimeMs__();

}

对应汇编函数

    delay_us

        0x08003b50:    e000        ..      B        0x8003b54 ; delay_us + 4

        0x08003b52:    bf00        ..      NOP      

        0x08003b54:    1e40        @.      SUBS     r0,r0,#1

        0x08003b56:    1c41        A.      ADDS     r1,r0,#1

        0x08003b58:    d1fb        ..      BNE      0x8003b52 ; delay_us + 2

        0x08003b5a:    4770        pG      BX       lr

    Get_SysTimeMs__

        0x08003b5c:    4a4a        JJ      LDR      r2,[pc,#296] ; [0x8003c88] = 0x200000b4

        0x08003b5e:    6810        .h      LDR      r0,[r2,#0]

        0x08003b60:    1c41        A.      ADDS     r1,r0,#1

        0x08003b62:    6011        .`      STR      r1,[r2,#0]

        0x08003b64:    4770        pG      BX       lr

    delay_us__

        0x08003b66:    e7f9        ..      B        Get_SysTimeMs__ ; 0x8003b5c

发送串口数据正常,

情况四

使用while循环,后面紧接着Get_SysTimeMs__和delay_us__函数,可以正常发送串口函数。

后面只紧接着delay_us__函数也可正常发送。因为delay_us__里面用了for循环。

// 简单的延时函数

void delay_us(uint32_t us) {

    while (us--) {

        __NOP();

    }

}

int cnt;

int Get_SysTimeMs__(){

    return cnt++;

}

int delay_us__(uint16_t us) {

    for(int i=0;i<us;i++)

    {}

}

对应汇编函数

delay_us

        0x08003b50:    e000        ..      B        0x8003b54 ; delay_us + 4

        0x08003b52:    bf00        ..      NOP      

        0x08003b54:    1e40        @.      SUBS     r0,r0,#1

        0x08003b56:    1c41        A.      ADDS     r1,r0,#1

        0x08003b58:    d1fb        ..      BNE      0x8003b52 ; delay_us + 2

        0x08003b5a:    4770        pG      BX       lr

    Get_SysTimeMs__

        0x08003b5c:    4a4c        LJ      LDR      r2,[pc,#304] ; [0x8003c90] = 0x200000b4

        0x08003b5e:    6810        .h      LDR      r0,[r2,#0]

        0x08003b60:    1c41        A.      ADDS     r1,r0,#1

        0x08003b62:    6011        .`      STR      r1,[r2,#0]

        0x08003b64:    4770        pG      BX       lr

    delay_us__

        0x08003b66:    2100        .!      MOVS     r1,#0

        0x08003b68:    e000        ..      B        0x8003b6c ; delay_us__ + 6

        0x08003b6a:    1c49        I.      ADDS     r1,r1,#1

        0x08003b6c:    4281        .B      CMP      r1,r0

        0x08003b6e:    dbfc        ..      BLT      0x8003b6a ; delay_us__ + 4

        0x08003b70:    4770        pG      BX       lr

也能正常发送串口数据,电脑接收到[19:42:11.328]收←◆Ahello02
中文

只记录了现象,为什么会这样,还不知道,总之使用循环的时候,特别是空循环的时候,要注意。

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

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

相关文章

小狐狸AI数字人分身声音克隆形象克隆口播口型同步SAAS系统源码

AI数字人软件系统的未来趋势和用途正朝着多模态交互和智能化方向发展。 1. **多模态交互**&#xff1a;AI数字人技术正在从单一的文本或语音交互&#xff0c;转变为更加自然的多模态交互方式&#xff0c;包括语言对话、行为互动和自主学习能力。这种技术的提升使得数字人能够更…

Idea忽略提交文件、Idea设置文件隐藏、Idea提交时隐藏部分文件、git提交时忽略文件

文章目录 一、在idea中commit文件时隐藏文件方式一&#xff1a;创建.gitignore文件&#xff08;推荐&#xff09;方式二&#xff1a;‌通过File Types设置隐藏文件方式三&#xff1a;通过Git配置忽略文件‌&#xff08;不推荐&#xff09;总结 二、可能遇到的问题2.1、.gitigno…

FastGPT 和 DiffYAI 算不算ANGENT

FastGPT 和 DiffYAI 这类应用从某种程度上来说&#xff0c;可以算是“智能体&#xff08;Agent&#xff09;”&#xff0c;但其具体性质和智能体的定义范围有关。以下是详细分析&#xff1a; 什么是智能体&#xff08;Agent&#xff09;&#xff1f; 智能体是一种能够感知环境…

ARM 架构(Advanced RISC Machine)精简指令集计算机(Reduced Instruction Set Computer)

文章目录 1、ARM 架构ARM 架构的特点ARM 架构的应用ARM 架构的未来发展 2、RISCRISC 的基本概念RISC 的优势RISC 的应用RISC 与 CISC 的对比总结 1、ARM 架构 ARM 架构是一种低功耗、高性能的处理器架构&#xff0c;广泛应用于移动设备、嵌入式系统以及越来越多的服务器和桌面…

如何使用Jest测试你的React组件

在本文中&#xff0c;我们将了解如何使用Jest&#xff08;Facebook 维护的一个测试框架&#xff09;来测试我们的React组件。我们将首先了解如何在纯 JavaScript 函数上使用 Jest&#xff0c;然后再了解它提供的一些开箱即用的功能&#xff0c;这些功能专门用于使测试 React 应…

10 —— Webpack打包模式

开发模式&#xff1a;development &#xff1b;场景&#xff1a;本地开发 生产模式&#xff1a;production &#xff1b; 场景&#xff1a;打包上线 设置&#xff1a; 方式1.webpack.config.js 配置文件设置mode选项 module.exports { mode:production }; 方式2.在packa…

健康养生点点滴滴

在当下纷扰忙碌的尘世中&#xff0c;养生宛如一支灵动的画笔&#xff0c;精心地为人们勾勒出健康生活的绚丽图景。它绝非仅是对躯体的片面保养&#xff0c;更是对精神世界的深度润泽&#xff0c;一种执着于身心交融、契合无间的生活美学。 饮食养生&#xff0c;仿若画卷中那细…

《TCP/IP网络编程》学习笔记 | Chapter 15:套接字与标准 I/O

《TCP/IP网络编程》学习笔记 | Chapter 15&#xff1a;套接字与标准 I/O 《TCP/IP网络编程》学习笔记 | Chapter 15&#xff1a;套接字与标准 I/O标准 I/O 函数标准 I/O 函数的两个优点标准 I/O 函数和系统函数之间的性能对比标准 I/O 函数的几个缺点 使用标准 I/O 函数利用 fd…

「Mac玩转仓颉内测版29」基础篇9 - 数组类型详解

本篇将介绍 Cangjie 中的数组类型&#xff0c;包括数组的定义、创建、访问、常见操作以及在数据管理中的应用&#xff0c;帮助开发者熟练掌握数组的使用。 关键词 数组类型定义数组创建数组访问数组操作应用场景 一、数组类型概述 在 Cangjie 中&#xff0c;数组是一种用于存…

[面试]-golang基础面试题总结

文章目录 panic 和 recover**注意事项**使用 pprof、trace 和 race 进行性能调试。**Go Module**&#xff1a;Go中new和make的区别 Channel什么是 Channel 的方向性&#xff1f;如何对 Channel 进行方向限制&#xff1f;Channel 的缓冲区大小对于 Channel 和 Goroutine 的通信有…

鸿蒙进阶-状态管理

大家好啊&#xff0c;这里是鸿蒙开天组&#xff0c;今天我们来学习状态管理。 开始组件化开发之后&#xff0c;如何管理组件的状态会变得尤为重要&#xff0c;咱们接下来系统的学习一下这部分的内容 状态管理机制 在声明式UI编程框架中&#xff0c;UI是程序状态的运行结果&a…

深度学习每周学习总结J6(ResNeXt-50 算法实战与解析 - 猴痘识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结ResNeXt基本介绍 1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1a;定义损失函数&…

IDEA 2024.3 版本更新主要功能介绍

IDEA 2024.3 版本提供的新特性 IntelliJ IDEA 2024.3 的主要新特性&#xff1a; AI Assistant 增强 改进的代码补全和建议更智能的代码分析和重构建议Java 支持改进 支持 Java 21 的所有新特性改进的模式匹配和记录模式支持更好的虚拟线程调试体验开发工具改进 更新的 UI/UX 设…

java基础概念37:正则表达式2-爬虫

一、定义 【回顾】正则表达式的作用 作用一&#xff1a;校验字符串是否满足规则作用二&#xff1a;在一段文本中查找满足要求的内容——爬虫 二、本地爬虫VS网络爬虫 2-1、本地爬虫 示例&#xff1a; 代码优化&#xff1a; public static void main(String[] args) {// 大…

嵌入式AI之rknn yolov5初探

本文主要记录在RK3588上跑通RKNUP的rknn_yolov5_demo的过程,并且对rknn_yolov5_demo的代码进行修改,实现在显示器上同步播放rknn_yolov5_demo视频流检测结果。 首先,是RKNUP SDK的编译,参考官方SDK中的README.md文档,下载好对应的sdk编译工具链,我这边使用的是debian系统…

【数据库批量删除】MySql通过 Procedure 循环删除数据

一、问题描述 在日常使用运维中&#xff0c;一些特殊情况需要批量删除陈旧或异常数据。 如果通过 delete from 【表名】 where 【条件】 直接删除&#xff0c;可能会由于数据量过大&#xff0c;事务执行时间过长&#xff0c;造成死锁。 二、解决方案 通过 Procedure 使用循环…

AmazonS3集成minio实现https访问

最近系统全面升级到https&#xff0c;之前AmazonS3大文件分片上传直接使用http://ip:9000访问minio的方式已然行不通&#xff0c;https服务器访问http资源会报Mixed Content混合内容错误。 一般有两种解决方案&#xff0c;一是升级minio服务&#xff0c;配置ssl证书&#xff0c…

JavaWeb——Mybatis

6. Mybatis MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发 6.1. Mybatis入门 6.1.1. 入门程序 6.1.2. JDBC 6.1.3. 数据库连接池 6.1.4. Lombok 6.2. Mybatis基础操作 6.2.1. 删除 6.2.1.1. 根据主键删除 6.2.1.2. 预编译SQL #{id}在编译过程中会替换成?…

【环境配置】ubuntu-jetson上的定时任务

使用 crontab 制定定时任务 目标 每分钟清理当前分钟之前的图片。 [可选]每小时清理当前小时之前的图片。 [可选]每天清理当前日期之前的图片。 [可选] 环境 操作系统&#xff1a;Ubuntu 22.04 (jetson)需要清理的文件夹&#xff1a;/home/nvidia/install/Snapshot 步骤 …

MongoDB数据备份与恢复(内含工具下载、数据处理以及常见问题解决方法)

一、工具准备 对MongoDB进行导入导出、备份恢复等操作时需要用到命令工具&#xff0c;我们要先检查一下MongoDB安装目录下是否有这些工具&#xff0c;正常情况下是没有的:)&#xff0c;因为新版本的MongoDB安装时不包含这些工具&#xff0c;需要我们手动下载安装。下载成功之后…