首页 > 其他分享 >esp32笔记[9]-rust的串口收发及GCODE解析

esp32笔记[9]-rust的串口收发及GCODE解析

时间:2023-10-26 13:11:30浏览次数:65  
标签:end LEVEL GCODE esp32 subcommand part 串口 println integer

摘要

使用rust在no-std环境下实现esp32-c3串口收发及gcode解析.

平台信息

  • esp32c3
  • rust

超链接

esp32笔记[7]-使用rust+zig开发入门

使用rust实现串口中断

示例代码:
serial_interrupts.rs

//! This shows some of the interrupts that can be generated by UART/Serial.
//! Use a proper serial terminal to connect to the board (espmonitor and
//! espflash won't work)

#![no_std]
#![no_main]

use core::{cell::RefCell, fmt::Write};

use critical_section::Mutex;
use esp32c3_hal::{
    clock::ClockControl,
    interrupt,
    peripherals::{self, Peripherals, UART0},
    prelude::*,
    riscv,
    timer::TimerGroup,
    uart::config::AtCmdConfig,
    Cpu,
    Uart,
};
use esp_backtrace as _;
use nb::block;

static SERIAL: Mutex<RefCell<Option<Uart<UART0>>>> = Mutex::new(RefCell::new(None));

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = peripherals.SYSTEM.split();
    let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

    //let mut uart0 = Uart::new(peripherals.UART0, &clocks);
    let mut uart0 = Uart::new(peripherals.UART0, &mut system.peripheral_clock_control);
    let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
    let mut timer0 = timer_group0.timer0;

    uart0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None));
    uart0.set_rx_fifo_full_threshold(30).unwrap();
    uart0.listen_at_cmd();
    uart0.listen_rx_fifo_full();

    timer0.start(1u64.secs());

    critical_section::with(|cs| SERIAL.borrow_ref_mut(cs).replace(uart0));

    interrupt::enable(
        peripherals::Interrupt::UART0,
        interrupt::Priority::Priority1,
    )
    .unwrap();
    interrupt::set_kind(
        Cpu::ProCpu,
        interrupt::CpuInterrupt::Interrupt1, // Interrupt 1 handles priority one interrupts
        interrupt::InterruptKind::Edge,
    );

    unsafe {
        riscv::interrupt::enable();
    }

    loop {
        critical_section::with(|cs| {
            writeln!(SERIAL.borrow_ref_mut(cs).as_mut().unwrap(), "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
        });

        block!(timer0.wait()).unwrap();
    }
}

#[interrupt]
fn UART0() {
    critical_section::with(|cs| {
        let mut serial = SERIAL.borrow_ref_mut(cs);
        let serial = serial.as_mut().unwrap();

        let mut cnt = 0;
        while let nb::Result::Ok(_c) = serial.read() {
            cnt += 1;
        }
        writeln!(serial, "Read {} bytes", cnt,).ok();

        writeln!(
            serial,
            "Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
            serial.at_cmd_interrupt_set(),
            serial.rx_fifo_full_interrupt_set(),
        )
        .ok();

        serial.reset_at_cmd_interrupt();
        serial.reset_rx_fifo_full_interrupt();
    });
}

GCODE简介

