Rust嵌入式开发库atsame54p的使用,针对ATSAME54P微控制器的硬件抽象层(HAL)和外设驱动支持

ATSAME54P

ATSAME54P是一个针对Microchip(原Atmel)ATSAME54P芯片的外设访问库,用于Rust嵌入式项目。

Build Status Crates.io

文档

这个源代码是通过svd2rust自动生成的,使用form分割成更小的部分,并通过rustfmt进行格式化。

许可证

采用以下任一种许可证:

  • Apache License, Version 2.0
  • MIT license

贡献

除非您明确声明,否则任何有意提交的贡献都将按照上述双重许可证授权,不附加任何额外条款或条件。

示例代码

以下是一个使用atsame54p库进行ATSAME54P微控制器开发的基本示例:

#![no_std]
#![no_main]

use atsame54p as pac;
use panic_halt as _;

#[cortex_m_rt::entry]
fn main() -> ! {
    // 获取设备外设访问实例
    let dp = pac::Peripherals::take().unwrap();
    
    // 配置时钟
    let _clocks = atsame54p_hal::clock::GenericClockController::with_external_32kosc(
        dp.GCLK,
        &mut dp.MCLK,
        &mut dp.OSC32KCTRL,
        &mut dp.OSCCTRL,
        &mut dp.NVMCTRL,
    );
    
    // 配置引脚
    let pins = atsame54p_hal::Pins::new(dp.PORT);
    
    // 配置LED引脚为输出
    let mut led = pins.pa15.into_push_pull_output();
    
    loop {
        // 切换LED状态
        led.toggle();
        
        // 简单延时
        cortex_m::asm::delay(8_000_000);
    }
}

更完整的示例 - 使用串口通信

#![no_std]
#![no_main]

use atsame54p as pac;
use atsame54p_hal as hal;
use panic_halt as _;

use core::fmt::Write;
use hal::clock::GenericClockController;
use hal::delay::Delay;
use hal::prelude::*;
use hal::serial::{self, Serial};

#[cortex_m_rt::entry]
fn main() -> ! {
    // 获取设备外设
    let mut peripherals = pac::Peripherals::take().unwrap();
    let mut core = pac::CorePeripherals::take().unwrap();
    
    // 配置时钟
    let mut clocks = GenericClockController::with_external_32kosc(
        peripherals.GCLK,
        &mut peripherals.MCLK,
        &mut peripherals.OSC32KCTRL,
        &mut peripherals.OSCCTRL,
        &mut peripherals.NVMCTRL,
    );
    
    // 初始化延时
    let mut delay = Delay::new(core.SYST, &mut clocks);
    
    // 配置引脚
    let pins = hal::Pins::new(peripherals.PORT);
    
    // 配置串口通信
    let tx = pins.pa04.into_function_c();
    let rx = pins.pa05.into_function_c();
    
    let mut uart = Serial::sercom0(
        peripherals.SERCOM0,
        (tx, rx),
        &mut peripherals.MCLK,
        115200.hz(),
        serial::Mode::Async,
        &mut clocks,
    );
    
    // 发送欢迎消息
    writeln!(uart, "ATSAME54P UART Example\r").unwrap();
    
    loop {
        // 发送计数消息
        writeln!(uart, "Counter: {}\r", 42).unwrap();
        
        // 延时1秒
        delay.delay_ms(1000u16);
    }
}

以上示例展示了ATSAME54P库的基本使用方法,包括:

  1. 时钟配置
  2. GPIO控制
  3. 串口通信
  4. 延时功能

可以根据具体需求扩展这些基础功能,如添加中断处理、使用其他外设等。

完整示例 - PWM控制LED亮度

#![no_std]
#![no_main]

use atsame54p as pac;
use atsame54p_hal as hal;
use panic_halt as _;

use hal::clock::GenericClockController;
use hal::pwm::Pwm0;
use hal::time::U32Ext;

#[cortex_m_rt::entry]
fn main() -> ! {
    // 获取设备外设
    let mut peripherals = pac::Peripherals::take().unwrap();
    let mut core = pac::CorePeripherals::take().unwrap();
    
    // 配置时钟
    let mut clocks = GenericClockController::with_external_32kosc(
        peripherals.GCLK,
        &mut peripherals.MCLK,
        &mut peripherals.OSC32KCTRL,
        &mut peripherals.OSCCTRL,
        &mut peripherals.NVMCTRL,
    );
    
    // 配置引脚
    let pins = hal::Pins::new(peripherals.PORT);
    
    // 配置PWM引脚
    let pwm_pin = pins.pa05.into_function_c();
    
    // 创建PWM实例
    let mut pwm = Pwm0::new(
        peripherals.TCC0,
        &mut peripherals.MCLK,
        &mut clocks,
        1.khz(),
        pwm_pin,
    );
    
    let max_duty = pwm.get_max_duty();
    
    // 呼吸灯效果
    loop {
        // 渐亮
        for i in 0..max_duty {
            pwm.set_duty(i);
            cortex_m::asm::delay(10_000);
        }
        
        // 渐暗
        for i in (0..max_duty).rev() {
            pwm.set_duty(i);
            cortex_m::asm::delay(10_000);
        }
    }
}

