欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > STM32-- 调试- 延时、编译空循环

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

2025/11/8 15:54:12 来源:https://blog.csdn.net/code_snow/article/details/143997416  浏览:    关键词: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
中文

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词