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

ops/2024/11/28 10:40:23/

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

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

//这部分函数是可以正常输出串口数据的
//使用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.ppmy.cn/ops/137327.html

相关文章

vi/vim文件管理命令练习

一.练习要求 文件管理命令练习&#xff1a; &#xff08;1&#xff09;在/opt目录下创建一个临时目录tmp&#xff1b; &#xff08;2&#xff09;在临时目录下创建一个文件&#xff0c;文件名为a.txt&#xff1b;vi/vim练习&#xff1a; (1) 应用vi命令在/tmp文件夹下创建文…

QChart数据可视化

目录 一、QChart基本介绍 1.1 QChart基本概念与用途 1.2 主要类的介绍 1.2.1 QChartView类 1.2.2 QChart类 1.2.3QAbstractSeries类 1.2.4 QAbstractAxis类 1.2.5 QLegendMarker 二、与图表交互 1. 动态绘制数据 2. 深入数据 3. 缩放和滚动 4. 鼠标悬停 三、主题 …

ThingsBoard规则链节点:GCP Pub/Sub 节点详解

目录 引言 1. GCP Pub/Sub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 事件通知 3.4 任务调度 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff…

Python3交叉编译arm-linux放入设备中运行方式

设置交叉编译环境 设置交叉编译工具链环境变量&#xff0c;告诉编译系统使用交叉编译工具链进行编译&#xff0c;而不是本地编译器。 export CROSS_COMPILEaarch64-linux-gnu- export ARCHarm64CROSS_COMPILE 指定交叉编译工具链的前缀&#xff0c;aarch64-linux-gnu- 表示你…

数据结构--B树

B树 B树原理实现 B树B*树 B树系列包括B树&#xff08;有些地方写成B-树&#xff0c;注意不要读成B减树&#xff0c;中间的 ‘-’ 是杠的意思&#xff0c;不是减号&#xff09;、B树、B 树&#xff0c;其中B树、B树是B树的改进优化&#xff0c;它们最常见的应用就是用于做索引。…

Kubernetes 分布式存储后端:指南

在 Kubernetes 中实现分布式存储后端对于管理跨集群的持久数据、确保高可用性、可扩展性和可靠性至关重要。在 Kubernetes 环境中&#xff0c;应用程序通常被容器化并跨多个节点部署。虽然 Kubernetes 可以有效处理无状态应用程序&#xff0c;但有状态应用程序需要持久存储来维…

养宠宠物空气净化器哪个好?实测热销品牌安德迈、希喂、小米

最近啊&#xff0c;猫咪们开始换毛了&#xff0c;不少铲屎官们正打算买个养宠宠物空气净化器呢&#xff0c;但面对众多选择&#xff0c;是不是有点儿犯愁不知道该咋挑&#xff1f;别担心&#xff0c;作为养猫多年的老手&#xff0c;我今天就来实测三款特别火的养宠宠物空气净化…

裸金属服务器和专属主机的区别是什么?

在当今互联网时代&#xff0c;人们越来越重视服务器的使用。裸金属服务器和专属主机是两种常见的服务器形式。裸金属服务器和云主机有什么区别呢&#xff1f; 一、定义和概念 裸金属服务器和云主机都是租用物理服务器的一种方式。 裸金属服务器是指没有安装虚拟化技术的物理…