esp32笔记[9]-rust的串口收发及GCODE解析
摘要
使用rust在no-std环境下实现esp32-c3串口收发及gcode解析.
平台信息
- esp32c3
- rust
超链接
使用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 自定义函数 */