画龙点睛:可能是厂商等公司之类的组织, 简化cortex-m 开发, 与特定的硬件绑定。


包引入,

stm32f1xx-hal

GPIO(General Purpose Input/Output)是一种可编程的数字信号引脚,用于微控制器和微处理器与外部设备进行交互。

  • 功能:
    输入: GPIO 可以配置为输入模式,读取外部信号的状态(例如按钮、开关或传感器)。
    输出: GPIO 可以配置为输出模式,向外部设备发送信号(例如点亮 LED、驱动继电器)。
    可编程: GPIO 的功能可以通过软件进行配置,可以根据需要设置为输入或输出,并可以选择不同的逻辑电平。
    中断: 一些 GPIO 引脚可以配置为中断源,响应外部事件(例如,按下按钮时触发中断)。
  • 常见应用:
    控制 LED 灯、继电器或其他电器。
    读取按钮或开关的状态。
    接收传感器信号,例如温度、湿度等。

同样是点亮led:

#![allow(clippy::empty_loop)]
#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m::delay::Delay;
use cortex_m::peripheral::SYST;
use panic_halt as _;

use cortex_m_rt::entry;
use stm32f1xx_hal::{pac, prelude::*};

#[entry]
fn main() -> ! {
    ///获取微控制器的外设实例 p,所有硬件外设的访问都是通过这个实例进行。
    let p = pac::Peripherals::take().unwrap();
    ///获取 GPIOC 的控制,将其拆分为更具体的控制结构,用于访问各个引脚
    let mut gpioc = p.GPIOC.split();
    // 获取 FLASH 和 RCC
    let mut flash = p.FLASH.constrain();
    let mut rcc = p.RCC.constrain();

    ///用条件编译(cfg)功能,根据启用的特性设置 GPIO 引脚的状态。
    /// 如果启用了 stm32f100 特性,则将 PC9 引脚设置为推挽输出并设置为高电平。
    // #[cfg(feature = "stm32f100")]
    // gpioc.pc9.into_push_pull_output(&mut gpioc.crh).set_high();
    //
    // #[cfg(feature = "stm32f101")]
    // gpioc.pc9.into_push_pull_output(&mut gpioc.crh).set_high();
    //
     // #[cfg(any(feature = "stm32f103", feature = "stm32f105", feature = "stm32f107"))]
    // gpioc.pc13.into_push_pull_output(&mut gpioc.crh).set_low();

    // 根据特性选择用于 LED 的引脚
    // 使用 `let` 语句将引脚的信息动态分析放在一个一起
    let mut led = if cfg!(feature = "stm32f103") || cfg!(feature = "stm32f105") || cfg!(feature = "stm32f107") {
        gpioc.pc13.into_push_pull_output(&mut gpioc.crh).unwrap() // 使用 PC13
    } else {
        gpioc.pc9.into_push_pull_output(&mut gpioc.crh).unwrap() // 使用 PC9
    };
    let clocks = rcc.cfgr.freeze(&mut flash.acr);


    let mut delay = Delay::new(SYST::take().unwrap(), clocks); // 获取 SYST

    loop {
        // 切换 LED 状态
        led.set_high().unwrap();
        delay.delay_ms(500_u32); // 等待 500 毫秒
        led.set_low().unwrap();
        delay.delay_ms(500_u32); // 等待 500 毫秒
    }
}

GPIO(通用输入/输出)引脚在嵌入式系统中用途广泛,除了控制 LED 外,还有许多其他功能和应用。以下是一些常见的使用场景:

  1. 开关控制
    通过 GPIO 控制电源开关,打开或关闭设备(如继电器)。
  2. 按键输入
    读取按钮或开关的状态,例如单击、双击等。这在用户界面中非常常见。
  3. 信号检测
    读取传感器的输出,例如温度传感器、湿度传感器或光传感器,获取环境数据。
  4. PWM 输出
    通过 GPIO 生成脉宽调制信号,控制电机速度或 LED 亮度。
  5. 中断处理
    配置 GPIO 引脚作为中断源,响应外部事件(例如按钮按下时触发中断)。
  6. 通信接口
    一些 GPIO 引脚可以配置为串行通信接口,如 UART、I2C、SPI 等,进行数据传输。
  7. 状态指示
    使用 GPIO 控制状态指示灯,显示系统的工作状态或故障提示。
  8. 数据采集
    通过 GPIO 接收外部设备(如传感器或模块)的数字信号进行数据采集。
  9. 控制外部设备
    驱动蜂鸣器、风扇或其他外部电器设备的开关。
  10. 模拟输入(ADC)
    一些 GPIO 引脚可以配置为模拟输入,用于连接模拟传感器并读取其输出值。
  11. 通信协议支持
    GPIO 可以用于实现各种协议,如 1-Wire、I2C、SPI、UART 等,以连接外部模块或传感器。