[https://www.sae.org/standards/content/rs274d/]
[https://bayareacircuits.com/blog/rs274d-vs-rd274x-gerber-file-format/]
GCODE是一种用于控制数控机床和3D打印机等数控设备的编程语言。在GCODE中,RS274D和RS274X是两种常见的格式。

RS274D是GCODE的早期版本,也称为基本GERBER格式。它使用坐标数据和功能码来描述运动和操作。RS274D格式的文件通常需要附带D码文件才能完整描述图形。

RS274X是GCODE的扩展版本,也称为扩展GERBER格式。它在RS274D的基础上增加了一些功能,如处理多边形填充、正负图形组合和自定义D码等。与RS274D不同,RS274X格式的文件内部包含了光圈表的信息,不需要额外的D码文件。

根据搜索结果,RS274X格式相对于RS274D格式更为常见和推荐使用。RS274X格式的文件具有更高的兼容性和便利性,因为它内部包含了光圈表的信息,无需额外的D码文件。

G代码(G-code)是一种用于控制数控机床的标准指令集。它采用文本格式,通过下发给机床控制系统,来控制机床的运动和操作。

在G代码中,以字母G开头的指令表示机床的运动控制,如轴的定位、线性或圆弧插补等。以字母M开头的指令表示机床的辅助功能和操作命令,如开关冷却液、启动或停止主轴等。

G代码的格式通常是由字母、数字和小数点组成,例如:G01、G02、G03、M03、M08等。其中,字母代表具体的功能,数字和小数点用于指定参数和数值。

G代码具有丰富的功能和应用,可以实现复杂的机床运动和工件加工。例如,通过指定不同的G代码和参数,可以实现直线或曲线的插补运动、螺旋插补、孔加工、螺纹加工、刀具补偿等操作。

G命令 M命令

实现

核心代码

src/main.rs

/*
备注:
- 使用no-std,没有常规的main函数
- 串口波特率115200
目标平台:
- esp32c3(riscv32imc)
依赖:
- esp32c3-hal(0.12.0)
- esp-backtrace(0.8.0)
- esp-println(0.6.0)
- critical_section(1.1.1)
编译及烧录命令:
- cargo-offline run
- cargo-offline build --release
*/
#![no_std]
#![no_main]
#![allow(unused_imports)]
#![allow(unused_parens)]
#![allow(unused_variables)]
#![allow(unused_unsafe)]
#![allow(dead_code)]
#![allow(unused_mut)]

/* start 与zig代码通信 */
#[link(name = "main")]
extern "C" {
    fn add(x: i32, y: i32) -> i32;
}
/* end 与zig代码通信 */

/* start 导入库 */
use esp_println::println;//串口打印
use esp_println::print;//串口打印
use core::{
    cell::RefCell, //内部可变性类型RefCell
    fmt::Write, //文本写入接口
};
use critical_section::Mutex;//no-std库专用的Mutex

use esp32c3_hal::{
    clock::ClockControl, //时钟控制
    peripherals::{self, Peripherals, TIMG0, TIMG1,UART0},//外设控制器
    prelude::*, 
    timer::{Timer, Timer0, TimerGroup},//定时器
    Rtc,//rtc时钟
    Delay,//延时
    gpio::{AnyPin,Input, Output, PullDown, PushPull, IO},//gpio相关
    systimer::SystemTimer,//系统定时器
    interrupt,//中断
    riscv,//riscv架构相关
    uart::config::AtCmdConfig,//串口解析at命令
    Cpu,//cpu相关
    Uart,//串口相关
};

use esp_backtrace as _;// 获取调用堆栈信息
use nb::block;//在异步上下文中阻塞执行代码
/* end 导入库 */

/* start 自定义类型 */
// 字符串类型
#[derive(PartialEq, Copy,Clone)]
struct MyString {
    chars: [u8; 128],  // 字符数组,可以根据实际需求调整大小
    length: usize,     // 字符串长度
}

impl MyString {
    fn new() -> MyString {
        MyString {
            chars: [0; 128],  // 初始化字符数组
            length: 0,       // 初始长度为 0
        }
    }

    fn push(&mut self, c: u8) {
        if self.length < self.chars.len() {
            self.chars[self.length] = c;
            self.length += 1;
        }
    }

    fn append(&mut self, s: &str) {
        for c in s.bytes() {
            self.push(c);
        }
    }

}

// 字典类型
#[derive(Copy,Clone)]
struct KeyValuePair<'a> {
    key: &'a MyString,
    value: &'a MyString,
}

struct MyStringDictionary<'a> {
    data: [Option<KeyValuePair<'a>>; 128],
    length: usize,
}

impl<'a> MyStringDictionary<'a> {
    fn new() -> MyStringDictionary<'a> {
        MyStringDictionary {
            data: [None; 128],
            length: 0,
        }
    }

    fn insert(&mut self, key: &'a MyString, value: &'a MyString) {
        if self.length < self.data.len() {
            self.data[self.length] = Some(KeyValuePair { key, value });
            self.length += 1;
        }
    }

    fn remove(&mut self, key: &MyString) {
        for i in 0..self.length {
            if let Some(pair) = self.data[i] {
                if pair.key == key {
                    self.data[i] = None;
                    // 后面的元素前移,保持紧凑布局
                    for j in i..self.length - 1 {
                        self.data[j] = self.data[j + 1];
                    }
                    self.length -= 1;
                    break;
                }
            }
        }
    }

    fn get(&self, key: &MyString) -> Option<&MyString> {
        for i in 0..self.length {
            if let Some(pair) = self.data[i] {
                if pair.key == key {
                    return Some(pair.value);
                }
            }
        }
        None
    }

    fn contains_key(&self, key: &MyString) -> bool {
        self.get(key).is_some()
    }
}

// 自定义的标准库
#[derive(PartialEq, Copy,Clone)]
struct MySTD;

impl MySTD {
    // strstr函数的实现
    fn strstr(haystack: &[u8], needle: &[u8]) -> Option<usize> {
        for i in 0..=(haystack.len() - needle.len()) {
            if haystack[i..].starts_with(needle) {
                return Some(i);
            }
        }
        None
    }

    // strchr函数的实现
    fn strchr(haystack: &[u8], needle: u8) -> Option<usize> {
        for (i, &byte) in haystack.iter().enumerate() {
            if byte == needle {
                return Some(i);
            }
        }
        None
    }

    // strlen函数的实现
    fn strlen(s: &[u8]) -> usize {
        let mut len = 0;
        while len < s.len() && s[len] != b'\0' {
            len += 1;
        }
        len
    }

    // strcmp函数的实现
    fn strcmp(s1: &[u8], s2: &[u8]) -> i32 {
        for i in 0..s1.len().min(s2.len()) {
            if s1[i] != s2[i] {
                return (s1[i] as i32) - (s2[i] as i32);
            }
        }
        (s1.len() as i32) - (s2.len() as i32)
    }

    // strcpy函数的实现
    fn strcpy(dest: &mut [u8], src: &[u8]) {
        let mut i = 0;
        while i < src.len() && i < dest.len() {
            dest[i] = src[i];
            i += 1;
        }
        if i < dest.len() {
            dest[i] = b'\0';
        }
    }

    // strncpy函数的实现
    fn strncpy(dest: &mut [u8], src: &[u8], count: usize) {
        let mut i = 0;
        while i < count && i < src.len() && i < dest.len() {
            dest[i] = src[i];
            i += 1;
        }
        if i < dest.len() {
            dest[i] = 0;
        }
    }

    // 复制指定区间的字符到目标字符串
    fn strnncpy(dest: &mut [u8], src: &[u8], _start: usize, _end: usize) {
        let start = _start.min(src.len());
        let end = _end.min(src.len()).min(start + dest.len());
        let mut i = 0;
        while start + i < end {
            dest[i] = src[start + i];
            i += 1;
        }
        if i < dest.len() {
            dest[i] = 0;
        }
    }