这个完整示例展示了如何使用ATSAME54P库实现PWM控制LED亮度,创建呼吸灯效果。主要功能包括:

  1. 初始化PWM外设
  2. 配置PWM频率
  3. 动态调整占空比
  4. 实现平滑的亮度变化效果

1 回复

Rust嵌入式开发库atsame54p的使用指南

介绍

atsame54p是一个针对Microchip(原Atmel)ATSAME54P系列微控制器的Rust硬件抽象层(HAL)库。它提供了对外设的Rust接口支持,使开发者能够在Rust语言环境下进行ATSAME54P微控制器的嵌入式开发。

该库基于embedded-hal和atsamd-hal构建,提供了对ATSAME54P系列芯片的完整支持,包括:

  • GPIO控制
  • 定时器
  • 串口通信
  • SPI/I2C接口
  • ADC/DAC
  • PWM输出
  • 以及其他片上外设

使用方法

1. 添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
atsame54p = "0.1"
cortex-m = "0.7"
cortex-m-rt = "0.7"

2. 基本使用示例

#![no_std]
#![no_main]

use atsame54p as pac;
use atsame54p::hal;
use hal::clock::GenericClockController;
use hal::delay::Delay;
use hal::prelude::*;
use hal::time::Hertz;
use pac::Peripherals;

#[cortex_m_rt::entry]
fn main() -> ! {
    // 获取外围设备
    let mut peripherals = Peripherals::take().unwrap();
    let mut core = pac::CorePeripherals::take().unwrap();
    
    // 初始化时钟
    let mut clocks = GenericClockController::with_internal_32kosc(
        peripherals.GCLK,
        &mut peripherals.MCLK,
        &mut peripherals.OSC32KCTRL,
        &mut peripherals.OSCCTRL,
        &mut peripherals.NVMCTRL,
    );
    
    // 创建延时实例
    let mut delay = Delay::new(core.SYST, &mut clocks);
    
    // 获取PORT外设
    let pins = hal::Pins::new(peripherals.PORT);
    
    // 配置LED引脚为输出
    let mut led = pins.pb10.into_push_pull_output();
    
    loop {
        // 翻转LED状态
        led.toggle().unwrap();
        delay.delay_ms(500u16);
    }
}

3. 外设使用示例

GPIO控制

use atsame54p::hal::gpio::IntoPushPullOutput;
use atsame54p::hal::prelude::*;

// 初始化后
let pins = hal::Pins::new(peripherals.PORT);
let mut output_pin = pins.pa15.into_push_pull_output();
let input_p极引脚为输出
    let mut led = pins.pb10.into_push_pull_output();
    
    // 配置UART通信
    let gclk0 = clocks.gclk0();
    let uart_clock = &clocks.sercom0_core(&gclk0).unwrap();
    let uart_pads = hal::sercom::Sercom0Paduart {
        tx: pins.pa04.into_pad(),
        rx: pins.pa05.into_pad(),
    };
    let mut uart = UART::new(
        peripherals.SERCOM0,
        uart_pads,
        uart_clock.freq(),
        Bps(115200),
        &mut peripherals.MCLK,
    );
    
    // 配置PWM输出
    let pwm_clock = &clocks.tc0_tc1(&gclk0).unwrap();
    let pwm_pin = pins.pa12.into_function_e();
    let mut pwm = Pwm0::new(
        peripherals.TC0,
        TC0Pinout::Pa12(pwm_pin),
        pwm_clock.freq(),
        Hertz(1000),
        &mut peripherals.MCLK,
    );
    pwm.set_duty(50); // 设置占空比为50%
    
    // 启用中断
    unsafe {
        NVIC::unmask(interrupt::SERCOM0);
    }
    
    let mut counter = 0;
    loop {
        // 翻转LED状态
        led.toggle().unwrap();
        
        // 通过UART发送数据
        uart.write(b'H').unwrap();
        uart.write(b'e').unwrap();
        uart.write(b'l').unwrap();
        uart.write(b'l').unwrap();
        uart.write(b'o').unwrap();
        uart.write(b'\n').unwrap();
        
        // 调整PWM占空比
        pwm.set_duty(counter % 100);
        counter += 1;
        
        // 延时500ms
        delay.delay_ms(500u16);
    }
}

#[interrupt]
fn SERCOM0() {
    // UART中断处理
}

这个完整示例演示了如何:

  1. 初始化系统时钟和基本外设
  2. 控制GPIO引脚(LED闪烁)
  3. 配置和使用UART通信
  4. 设置PWM输出
  5. 启用中断处理

您可以根据实际硬件连接修改引脚配置,并添加更多外设功能。

回到顶部