ADC(Analog-to-Digital Converter)是一种电子设备,用于将模拟信号转换为数字信号,使微控制器可以处理和分析这些信号。

  • 功能:
    模拟输入: ADC 能够接收连续的模拟电压信号(如从传感器输出的电压)。
    转换: ADC 将模拟信号转换为相应的数字值,以便微控制器进行处理。
    分辨率: ADC 的分辨率通常以比特(例如 8-bit、10-bit、12-bit 等)来表示,分辨率越高,能够区分的电压变化越小。
  • 常见应用:

读取温度传感器、光传感器或其他模拟传感器的输出电压。
实现音频信号处理,将音频信号转换为数字形式进行处理。
控制系统中的电压监测,例如电池电量检测。


#![no_std]
#![no_main]

use panic_halt as _;
use cortex_m_rt::entry;
use stm32f1xx_hal::{adc, pac, prelude::*};
use cortex_m_semihosting::hprintln;

const LIGHT_THRESHOLD: u16 = 200; // 设置光照阈值

#[entry]
fn main() -> ! {
    // 获取外设
    let p = pac::Peripherals::take().unwrap();
    let mut flash = p.FLASH.constrain();
    let rcc = p.RCC.constrain();

    // 配置 ADC 时钟
    let clocks = rcc.cfgr.adcclk(2.MHz()).freeze(&mut flash.acr);

    // 初始化 ADC
    let mut adc1 = adc::Adc::adc1(p.ADC1, clocks);

    // 初始化 GPIO
    let mut gpiob = p.GPIOB.split();
    let mut gpioc = p.GPIOC.split();

    // 将 PB0 配置为模拟输入
    let mut ldr_pin = gpiob.pb0.into_analog(&mut gpiob.crl);

    // 将 PC13 配置为推挽输出 (用于控制 LED)
    let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);

    loop {
        // 读取光传感器的值
        let light_value: u16 = adc1.read(&mut ldr_pin).unwrap();
        hprintln!("Light Value: {}", light_value).unwrap();

        // 根据光照值控制 LED
        if light_value < LIGHT_THRESHOLD {
            led.set_high().unwrap(); // 光照低,打开 LED
        } else {
            led.set_low().unwrap();  // 光照足够,关闭 LED
        }

        // 可选的延迟,避免过于频繁读取
        cortex_m::asm::delay(1_000_000);
    }
}

#![deny(unsafe_code)]
#![no_main]
#![no_std]

use panic_semihosting as _;

use cortex_m_rt::entry;
use stm32f1xx_hal::{adc, pac, prelude::*};

use cortex_m_semihosting::hprintln;

#[entry]
fn main() -> ! {
    // Acquire peripherals
    let p = pac::Peripherals::take().unwrap();
    ///是闪存控制器的约束配置,用于后续时钟设置。
    let mut flash = p.FLASH.constrain();
    ///是时钟控制器的约束配置,用于配置系统时钟和 ADC 时钟。
    let rcc = p.RCC.constrain();

    // Configure ADC clocks
    // Default value is the slowest possible ADC clock: PCLK2 / 8. Meanwhile ADC
    // clock is configurable. So its frequency may be tweaked to meet certain
    // practical needs. User specified value is be approximated using supported
    // prescaler values 2/4/6/8.
    let clocks = rcc.cfgr.adcclk(2.MHz()).freeze(&mut flash.acr);
    //hprintln! 用于半主机环境下打印 ADC 时钟频率。
    hprintln!("adc freq: {}", clocks.adcclk());

    // Setup ADC
    let mut adc1 = adc::Adc::adc1(p.ADC1, clocks);

    #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
        let mut adc2 = adc::Adc::adc2(p.ADC2, clocks);

    // Setup GPIOB
    ///GPIOB: 这是微控制器上一个具体的 GPIO 端口,通常有多个端口,如 GPIOA、GPIOB 等。每个端口包含多个引脚(比如 PA0, PA1, PB0, PB1等)。
    /// 引脚: 在这个例子中,pb0 表示 GPIOB 上的第0个引脚。类似地,pb1 就是 GPIOB 的第1个引脚。
    let mut gpiob = p.GPIOB.split();

    // Configure pb0, pb1 as an analog input
    ///将指定的引脚(在这里是 pb0)配置为模拟输入模式
    /// 在 STM32 系列微控制器中,每个 GPIO 端口都有一个控制寄存器,通常分为两个部分:CRL 和 CRH。
    /// gpiob.crl 控制的是引脚 0 到引脚 7(低位端)。
    /// gpiob.crh 控制的是引脚 8 到引脚 15(高位端)。
    let mut ch0 = gpiob.pb0.into_analog(&mut gpiob.crl);

    #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
        let mut ch1 = gpiob.pb1.into_analog(&mut gpiob.crl);

    loop {
        let data: u16 = adc1.read(&mut ch0).unwrap();
        hprintln!("adc1: {}", data);

        #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
        {
            let data1: u16 = adc2.read(&mut ch1).unwrap();
            hprintln!("adc2: {}", data1);
        }
    }
}


putao
8 声望1 粉丝

推动世界向前发展,改善民生。