    // strtok函数的实现
    fn strtok(s: *mut u8, s_size: usize, delim: u8) -> Option<&'static mut [u8]> {
        return None;
    }

    // strprint函数的实现
    fn strprint(_input: &[u8]) {
        let len = Self::strlen(_input);
        for i in 0..len {
            print!("{}", _input[i] as char);
        }
        print!("\n");
    }

    // 字符数组转int32数字
    fn atoi(s: &[u8]) -> Option<i32> {
        if(s.len() == 0){
            return None;
        }

        let mut value = 0;
        let mut sign = 1;
        let mut i = 0;

        // 处理符号位
        if s[i] == b'-' {
            sign = -1;
            i += 1;
        } else if s[i] == b'+' {
            i += 1;
        }

        // 处理整数部分
        while i < s.len() {
            let digit = s[i] - b'0';
            if digit < 0 || digit > 9 {
                break;
            }
            value = value * 10 + (digit as i32);
            i += 1;
        }

        if i > 0 {
            Some(value * sign)
        } else {
            None
        }
    }

    // 字符数组转f32数字
    fn atof(s: &[u8]) -> Option<f32> {

        if(s.len() == 0){
            return None;
        }

        let mut value = 0.0;
        let mut sign = 1.0;
        let mut i = 0;

        // 处理符号位
        if s[i] == b'-' {
            sign = -1.0;
            i += 1;
        } else if s[i] == b'+' {
            i += 1;
        }

        // 处理整数部分
        while i < s.len() && s[i] >= b'0' && s[i] <= b'9' {
            value = value * 10.0 + ((s[i] - b'0') as f32);
            i += 1;
        }

        // 处理小数部分
        if i < s.len() && s[i] == b'.' {
            let mut power = 1.0;
            i += 1;
            while i < s.len() && s[i] >= b'0' && s[i] <= b'9' {
                value = value + (((s[i] - b'0') as f32) / (10.0 * power));
                power *= 10.0;
                i += 1;
            }
        }

        // 检查是否成功转换了至少一个数字字符
        if i > 0 {
            Some(value * sign)
        } else {
            None
        }
    }

    // strcat函数的实现
    fn strcat(dest: &mut [u8], src: &[u8]) {
        let dest_len = dest.len();
        let src_len = src.len();

        if src_len > dest_len {
            return;
        }

        let mut i = 0;
        while i < dest_len && dest[i] != 0 {
            i += 1;
        }

        let mut j = 0;
        while j < src_len && i < dest_len {
            dest[i] = src[j];
            i += 1;
            j += 1;
        }

        if i < dest_len {
            dest[i] = 0;
        }
    }

    // 转换f32浮点数到{整数.整数}
    fn float_to_uint_point_uint(f: Option<f32>) -> (u16, u16) {
        match(f){
            None=>{
                return (0,0);
            }
            Some(f)=>{
                let integer_part = f as u16;
                let decimal_part = ((f - integer_part as f32) * 10000.0) as u16;
                return (integer_part, decimal_part);
            }
        }//end match
    }

    // 测试:复制内容到字符数组
    fn assign_string(str_value: &[u8]) {
        let len = str_value.len().min(UART0_RX_BUFFER_SIZE);
        unsafe {
            UART0_RX_BUFFER[..len].copy_from_slice(&str_value[..len]);
        }
    }

    // 判断字符数组是否以某个字符开头
    fn starts_with_prefix(s: &[u8], prefix: &[u8]) -> bool {
        if s.len() < prefix.len() {
            return false;
        }

        for i in 0..prefix.len() {
            if s[i] != prefix[i] {
                return false;
            }
        }
        true
    }
}

// 自定义的GCODE处理类
#[derive(PartialEq, Copy,Clone)]
struct MyGCODE {
    main_command: u8,
    sub_command: [u8; 7],
    sub_command_num: Option<f32>,
    command_args: [Option<f32>; 4],
    command_has_args: [bool; 4],
}

impl MyGCODE {
    // 去除gcode的注释
    fn copy_valid_command(source: &[u8], destination: &mut [u8]) {
        // 查找注释字符';'
        match MySTD::strchr(source, b';') {
            Some(index)=>{
                // 复制源字符数组b';'之前的内容到目标字符数组
                MySTD::strnncpy(destination, source, 0, index);
            }
            None => {
                // 没有注释字符';',复制整个源字符数组到目标字符数组
                MySTD::strcpy(destination, source);
            }
        }
    }//end copy_valid_command

    // 解析主命令
    fn parse_main_command(_input: &[u8]) -> Option<MyGCODE> {
        let mut gcode = MyGCODE {
            main_command: 0,
            sub_command: [0; 7],
            sub_command_num: None,
            command_args: [None; 4],
            command_has_args: [false; 4],
        };
        
        match _input.get(0) {
            Some(&b'G') => {
                gcode.main_command = b'G';
        
                if let space_0_pos = MySTD::strchr(&_input[1..], b' ') {
                    match(space_0_pos){
                        None =>{
                            //没有找到空格,命令没有参数
                            let null_pos = MySTD::strlen(&_input) - 1;
                            let sub_command = &_input[1..(null_pos + 1)];
                            gcode.sub_command_num = MySTD::atof(sub_command);
                            gcode.parse_command_args(&_input[1..(null_pos + 1)]);
                            gcode.exe_command();
                        }
                        Some(space_0_pos) =>{
                            let sub_command = &_input[1..(space_0_pos + 1)];
                            gcode.sub_command_num = MySTD::atof(sub_command);
                            gcode.parse_command_args(&_input[1..(space_0_pos + 1)]);
                            gcode.exe_command();
                        }
                    
                    }//end match
                } 
                else if let null_pos = MySTD::strchr(&_input[1..], b'\0') {
                    match(null_pos){
                        None =>{
                            //pass
                        }
                        Some(null_pos)=>{
                            let sub_command = &_input[1..(null_pos + 1)];
                            gcode.sub_command_num = MySTD::atof(sub_command);
                            gcode.parse_command_args(&_input[1..(null_pos + 1)]);
                            gcode.exe_command();
                        }
                    }//end match
                    
                }
            },
            Some(&b'M') => {
                gcode.main_command = b'M';
                if let space_0_pos = MySTD::strchr(&_input[1..], b' ') {
                    match(space_0_pos){
                        None=>{
                            //没有空格,没有参数
                            let null_pos = MySTD::strlen(&_input) - 1;
                            let sub_command = &_input[1..(null_pos + 1)];
                            gcode.sub_command_num = MySTD::atof(sub_command);
                            gcode.parse_command_args(&_input[1..(null_pos + 1)]);
                            gcode.exe_command();
                        }
                        Some(space_0_pos)=>{
                            let sub_command = &_input[1..(space_0_pos + 1)];
                            gcode.sub_command_num = MySTD::atof(sub_command);
                            gcode.parse_command_args(&_input[1..(space_0_pos + 1)]);
                            gcode.exe_command();
                        }
                    }//end match 
                    
                } else if let null_pos = MySTD::strchr(&_input[1..], b'\0') {
                    match(null_pos){
                        None=>{
                            //pass
                        }
                        Some(null_pos)=>{
                            let sub_command = &_input[1..(null_pos + 1)];
                            gcode.sub_command_num = MySTD::atof(sub_command);
                            gcode.parse_command_args(&_input[1..(null_pos + 1)]);
                            gcode.exe_command();
                        }
                    }//end match
                
                }//end null_pos
            },
            _ => {
                return None;
            }
        }//end match
        return Some(gcode);
    }//end parse_main_command
    
