stm32开发3D打印机(六)——使用FATFS文件系统读取打印文件 获取信息 执行转换 转换坐标(下)

在上一篇文章我们完成了一次只读取一个字节的函数zf_read

那现在需要了解打印文件(后缀为gcode的文件)的指令。
不做详细的介绍,建议百度G代码或者gcode

粗略的介绍一下,现在只识别这两个指令

指令 功能
G0 快速定位
G1 直线插补

打印文件截图,如下所示
在这里插入图片描述
其实G0与G1可以当成一样的
X、Y、Z后为对应的坐标,E为挤出头运行距离
F为速度(还未能实现)

注意现在设定只识别这两个指令

那现在我们需要了解一下,c++的一些函数
在string.h库中,我们在解析指令需要以下函数
函数的功能就不详细说了,在这个网站有详细的介绍
链接为:https://www.runoob.com/cprogramming/c-function-strchr.html

函数 功能
strchr 查找
strcpy 复制
strtod 转换识别字符后的字节

第一个函数为识别该文件是否打印完,即打印文件是否读取完毕

u8 card_eof(void)
{
    
     
	if((file)->fptr == (file)->fsize) 
		return 1;
	else return 0;
}

第二个函数为解析指令,是否存在指令

u8 code_cmdseen(char code)	///解析指令,检测是否有该指令、code为搜索的指令(G、X、Y、Z、E、F),检测出存在指令则返回1
{
    
    
	if(code=='F')			///如果检测F指令
	{
    
    
		Fbuf=strchr(cmdbuffer[readindex],code);//扫描cmdbuffer是否有F
		if(Fbuf==NULL)	return 0;	
		if(*(Fbuf+1)>'9'||*(Fbuf+1)<'0')	return 0;	//若检测到F后为非数字,则返回为未检测出指令
		return 1;
	}
	
	strchr_pointer = strchr(cmdbuffer[readindex],code);
	if(strchr_pointer==NULL) return 0;
	else 
	{
    
    
		strcpy(cmdbuffer[readindex],strchr(cmdbuffer[readindex],code));
		printf("解析指令",cmdbuffer[readindex]);//此行可省略
		if (*(cmdbuffer[readindex] + 1) > '9' || *(cmdbuffer[readindex] + 1) < '0')
			return 0;
		return 1;							
	}
}

第三个函数为解析指令后的数值(前提识别出有指令)

float code_numseen(void)		///½âÎö»ñµÃÖ¸ÁîºóµÄÊýÖµ
{
    
    
	cmdswitchbuf_num=(strtod(cmdbuffer[readindex]+1,&cmdswitchbuf));//获取指令后的数据,之所以加1,是因为跳过自身指令(G、X、Y、Z、E、F)后读取数值。
	strcpy(cmdbuffer[readindex],cmdswitchbuf);//获取指令后的数值,那么把刚才识别的指令及数值跳过,及重新给cmdbuffer赋值
	printf("获取解析指令后的数值",cmdswitchbuf_num);//可省略
	return cmdswitchbuf_num;
}	

第四个函数为解析指令F后的数值(前提识别出有指令)
之所以要写多一个,是因为在打印文件中,XYZ是固定的位置,而F不是

int code_numseen_feed(void)		
{
    
    
	cmdswitchbuf_num=(strtod(Fbuf+1,NULL));
//	strcpy(cmdbuffer[readindex],cmdswitchbuf);//F不需要,位置不为固定的
//	printf("获取解析指令后的数值f",cmdswitchbuf_num);

	return cmdswitchbuf_num;
}	

第五个函数为解析函数,整合上述函数

u8 get_command(void)
{
    
    
	u8 res=0;
	u16 t;
	if(block_num<BLOCK_BUFFER_SIZE-1)
	{
    
    
		if(!SDPRINT||serial_count!=0)
			return error;
		while(1)
		{
    
    
			serial_char=zf_read();	
			cmdbuffer[zindew1][zindew2]=serial_char;
			zindew2++;
			if(serial_char==0x0a)
			{
    
    
				printf("获得数据为ª:%s,cmdbuffer[%d]=%s\n\r\n\r",cmdbuffer[zindew1],zindew1,cmdbuffer[zindew1]);
				zindew1=((zindew1+1)%BUFSIZE);
				zindew2=0;
				buflen++;
				break;
			}
		}
		process_commands();
		if(card_eof())
		{
    
    
			printf("finsh print\n\r\n\r");
			serial_count=1;
			return ok;
		}
	}
	return ok;
}

void process_commands(void)
{
    
    
	u8 i,q;
	buflen = (buflen-1);
	if(zindew1==0)
		readindex=7;
	else
		readindex=(zindew1-1);
	
		if((code_cmdseen('G')))//&&(strstr(cmdbuffer[bufindr], "M701") == NULL)&&(strstr(cmdbuffer[bufindw], "M702") == NULL))
		{
    
    
			 switch(i=(int)code_numseen())
			 {
    
    
				 case 0:////只添加了0与1,所以这里只识别G0与G1
				 {
    
    	 
				 }			 
				 case 1:
				 {
    
    
						printf("执行转换\n\r\n\r");
						get_coordinates(); 
						return;
				 }		 
			}	
		}
		else
		{
    
    
			printf("解析失败,读取的数据为%sreadindex=%d\n\r\n\r",cmdbuffer[readindex],readindex);	
		}
}
void get_coordinates(void)
{
    
    
	u8 i=0;
	if(block_num<BLOCK_BUFFER_SIZE-1)
	{
    
    
		if(code_cmdseen('F'))
		{
    
    
			feedrate=(int)code_numseen_feed();
			printf("feedrate = %f\r\n",feedrate);
		}
		for(i=0;i<=(NUM_AXIS-1);i++)
		{
    
    
			if(code_cmdseen(axis_codes[i]))
			{
    
    
				destination[i] = (float)code_numseen();
				printf("destination[%d] = %f\r\n",i,destination[i]);
			}
			else 
			{
    
    
				destination[i]=current_position[i];
			}
		}
		prepare_move();
	}
}
void prepare_move(void)
{
    
    
	u8 i;

	plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
	for(i=0; i < NUM_AXIS; i++) 
	{
    
    
		current_position[i] = destination[i];
	}
}

plan_buffer_line(const float x, const float y, const float z, const float e, float feed_rate, const uint8_t extruder)
这个函数很复杂,比上面的还要长,下次再更新了
这个函数在下一篇文章更新

我们创建了两个文件,名为:command.c与command.h
command.c文件如下所示

在这里插入代码片

猜你喜欢

转载自blog.csdn.net/Nico_jion/article/details/108673011