Rust嵌入式开发库pic32-hal的使用,PIC32微控制器硬件抽象层(HAL)驱动开发
pic32-hal
一个针对部分PIC32微控制器的硬件抽象层。
这个crate在PAC crate实现的寄存器访问API基础上提供了一个薄的低级API。提供以下HAL功能:
- 基本时钟控制,包括参考时钟发生器
- GPIO
- UART
- USB
- 访问MIPS核心计时器
- DMA通道
- I2C外设
- SPI外设
- 中断控制器
- 外设引脚选择(PPS)
- 10位模数转换器(ADC)
- 定时器
- 输出比较
部分模块实现了embedded-hal API,这样使用该API的设备驱动(如显示器驱动)可以访问PIC32外设。
所有功能都还在开发中。
示例代码
以下是一个使用pic32-hal进行GPIO控制的完整示例:
// 导入必要的crate
use pic32_hal as hal;
use embedded_hal::digital::v2::OutputPin;
use hal::pac;
// 主函数
fn main() -> ! {
// 获取外设访问权限
let dp = pac::Peripherals::take().unwrap();
// 初始化系统时钟
let clocks = hal::clock::Clocks::new(dp.OSC);
// 配置GPIO
let gpioa = hal::gpio::Gpio::new(dp.PORTA);
// 将PA0配置为输出引脚
let mut led = gpioa.pa0.into_output();
loop {
// 切换LED状态
led.set_high().unwrap();
hal::delay(clocks.sysclk().0 / 2);
led.set_low().unwrap();
hal::delay(clocks.sysclk().0 / 2);
}
}
UART示例
下面是一个使用UART进行串口通信的示例:
use pic32_hal as hal;
use hal::pac;
use hal::uart;
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let clocks = hal::clock::Clocks::new(dp.OSC);
// 初始化UART1
let uart1 = uart::Uart::new(
dp.UART1,
115200.bps(),
clocks,
);
// 发送字符串
uart1.write(b"Hello, PIC32!\r\n").unwrap();
loop {
// 接收数据
if let Ok(byte) = uart1.read() {
// 回显接收到的数据
uart1.write(&[byte]).unwrap();
}
}
}
完整ADC示例
下面是一个使用ADC进行模拟信号采集的完整示例:
use pic32_hal as hal;
use hal::pac;
fn main() -> ! {
// 获取外设访问权限
let dp = pac::Peripherals::take().unwrap();
// 初始化系统时钟
let clocks = hal::clock::Clocks::new(dp.OSC);
// 初始化ADC模块
let mut adc = hal::adc::Adc::new(dp.ADC, &clocks);
// 配置ADC通道0
let channel = hal::adc::Channel::new(0);
loop {
// 启动ADC转换
let value = adc.read(&channel).unwrap();
// 处理ADC采样值
// ...
// 简单延时
hal::delay(clocks.sysclk().0 / 1000);
}
}
安装
在项目目录中运行以下Cargo命令:
cargo add pic32-hal
或在Cargo.toml中添加以下行:
pic32-hal = "0.13.0"
许可证
MIT OR Apache-2.0
1 回复
Rust嵌入式开发库pic32-hal的使用指南
简介
pic32-hal是一个用于PIC32微控制器系列的硬件抽象层(HAL)库,它提供了访问PIC32微控制器外设的Rust接口。这个库是建立在embedded-hal
标准之上的,使得开发者可以使用Rust进行PIC32微控制器的嵌入式开发。
主要特性
- 支持多种PIC32微控制器型号
- 提供GPIO、UART、SPI、I2C等常见外设的抽象
- 基于
embedded-hal
标准实现 - 中断处理支持
- 时钟配置功能
使用方法
1. 添加依赖
首先在项目的Cargo.toml
中添加依赖:
[dependencies]
pic32-hal = "0.1" # 请使用最新版本
cortex-m = "0.7"
embedded-hal = "0.2"
2. 基本初始化
#![no_std]
#![no_main]
use pic32_hal::pac;
use pic32_hal::prelude::*;
use panic_halt as _;
#[entry]
fn main() -> ! {
// 获取设备外设访问权
let dp = pac::Peripherals::take().unwrap();
// 初始化时钟
let clocks = pic32_hal::clock::ClockSetup::new(dp.OSC, dp.DEVCFG)
.sys_clock(80.mhz())
.freeze();
// 获取GPIO端口
let mut ports = pic32_hal::gpio::Ports::new(dp.PORTS);
// 配置LED引脚为输出
let mut led = ports.ra0.into_output();
loop {
// 翻转LED状态
led.toggle().unwrap();
pic32_hal::delay::delay_ms(1000);
}
}
3. GPIO使用示例
// 配置按钮输入和LED输出
let button = ports.rb4.into_input();
let mut led = ports.ra1.into_output();
loop {
if button.is_high().unwrap() {
led.set_high().unwrap();
} else {
led.set_low().unwrap();
}
}
4. UART通信示例
// 初始化UART
let mut uart = pic32_hal::uart::Uart::new(
dp.UART1,
(ports.rb10.into_alternate(), ports.rb7.into_alternate()),
pic32_hal::uart::Config::default()
.baudrate(115200.bps())
.clock(clocks),
);
// 发送数据
uart.write(b"Hello from PIC32!\r\n").unwrap();
// 接收数据
let mut buf = [0u8; 32];
let len = uart.read(&mut buf).unwrap();
5. 中断处理示例
use pic32_hal::interrupt;
// 定义中断处理函数
#[interrupt]
fn TIMER1() {
// 中断处理逻辑
unsafe {
(*pac::TIMER1::ptr()).intr.clear_bit();
}
}
// 在主函数中配置和启用中断
pic32_hal::interrupt::enable_interrupt(
pic32_hal::interrupt::Interrupt::TIMER1,
pic32_hal::interrupt::Priority::P3,
);
注意事项
- 确保你的PIC32芯片型号被该库支持
- 需要正确配置链接器脚本和内存布局
- 某些功能可能需要特定的硬件配置
- 中断处理需要小心管理共享资源
完整示例代码
以下是一个结合GPIO和UART功能的完整示例:
#![no_std]
#![no_main]
use pic32_hal::{pac, prelude::*};
use panic_halt as _;
#[entry]
fn main() -> ! {
// 初始化外设
let dp = pac::Peripherals::take().unwrap();
let clocks = pic32_hal::clock::ClockSetup::new(dp.OSC, dp.DEVCFG)
.sys_clock(80.mhz())
.freeze();
// 初始化GPIO
let mut ports = pic32_hal::gpio::Ports::new(dp.PORTS);
let mut led = ports.ra0.into_output();
let button = ports.rb4.into_input();
// 初始化UART
let mut uart = pic32_hal::uart::Uart::new(
dp.UART1,
(ports.rb10.into_alternate(), ports.rb7.into_alternate()),
pic32_hal::uart::Config::default()
.baudrate(115200.bps())
.clock(clocks),
);
// 发送欢迎消息
uart.write(b"PIC32 Rust HAL Demo Started\r\n").unwrap();
loop {
// 读取按钮状态并控制LED
if button.is_high().unwrap() {
led.set_high().unwrap();
uart.write(b"Button pressed\r\n").unwrap();
} else {
led.set_low().unwrap();
}
// 延时防止过于频繁的检测
pic32_hal::delay::delay_ms(100);
}
}
这个示例演示了如何同时使用GPIO和UART功能,实现按钮控制LED并通过串口发送状态信息的功能。