    // 解析命令参数
    fn parse_command_args(&mut self, _input: &[u8]) {
        for (index, &c) in _input.iter().enumerate() {
            match c {
                b'X' => {
                    //println!("找到X");
                    // 判断数组索引是否越界
                    if(index == (MySTD::strlen(&_input) - 1)){
                        return;
                    }

                    if let x_end = MySTD::strchr(&_input[(index + 1)..], b' ') {
                        match(x_end){
                            None=>{
                                let null_pos = MySTD::strlen(&_input) - 1;
                                let x_value = &_input[(index + 1)..(null_pos+1)];
                                self.command_args[0] = MySTD::atof(x_value);
                                //self.command_has_args[0] = true;
                            }
                            Some(x_end)=>{
                                let x_value = &_input[(index + 1)..(index + 1 + x_end)];
                                self.command_args[0] = MySTD::atof(x_value);
                                //self.command_has_args[0] = true;
                            }
                        }//end match
                     
                    }
                },
                b'Y' => {
                    // 判断数组索引是否越界
                    if(index == (MySTD::strlen(&_input) - 1)){
                        return;
                    }

                    if let y_end = MySTD::strchr(&_input[(index + 1)..], b' ') {
                        match(y_end){
                            None=>{
                                let null_pos = MySTD::strlen(&_input) - 1;
                                let y_value = &_input[(index + 1)..(null_pos+1)];
                                self.command_args[1] = MySTD::atof(y_value);
                                //self.command_has_args[1] = true;
                            }
                            Some(y_end)=>{
                                let y_value = &_input[(index + 1)..(index + 1 + y_end)];
                                self.command_args[1] = MySTD::atof(y_value);
                                //self.command_has_args[1] = true;
                            }
                        }//end match
                    } 
                },
                b'Z' => {
                    //println!("找到Z");
                    // 判断数组索引是否越界
                    if(index == (MySTD::strlen(&_input) - 1)){
                        return;
                    }

                    if let z_end = MySTD::strchr(&_input[(index + 1)..], b' ') {
                        match(z_end){
                            None=>{
                                let null_pos = MySTD::strlen(&_input) - 1;
                                let z_value = &_input[(index + 1)..(null_pos+1)];
                                self.command_args[2] = MySTD::atof(z_value);
                                //self.command_has_args[2] = true;
                            }
                            Some(z_end)=>{
                                let z_value = &_input[(index + 1)..(index + 1 + z_end)];
                                self.command_args[2] = MySTD::atof(z_value);
                                //self.command_has_args[2] = true;
                            }
                        
                        }//end match
                       
                    } //end if
                },
                b'F' => {
                    //println!("找到F");

                    // 判断数组索引是否越界
                    if(index == (MySTD::strlen(&_input) - 1)){
                        return;
                    }

                    if let f_end = MySTD::strchr(&_input[(index + 1)..], b' ') {
                        match(f_end){
                            None=>{
                                let null_pos = MySTD::strlen(&_input) - 1;
                                let f_value = &_input[(index + 1)..(null_pos+1)];
                                self.command_args[3] = MySTD::atof(f_value);
                                //self.command_has_args[3] = true;
                            }
                            Some(f_end)=>{
                                let f_value = &_input[(index + 1)..(index + 1 + f_end)];
                                self.command_args[3] = MySTD::atof(f_value);
                                //self.command_has_args[3] = true;
                            }
                        }//end match
                       
                    }//end if
                },
                _ => {
                    //println!("无效参数类型");
                }
            }//end match
        }//end for
    }//end parse_command_args
    
