ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用 rust 开发 stm32:stm32f3discovery-serial-rtic

2021-06-19 23:02:54  阅读:265  来源: 互联网

标签:mut tx rtic stm32 gpioa let dp serial rust


更多分享内容可访问我的个人博客

https://www.niuiic.top/

本系列教程全部置于stm32专栏

本例程参考stm32fxxx-hal crate(如stm32f1xx-hal)官方例程,并在官方例程的基础上增加了一些注释,修正了一些错误。可以借鉴不同型号的 stm32 例程,毕竟固件库的核是一样的。

Since tx, tx_buf, tx_channel will be moved in use, I have not found a way to use USART with DMA and Interrupt.

Serial

#![no_main]
#![no_std]

use hal::{pac, prelude::*, serial::Serial};
use panic_semihosting as _;
use rtic::app;
use stm32f3xx_hal as hal;

#[app(device = stm32f3xx_hal::pac, peripherals = true)]
const APP: () = {
    struct Resources {}

    #[init]
    fn init(cx: init::Context) {
        let dp: pac::Peripherals = cx.device;
        let mut rcc = dp.RCC.constrain();
        let clock = rcc
            .cfgr
            .sysclk(48_u32.MHz())
            .freeze(&mut dp.FLASH.constrain().acr);
        let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);

        let pins = (
            gpioa
                .pa9
                .into_af7_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh),
            gpioa
                .pa10
                .into_af7_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh),
        );

        let mut serial = Serial::usart1(dp.USART1, pins, 9600_u32.Bd(), clock, &mut rcc.apb2);

        let mut send: u8 = 'a' as u8;

        serial.write(send).unwrap();

        send = 'b' as u8;

        // Wait for the first send operation complete.
        cortex_m::asm::delay(10000000);

        // serial can be used multiple times.
        serial.write(send).unwrap();

        let (mut tx, _rx) = serial.split();

        cortex_m::asm::delay(10000000);

        // tx can also be used multiple times.
        tx.write(send).unwrap();

        cortex_m::asm::delay(10000000);

        tx.write(send).unwrap();
    }

    #[idle]
    fn idle(_cx: idle::Context) -> ! {
        loop {
            cortex_m::asm::nop();
        }
    }
};

Serial with DMA

#![no_main]
#![no_std]

use cortex_m::singleton;
use cortex_m_semihosting::hprintln;
use hal::{pac, prelude::*, serial::Serial};
use panic_semihosting as _;
use rtic::app;
use stm32f3xx_hal as hal;

#[app(device = stm32f3xx_hal::pac, peripherals = true)]
const APP: () = {
    struct Resources {}

    #[init]
    fn init(cx: init::Context) {
        let dp: pac::Peripherals = cx.device;
        let mut rcc = dp.RCC.constrain();
        let clock = rcc
            .cfgr
            .sysclk(48_u32.MHz())
            .freeze(&mut dp.FLASH.constrain().acr);
        let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);

        let pins = (
            gpioa
                .pa9
                .into_af7_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh),
            gpioa
                .pa10
                .into_af7_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh),
        );

        let serial = Serial::usart1(dp.USART1, pins, 9600_u32.Bd(), clock, &mut rcc.apb2);

        let (tx, rx) = serial.split();

        let dma1 = dp.DMA1.split(&mut rcc.ahb);

        let tx_buf = singleton!(:[u8;8]=*b"hello321").unwrap();

        let rx_buf = singleton!(:[u8;8]=[0;8]).unwrap();

        let (tx_channel, rx_channel) = (dma1.ch4, dma1.ch5);

        // tx, tx_buf, tx_channel will be moved here.
        // The data will be sent here.
        let sending = tx.write_all(tx_buf, tx_channel);
        // The data will not be read here.
        let receiving = rx.read_exact(rx_buf, rx_channel);

        // tx, tx_buf, tx_channel are regenerated here.
        // Method `wait` waits for the send operation complete.
        let (_tx_buf, _tx_channel, _tx) = sending.wait();
        // Wait for data to be received.
        let (rx_buf, _rx_channel, _rx) = receiving.wait();

        for i in 0..rx_buf.len() {
            hprintln!("{}", rx_buf[i] as char).unwrap();
        }
    }

    #[idle]
    fn idle(_cx: idle::Context) -> ! {
        loop {
            cortex_m::asm::nop();
        }
    }
};

Serial with Interrupt

#![no_main]
#![no_std]

use cortex_m_semihosting::hprintln;
use hal::{
    gpio::{self, PushPull, AF7},
    pac::USART1,
    prelude::*,
    rcc::RccExt,
    serial::{Event, Serial},
};

use panic_semihosting as _;
use stm32f3xx_hal as hal;

type SerialType = Serial<
    USART1,
    (
        gpio::gpioa::PA9<AF7<PushPull>>,
        gpio::gpioa::PA10<AF7<PushPull>>,
    ),
>;

#[rtic::app(device = stm32f3xx_hal::pac, peripherals = true)]
const APP: () = {
    struct Resources {
        serial: SerialType,
    }

    #[init]
    fn init(cx: init::Context) -> init::LateResources {
        let dp: hal::pac::Peripherals = cx.device;
        let mut rcc = dp.RCC.constrain();
        let clocks = rcc
            .cfgr
            .sysclk(48_u32.MHz())
            .freeze(&mut dp.FLASH.constrain().acr);
        let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);

        let pins = (
            gpioa
                .pa9
                .into_af7_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh),
            gpioa
                .pa10
                .into_af7_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh),
        );

        let mut serial = Serial::usart1(dp.USART1, pins, 9600_u32.Bd(), clocks, &mut rcc.apb2);

        serial.listen(Event::Rxne);

        init::LateResources { serial }
    }

    #[task(binds = USART1_EXTI25, resources = [serial])]
    fn serial(cx: serial::Context) {
        let serial: &mut SerialType = cx.resources.serial;

        if serial.is_rxne() {
            serial.unlisten(Event::Rxne);
            match serial.read() {
                Ok(byte) => {
                    serial.write(byte).unwrap();
                    serial.listen(Event::Tc);
                    // This will cause a few millisecond to execute the function.
                    // And this will result in partial data not being received.
                    // hprintln!("{}", byte as char).unwrap();
                }

                Err(_error) => {
                    hprintln!("read error").unwrap();
                }
            }
        }

        if serial.is_tc() {
            serial.unlisten(Event::Tc);
            serial.listen(Event::Rxne);
        }
    }
};

标签:mut,tx,rtic,stm32,gpioa,let,dp,serial,rust
来源: https://blog.csdn.net/niuiic/article/details/118060501

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有