在 stm32 中 volatile unsigned signed 分别有什么作用,分别在什么场景下使用?

在STM32开发中,

plaintext

复制

volatile

plaintext

复制

unsigned

plaintext

复制

signed

是三个关键的关键字,它们的用途和场景如下:


1.

plaintext

复制

volatile

关键字

作用
  • 禁止编译器优化:告诉编译器该变量的值可能随时被外部因素(如硬件、中断、多线程等)改变,要求每次访问变量时都直接从内存中读取,而不是使用寄存器中的缓存值。
  • 保证内存可见性:确保变量的读写操作直接作用于内存,避免因编译器优化导致时序错误。
使用场景
  • 硬件寄存器操作
    STM32的寄存器(如

    plaintext

    复制

    GPIOx->ODR

    plaintext

    复制

    TIMx->CNT
    )必须用

    plaintext

    复制

    volatile
    修饰,因为它们的值由硬件直接修改。

    复制代码

    c

    复制

    volatile uint32_t *pReg = (volatile uint32_t*)0x40020000; // 硬件寄存器地址

  • 中断服务程序(ISR)中的共享变量
    如果变量在主循环和ISR中被共同修改,必须用

    plaintext

    复制

    volatile
    修饰,确保双方看到的变量值一致。

    复制代码

    c

    复制

    volatile uint8_t flag = 0; // 在中断中修改,在主循环中读取

  • 多线程/RTOS中的共享数据
    在实时操作系统(如FreeRTOS)中,任务间共享的变量需要

    plaintext

    复制

    volatile
    修饰(通常还需配合互斥锁)。

注意事项
  • 过度使用 plaintext

    复制

    volatile
    可能导致性能下降(频繁内存访问)。

  • 不能替代原子操作或多线程同步机制(如互斥锁)。


2.

plaintext

复制

unsigned

plaintext

复制

signed

关键字

作用
  • 指定整型的符号性
    • plaintext

      复制

      unsigned
      :无符号整数(范围:

      plaintext

      复制

      0

      plaintext

      复制

      2^n - 1
      )。

    • plaintext

      复制

      signed
      :有符号整数(范围:

      plaintext

      复制

      -2^(n-1)

      plaintext

      复制

      2^(n-1) - 1
      )。

      plaintext

      复制

      n
      为类型位数,如

      plaintext

      复制

      uint32_t
      是32位)

使用场景

plaintext

复制

unsigned
的典型场景

  • 硬件相关数据
    ADC采样值(如

    plaintext

    复制

    uint16_t adc_value
    )、定时器计数值(

    plaintext

    复制

    TIMx->CNT
    )等不会为负的值。

  • 位操作
    无符号数右移时高位补0,适合位掩码操作(如

    plaintext

    复制

    GPIO引脚控制
    )。

  • 避免溢出
    当数值可能超过有符号类型的正最大值时(如32位计数器的

    plaintext

    复制

    0xFFFFFFFF
    )。

plaintext

复制

signed
的典型场景

  • 需要负值的场景
    如温度传感器读数(

    plaintext

    复制

    int16_t temperature
    )、电机速度方向(正/负表示方向)。

  • 数学运算
    涉及负数的计算(如滤波算法、PID控制)。

注意事项
  • 默认情况下, plaintext

    复制

    int

    plaintext

    复制

    signed
    ,但

    plaintext

    复制

    char
    的符号性取决于编译器(建议显式声明)。

  • 混合使用 plaintext

    复制

    unsigned

    plaintext

    复制

    signed
    可能导致意外的类型提升和逻辑错误:

    复制代码

    c

    复制

    uint32_t a = 5; int32_t b = -10; if (a > b) { ... } // 这里b会被隐式转换为无符号数,导致比较结果错误!


3. 在STM32中的典型代码示例

硬件寄存器操作(必须用

plaintext

复制

volatile

):

复制代码

c

复制

// 定义一个GPIO输出寄存器(volatile + unsigned) volatile uint32_t *GPIOA_ODR = (volatile uint32_t*)0x40020014; *GPIOA_ODR |= 0x00000001; // 设置PA0引脚为高电平

中断服务程序中的共享变量:
复制代码

c

复制

volatile uint8_t data_ready = 0; // 主循环和UART中断共享 // 中断服务函数 void USART1_IRQHandler(void) { data_ready = 1; // 数据到达时置位标志 } // 主循环中等待标志 while (1) { if (data_ready) { process_data(); data_ready = 0; } }

使用无符号类型处理ADC数据:
复制代码

c

复制

uint16_t adc_value = 0; // ADC采样值(0-4095,无符号) adc_value = HAL_ADC_GetValue(&hadc1); // 读取ADC值

使用有符号类型处理温度数据:
复制代码

c

复制

int16_t temperature = -25; // 温度可能为负 if (temperature < 0) { heating_enable(); }


总结表

关键字 作用 典型场景
plaintext 复制 volatile 防止编译器优化,保证内存可见性 硬件寄存器、中断共享变量、多线程
plaintext 复制 unsigned 无符号整数(0到最大值) ADC采样、定时器计数、位操作
plaintext 复制 signed 有符号整数(含负数) 温度、速度方向、需要负值的计算

合理使用这些关键字可以避免嵌入式开发中常见的硬件操作错误、数据溢出和逻辑问题。

相关推荐
O。o.尊都假都1 分钟前
STM32之中断
stm32·单片机·嵌入式硬件
学习噢学个屁42 分钟前
基于51单片机教室红外计数灯光控制—可蓝牙控制
c语言·单片机·嵌入式硬件·51单片机
AidLux2 小时前
智能IoT未来与边缘生态共建 | 2025 高通边缘智能创新应用大赛第六场公开课来袭!
物联网
电极限2 小时前
一个实际电路的原理图是怎样设计出来的?附带案例流程图!
人工智能·单片机·嵌入式硬件·支持向量机·动态规划
0xCC说逆向4 小时前
Windows逆向工程提升之IMAGE_SECTION_HEADER
汇编·windows·单片机·嵌入式硬件·安全·逆向工程·pe结果
芯眼4 小时前
STM32库函数简介(重点)
数据库·c++·stm32·单片机·嵌入式硬件
hallo-ooo4 小时前
【STM32】自定义打印函数
stm32
zskj_zhyl4 小时前
七彩喜社区养老体验店:创新养老服务的探索与实践
人工智能·科技·物联网
wenchm13 小时前
细说STM32单片机FreeRTOS将任务通知用作计数信号量的方法及其应用实例
stm32·单片机·嵌入式硬件