    // 根据子命令判断参数并调用对应的执行函数
    fn exe_command(&self) {
        match self.main_command {
            b'M' => {
                match(self.sub_command_num){
                    None=>{
                        //pass
                    }

                    Some(sub_command_num)=>{
                        // 分割整数和小数
                        let (_subcommand_integer_part,_subcommand_decimal_part) = MySTD::float_to_uint_point_uint(Some(sub_command_num));

                        if(DEBUG_LEVEL_0 == true){
                            println!("->M:{}.{}", _subcommand_integer_part,_subcommand_decimal_part);
                        }

                // 根据子命令判断
                match(_subcommand_decimal_part){
                    /*
                    * M0:强制停止程序,Mandatory Program Stop:
                    */
                    0=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M0

                    /*
                    * M1:可选停止程序,Optional Program Stop
                    */
                    1=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M1

                    /*
                    * M2:程序结束,Program End
                    */
                    2=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M2

                    /*
                    * M3:主轴向前/顺时针,Spindle Forward/Clockwise
                    */
                    3=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M3

                    /*
                    * M4:主轴反向/逆时针,Spindle Reverse/Counterclockwise
                    */
                    4=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M4

                    /*
                    * M5:主轴停止,Spindle Stop
                    */
                    5=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M5

                    /*
                    * M6:切换工具,Tool Change
                    */
                    6=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M6

                    /*
                    * M7:喷雾冷却剂开启,Mist Coolant On
                    */
                    7=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M7

                    /*
                    * M8:打开冷却液,Flood Coolant On
                    */
                    8=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M8

                    /*
                    * M9:喷雾冷却剂关闭,All Coolant Off
                    */
                    9=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M9

                    /*
                    * M19:主轴定向,Spindle Orient
                    */
                    19=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M19

                    /*
                    * M30:结束程序重头开始,Program End and Rewind
                    */
                    30=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M30

                    /*
                    * M40:变速到0,Gear Change to 0
                    */
                    40=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M40

                    /*
                    * M41:变速到1,Gear Change to 1
                    */
                    41=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M41

                    /*
                    * M42:变速到2,Gear Change to 2
                    */
                    42=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M42

                    /*
                    * M43:变速到3,Gear Change to 3
                    */
                    43=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M43

                    /*
                    * M44:变速到4,Gear Change to 4
                    */
                    44=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M44

                    /*
                    * M45:变速到5,Gear Change to 5
                    */
                    45=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M45

                    /*
                    * M47:从第一行开始重复程序,Repeat Program from First Line
                    */
                    47=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M47

                    /*
                    * M48:启用进给速度/主轴速度覆盖,Enable Feed rate/Spindle Speed Overrides
                    */
                    48=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M48

                    /*
                    * M49:禁用进给速度/主轴速度覆盖,Disable Feed rate/Spindle Speed Overrides
                    */
                    49=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M49

                    /*
                    * M98:调用子程序,Subprogram Call
                    */
                    98=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M98

                    /*
                    * M99:回到主程序,Return to main program
                    */
                    99=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M99

                    /*
                    * M228:Macro for Go To Positions
                    * It takes a P(1-14) parameter for which position it goes to,
                    * follow in the order that the positions are listed in the screen configuration dialog.
                    */
                    228=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("M:{}子命令",_subcommand_integer_part);
                        }
                    }// end M228

                    /*
                    * 其他情况
                    * M200 – M221: Macros to turn outputs on/off
                    */
                    _=>{
                        println!("M:undefine:{}子命令",_subcommand_integer_part); 
                    }
                }//end match

            }//end Some
        }//end match
            },
            b'G' => {
                match(self.sub_command_num){
                    None=>{
                        //pass
                    }
                    Some(sub_command_num)=>{

                
                // 分割整数和小数
                let (_subcommand_integer_part,_subcommand_decimal_part) = MySTD::float_to_uint_point_uint(Some(sub_command_num));

                if(DEBUG_LEVEL_0 == true){
                    println!("->G:{}.{}", _subcommand_integer_part,_subcommand_decimal_part);
                }

                // 根据子命令判断参数并调用对应的执行函数
                match(_subcommand_decimal_part){
                    /*
                    * G0:快速移动,Rapid Move
                    * 参数:X,Y,Z,F
                    * 备注:G90绝对坐标,G91相对坐标
                    */
                    0=>{
                        println!("G:{}子命令",_subcommand_integer_part);

                        match(self.command_args[0]){
                            None=>{
                                //没有X参数
                            }
                            Some(_x)=>{
                                let (_x_integer_part,_x_decimal_part) = MySTD::float_to_uint_point_uint(Some(_x));
                                println!("X:{}.{}",_x_integer_part,_x_decimal_part);
                            }
                        }//end match X

                        match(self.command_args[1]){
                            None=>{
                                //没有Y参数
                            }
                            Some(_y)=>{
                                let (_y_integer_part,_y_decimal_part) = MySTD::float_to_uint_point_uint(Some(_y));
                                println!("Y:{}.{}",_y_integer_part,_y_decimal_part);
                            }
                        }//end match Y

                        match(self.command_args[2]){
                            None=>{
                                //没有Z参数
                            }
                            Some(_z)=>{
                                let (_z_integer_part,_z_decimal_part) = MySTD::float_to_uint_point_uint(Some(_z));
                                println!("Z:{}.{}",_z_integer_part,_z_decimal_part);
                            }
                        }//end match Z

                        match(self.command_args[3]){
                            None=>{
                                //没有F参数
                            }
                            Some(_f)=>{
                                let (_f_integer_part,_f_decimal_part) = MySTD::float_to_uint_point_uint(Some(_f));
                                println!("F:{}.{}",_f_integer_part,_f_decimal_part);
                            }
                        }//end match F
                    }//end G0

                    /*
                    * G1:线性进给移动,Linear Feed Move
                    * 参数:X,Y,Z,F
                    * 备注:G90绝对坐标,G91相对坐标
                    */
                    1=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }

                        match(self.command_args[0]){
                            None=>{
                                //没有X参数
                            }
                            Some(_x)=>{
                                let (_x_integer_part,_x_decimal_part) = MySTD::float_to_uint_point_uint(Some(_x));
                                println!("X:{}.{}",_x_integer_part,_x_decimal_part);
                            }
                        }//end match X

                        match(self.command_args[1]){
                            None=>{
                                //没有Y参数
                            }
                            Some(_y)=>{
                                let (_y_integer_part,_y_decimal_part) = MySTD::float_to_uint_point_uint(Some(_y));
                                println!("Y:{}.{}",_y_integer_part,_y_decimal_part);
                            }
                        }//end match Y

                        match(self.command_args[2]){
                            None=>{
                                //没有Z参数
                            }
                            Some(_z)=>{
                                let (_z_integer_part,_z_decimal_part) = MySTD::float_to_uint_point_uint(Some(_z));
                                println!("Z:{}.{}",_z_integer_part,_z_decimal_part);
                            }
                        }//end match Z

                        match(self.command_args[3]){
                            None=>{
                                //没有F参数
                            }
                            Some(_f)=>{
                                let (_f_integer_part,_f_decimal_part) = MySTD::float_to_uint_point_uint(Some(_f));
                                println!("F:{}.{}",_f_integer_part,_f_decimal_part);
                            }
                        }//end match F
                       
                    }//end G1

                    /*
                    * G02:顺时针圆弧进给移动,Clockwise Arc Feed Move
                    * 参数:X,Y,Z,F
                    * 备注:G90绝对坐标,G91相对坐标
                    */
                    2=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G2

                    3=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G3

                    4=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G4

                    5=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G5

                    6=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G6

                    7=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G7

                    8=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G8

                    9=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G9

                    10=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G10

                    11=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G11

                    12=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G12

                    13=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G13

                    14=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G14

                    15=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G15

                    16=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G16

                    17=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G17

                    18=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G18

                    19=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G19

                    20=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G20

                    21=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:{}子命令",_subcommand_integer_part);
                        }
                    }//end G21

                    22 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G22
                    23 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G23
                    24 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G24
                    25 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G25
                    26 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G26
                    27 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G27
                    28 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G28
                    29 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G29
                    30 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G30

                    31 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G31

                    32 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G32

                    33 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G33

                    34 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G34

                    35 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G35

                    36 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G36

                    37 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G37

                    38 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G38

                    39 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G39

                    40 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G40

                    41 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G41

                    42 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G42

                    43 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G43

                    44 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G44

                    45 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G45

                    46 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G46

                    47 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G47

                    48 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G48

                    49 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G49

                    50 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G50
                    
                    51 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G51

                    52 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G52

                    53 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G53

                    54 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G54

                    55 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G55

                    56 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G56

                    57 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G57

                    58 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G58

                    59 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G59

                    60 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G60

                    61 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G61

                    62 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G62

                    63 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G63

                    64 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G64

                    65 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G65

                    66 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G66

                    67 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G67

                    68 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G68

                    69 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G69

                    70 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G70

                    71 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G71

                    72 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G72

                    73 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G73

                    74 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G74

                    75 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G75

                    76 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G76

                    77 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G77

                    78 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G78

                    79 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G79

                    80 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G80

                    81 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G81

                    82 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G82

                    83 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G83

                    84 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G84

                    85 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G85

                    86 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G86

                    87 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G87

                    88 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G88

                    89 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G89

                    90 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G90

                    91 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G91

                    92 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G92

                    93 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G93

                    94 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G94

                    95 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G95

                    96 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G96

                    97 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G97

                    98 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G98

                    99 => {
                        if DEBUG_LEVEL_0 {
                            println!("G:{}子命令", _subcommand_integer_part);
                        }
                    } // end G99

                    /*
                    * 其他子命令
                    */
                    _=>{
                        if(DEBUG_LEVEL_0==true){
                            println!("G:undefined:{}子命令",_subcommand_integer_part);
                        }
                    }
                }//end match

            }//end Some
        }//end match
        
            }//end 'G'
            
            _ => {
                println!("无效的GCODE命令")
            }
        }//end match
    }//end exe_command
}//end MyGCODE

/* end 自定义类型 */

/* start 全局变量 */
static TIMER0: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
static TIMER1: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
static mut LED_D4: Option<esp32c3_hal::gpio::Gpio12<Output<PushPull>>> = None;
static mut LED_D5: Option<esp32c3_hal::gpio::Gpio13<Output<PushPull>>> = None;
static SERIAL0: Mutex<RefCell<Option<Uart<UART0>>>> = Mutex::new(RefCell::new(None));
// 创建一个静态数组作为字符缓冲区
const UART0_RX_BUFFER_SIZE: usize = 32;
static mut UART0_RX_BUFFER: [u8; UART0_RX_BUFFER_SIZE] = [0; UART0_RX_BUFFER_SIZE];
static mut UART0_RX_BUF_INDEX: usize = 0; // 缓冲区当前索引
//调试参数
const DEBUG_LEVEL_0:bool = true;
const DEBUG_LEVEL_1:bool = true;
/* end 全局变量 */

/* start 程序入口点 */
#[entry]
fn main() -> ! {
    // 实例化对象和定义变量
    let peripherals = Peripherals::take();
    let mut system = peripherals.SYSTEM.split();
    let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
    let mut uart0 = Uart::new(peripherals.UART0, &mut system.peripheral_clock_control);

    // TIMG0和TIMG1各自包含一个通用定时器和一个看门狗定时器
    let mut rtc = Rtc::new(peripherals.RTC_CNTL);
    let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks,&mut system.peripheral_clock_control);
    let mut wdt0 = timer_group0.wdt;
    let mut timer0 = timer_group0.timer0;
    let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks,&mut system.peripheral_clock_control);
    let mut wdt1 = timer_group1.wdt;
    let mut timer1 = timer_group1.timer0;

    // 延时函数初始化
    let mut delay = Delay::new(&clocks);

    // 配置gpio口
    let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);

    // 配置uart0串口
    uart0.set_rx_fifo_full_threshold(1).unwrap();
    uart0.listen_rx_fifo_full();

    // 初始化串口中断
    critical_section::with(|cs| SERIAL0.borrow_ref_mut(cs).replace(uart0));
    interrupt::enable(
        peripherals::Interrupt::UART0,
        interrupt::Priority::Priority1,//1级中断优先级
    )
    .unwrap();
    interrupt::set_kind(
        Cpu::ProCpu,
        interrupt::CpuInterrupt::Interrupt1, 
        interrupt::InterruptKind::Edge,
    );

    // 配置引脚功能
    unsafe {
        LED_D4.replace(io.pins.gpio12.into_push_pull_output());
        LED_D5.replace(io.pins.gpio13.into_push_pull_output());
    }

    // 初始化定时器0中断
    interrupt::enable(
        peripherals::Interrupt::TG0_T0_LEVEL,
        interrupt::Priority::Priority2,
    )
    .unwrap();
    timer0.start(500u64.millis());
    timer0.listen();

    // 初始化定时器1中断
    interrupt::enable(
        peripherals::Interrupt::TG1_T0_LEVEL,
        interrupt::Priority::Priority2,
    )
    .unwrap();
    timer1.start(1u64.secs());
    timer1.listen();

    // 打开定时器引用锁Mutex,使得定时器中断handler安全跳转
    critical_section::with(|cs| {
        TIMER0.borrow_ref_mut(cs).replace(timer0);
        TIMER1.borrow_ref_mut(cs).replace(timer1);
    });//end critical_section

    // 允许中断
    unsafe {
        riscv::interrupt::enable();
    }

    unsafe{
        //测试
        if(DEBUG_LEVEL_1 == true){
            let mut mystr = MyString::new();
            mystr.append("G00");
            let mut mydict = MyStringDictionary::new();
            let mut key1 = MyString::new();
            key1.append("G00");
            let mut value1 = MyString::new();
            value1.append("Rapid Move");
            mydict.insert(&key1, &value1);

            match mydict.get(&mystr) {
                Some(val) => {
                    let mut result = MyString::new();
                    for i in 0..val.length {
                        result.push(val.chars[i]);
                    }
                    print_my_string(&result);
                },
                None => println!("Not found!"),
            }

            fn print_my_string(s: &MyString) {
                for i in 0..s.length {
                    print!("{}", s.chars[i] as char);
                }
                println!();
            }
        }
    }//end unsafe

    unsafe{
        print!("Compute(ziglang):");
        unsafe {
            println!("{}", add(4,5));
        }
    }

    // 开始循环
    loop {
        //println!("Compute(ziglang):");
        test_uart();// 分析串口命令
        //delay.delay_ms(2000u32);//延时2000ms
    }

}
/* end 程序入口点 */

/* start 中断处理函数 */
// 定时器0中断处理函数
#[interrupt]
fn TG0_T0_LEVEL() {
    critical_section::with(|cs| {
        //esp_println::println!("Interrupt 1");

        //翻转led_d5电平
        unsafe {
            if let Some(led) = &mut LED_D5 {
                led.toggle();
            } else {
                esp_println::println!("Toggle LED_D5 failed!");
            }
        }

        let mut timer0 = TIMER0.borrow_ref_mut(cs);
        let timer0 = timer0.as_mut().unwrap();

        timer0.clear_interrupt();
        timer0.start(500u64.millis());
    });//end critical_section
}

// 定时器1中断处理函数
#[interrupt]
fn TG1_T0_LEVEL() {
    critical_section::with(|cs| {
        //esp_println::println!("Interrupt 11");

        //翻转led_d4电平
        unsafe {
            if let Some(led) = &mut LED_D4 {
                led.toggle();
            } else {
                esp_println::println!("Toggle LED_D4 failed!");
            }
        }

        let mut timer1 = TIMER1.borrow_ref_mut(cs);
        let timer1 = timer1.as_mut().unwrap();

        timer1.clear_interrupt();
        timer1.start(1u64.secs());
    });//end critical_section
}

// 串口0中断处理函数
#[interrupt]
fn UART0() {
    critical_section::with(|cs| {
        let mut serial = SERIAL0.borrow_ref_mut(cs);
        let serial = serial.as_mut().unwrap();

        let mut cnt = 0; //串口接收计数
        while let nb::Result::Ok(_c) = serial.read() {
            cnt += 1;//计数自增

            // 将接收到的字符加入到字符缓冲区
            unsafe {
                if UART0_RX_BUF_INDEX < UART0_RX_BUFFER_SIZE {
                    UART0_RX_BUFFER[UART0_RX_BUF_INDEX] = _c;
                    UART0_RX_BUF_INDEX += 1;
                }
            }
        }//end while

        if(DEBUG_LEVEL_0 == true){
            writeln!(serial, "Read {} bytes", cnt,).ok();
        }
        
        // 重置串口中断标志
        serial.reset_rx_fifo_full_interrupt();

    });//end critical_section
}
/* end 中断处理函数 */

/* start 自定义函数 */
// 测试专用:按位赋值数组
fn assign_string(str_value: &[u8]) {
    unsafe {
        UART0_RX_BUFFER.copy_from_slice(&str_value[..UART0_RX_BUFFER_SIZE]);
    }
}

// 测试串口
fn test_uart(){
    // 判断串口缓冲区中是否有字符
    unsafe{
        if(UART0_RX_BUFFER[0] == 0){
            return;
        }
    }

    // 复制字符串
    let mut uart0_char_buf:[u8;48]=[0;48];
    unsafe{
        let len = MySTD::strlen(&UART0_RX_BUFFER);
        MySTD::strnncpy(&mut uart0_char_buf,&UART0_RX_BUFFER,0,len);
    }

    // 打印字符缓冲区中的字符
    unsafe {
        // 复制字符串
        if(DEBUG_LEVEL_0 == true){
            print!("Rec:");
            MySTD::strprint(&uart0_char_buf);
        }
    }// end unsafe

     // 清空缓存区
     unsafe{
        UART0_RX_BUF_INDEX = 0; // 清空缓冲区索引
        UART0_RX_BUFFER[0]=0;
    }
   
    // 分析字符串
    unsafe{
        let my_gcode_command = MyGCODE::parse_main_command(&uart0_char_buf);
        match(my_gcode_command){
            None=>{
                if(DEBUG_LEVEL_0 == true){
                    println!("no valid GCODE");
                }
            }
            Some(mut _gcode_command)=>{
                //解析命令参数
                _gcode_command.parse_command_args(&uart0_char_buf);
                if(DEBUG_LEVEL_0 == true){
                    println!("/* start GCODE */");
                    print!("main_command:{}\n",_gcode_command.main_command as char);
                    //print!("子命令:{}\n",_gcode_command.sub_command_num as f32);
                    // 分割整数和小数
                    let (_subcommand_integer_part,_subcommand_decimal_part) = MySTD::float_to_uint_point_uint(_gcode_command.sub_command_num);
                    println!("->sub_command:{}.{}", _subcommand_integer_part,_subcommand_decimal_part);
                    match(_gcode_command.command_args[0]){
                        None=>{
                            //没有X参数
                        }
                        Some(_x)=>{
                            let (_x_integer_part,_x_decimal_part) = MySTD::float_to_uint_point_uint(Some(_x));
                            println!("X:{}.{}",_x_integer_part,_x_decimal_part);
                        }
                    }//end match X

                    match(_gcode_command.command_args[1]){
                        None=>{
                            //没有Y参数
                        }
                        Some(_y)=>{
                            let (_y_integer_part,_y_decimal_part) = MySTD::float_to_uint_point_uint(Some(_y));
                            println!("Y:{}.{}",_y_integer_part,_y_decimal_part);
                        }
                    }//end match Y

                    match(_gcode_command.command_args[2]){
                        None=>{
                            //没有Z参数
                        }
                        Some(_z)=>{
                            let (_z_integer_part,_z_decimal_part) = MySTD::float_to_uint_point_uint(Some(_z));
                            println!("Z:{}.{}",_z_integer_part,_z_decimal_part);
                        }
                    }//end match Z

                    match(_gcode_command.command_args[3]){
                        None=>{
                            //没有F参数
                        }
                        Some(_f)=>{
                            let (_f_integer_part,_f_decimal_part) = MySTD::float_to_uint_point_uint(Some(_f));
                            println!("F:{}.{}",_f_integer_part,_f_decimal_part);
                        }
                    }//end match F
                    
                    println!("/* end GCODE */")
                }//end DEBUG_LEVEL_0

            }//end Some
        }//end match

    }//end unsafe

}
/* end 自定义函数 */

效果

标签:end,LEVEL,GCODE,esp32,subcommand,part,串口,println,integer
From: https://www.cnblogs.com/qsbye/p/17789175.html

相关文章

  • 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能
    开发板:STM32F407ZGT6;目标:想使用软件“串口调试助手”情况:开发板上的USB_UART口所在器件损坏或者直接没有;解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作:1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,将串口1的TX接USB转TTL模块的R......
  • Zephyr重定向日志打印到USB串口
    nRF52840DK开发板的例程大多数是从硬件串口打印日志,然后硬件串口在开发板上通过Jlink转换为USB串口,最后打印到电脑上。这里给出通过52840自己的USB串口打印日志的方法。以zephyr/samples/hello_world例程为例:修改config#使能串口驱动CONFIG_SERIAL=y#使能串口的中断模式(......
  • 解决Linux非root用户读写串口权限问题
    查看串口和基本设置查看串口:ls/dev/ttyUSB*查看参数:stty-F/dev/ttyUSB0设置波特率:stty-F/dev/ttyUSB0speed9600收发数据先打开后台接收:cat/dev/ttyUSB0&发送:echohello>/dev/ttyUSB0可以使用printf做更精确的控制:printf'hello\r'>/dev/ttyUSB0解决"P......
  • esp32笔记[8]-rust的定时器中断点灯
    摘要使用rust开发esp32c3实现定时器中断点亮led灯.超链接esp32笔记[7]-使用rust+zig开发入门平台信息esp32c3rustMutex锁usecore::cell::RefCell;usecritical_section::Mutex;//no-std库专用的Mutex我们首先注意到的是静态变量BUTTON。我们需要它,因为在中断处理程......
  • esp32 factory+双OTA分区
    #Name,Type,SubType,Offset,Size,Flags#Note:ifyouhaveincreasedthebootloadersize,makesuretoupdatetheoffsetstoavoidoverlap,,,,nvs,data,nvs,0x4000,otadata,data,ota,0x4000,phy_init,data,phy,0x1000,factory,......
  • 无涯教程-Arduino - 外围串口
    串行外围设备接口(SPI)总线是用于串行通信的系统,它最多使用四根导线,通常为三根,一根导线用于数据接收,一根导线用于数据发送,一根导线用于同步,另一根导线用于选择要与之通信的设备,这是全双工连接,这意味着将同时发送和接收数据,最大波特率高于I2C通信系统中的波特率。BoardSPIPins......
  • 修改串口节点名称
    需求:3368的老主板更换为3568的新主板,为了app兼容两款主板,要求串口号一致。有个ttyS0的口,需要对应改为ttySWK0跟踪驱动代码:dw8250_probe(drivers\tty\serial\8250\8250_dw.c)-->serial8250_register_8250_port(drivers\tty\serial\8250\8250_core.c)-......
  • FreeRTOS qemu mps2-an385 bsp 移植制作 :串口打印篇
    开发环境Win1064位+VSCode,ssh远程连接ubuntuVMwareWorkstationPro16+Ubuntu20.04FreeRTOSv202212.01(备注:可以在github获取最新版本)qemuqemu-system-armmps2-an385开发板,qemu版本QEMUemulatorversion4.2.1或更高armgcc交叉编译工具链:当前使用gcc编译环境......
  • ESP32-MicroPython without Thonny
    whywitoutThonny?最近闲来在ESP32上用MicroPython捣鼓些小玩具,见很多教程推荐使用Thonny。欣然往之,竟是个这,实在不能认同。Thonnyesp32-MicroPython开发的入门最佳实践?no!刷入固件使用esptool.py将MicroPython刷入ESP32开发板涉及几个步骤。1.安装esptool如果你还......
  • ESP32-MicroPython 开发环境
    Linux/Mac下使用MicroPython开发ESP32刷入固件使用esptool.py将MicroPython刷入ESP32开发板涉及几个步骤。1.安装esptool如果你还没有安装esptool.py,你可以使用pip来安装它:pipinstallesptool2.下载MicroPython固件MicroPython-Pythonformicrocontrol......