工序解释执行程序--工程师的成长

多年前一个项目主要做一台机器,读取文件数据并解释执行,吸合电磁阀或点亮相应的LED,提示工人操作

文件格式

A	
1	1      1
2	2      2
3	3      3
4	4      4
5	5      5
6	6      6
7	7      7
8	8      8
9	9      9
10	10     10
11	11     11
12	12     12
13	13     13
14	14     14
15	15     15
16	16     16
17	17     17
18	18     18
19	19     19
20	20     20
23	23     23
63	23     23
62	22     22
60	20     20
58	18     18
57	17     17
56	16     16
55	15     15
54	14     14
53	13     13
52	12     12
51	11     11
50	10     10
49	9      9
47	7      7

第一列表示按键序号,第二列表示LED序号,第三列表示电磁阀序号
读取第一行,点亮相应的LED,吸合电磁,等待相应的按键按下,接着执行第二行,以此类推

解释字符串并转换成相应的工序数据

#include "file.h"
#include "znFAT.h"
#include "io.h"
#include "LCD1602.h"

#include <string.h>
#include <stdlib.h>

struct FileInfo FileInfo;        //文件信息结构体实体

FILE_T File;
STRING_T String;

void FileInit( void )
{
	memset(&File,0,sizeof(FILE_T));
	File.Name[0] = '\\';
}

u8 ValidChar( u8 chr )
{
	if( (chr>='0'&&chr<='9') || (chr>='A'&&chr<='E')
	|| chr=='X' || chr==' ' || chr==','
	|| chr==0x09 || chr==0x0a || chr==0x0d )
		return 1;
	else
		return 0;
}

//获取文件中各个工人的起始,结束地址
void InitFileInfo( void )
{
	UINT8 step=0,wks=0;
	UINT16 i=0;	
	memset( &File.ReadPtr,0,MAX_WORKERS );
	memset( &File.End,0,MAX_WORKERS );
	while( i<File.Len )
	{
		switch( step )
		{
			case 0:
				switch( File.Buf[i] )
				{
					case 'A':
						WorkerFlow.Flow[A].Beep = 0;
						while( File.Buf[i]!='\n' )
						{
							if( File.Buf[i]=='X' )
								WorkerFlow.Flow[A].Beep = 'X';
							i++;
						}
						File.ReadPtr[A] = i+1;
						step = 1;
						wks++;
						break;
					case 'B':
						WorkerFlow.Flow[B].Beep = 0;
						while( File.Buf[i]!='\n' )
						{
							if( File.Buf[i]=='X' )
								WorkerFlow.Flow[B].Beep = 'X';
							i++;
						}
						File.ReadPtr[B] = i+1;
						step = 2;
						wks++;
						break;
					case 'C':
						WorkerFlow.Flow[C].Beep = 0;
						while( File.Buf[i]!='\n' )
						{
							if( File.Buf[i]=='X' )
								WorkerFlow.Flow[C].Beep = 'X';
							i++;
						}
						File.ReadPtr[C] = i+1;
						step = 3;
						wks++;
						break;
					case 'D':
						WorkerFlow.Flow[D].Beep = 0;
						while( File.Buf[i]!='\n' )
						{
							if( File.Buf[i]=='X' )
								WorkerFlow.Flow[D].Beep = 'X';
							i++;
						}
						File.ReadPtr[D] = i+1;
						step = 4;
						wks++;
						break;
					case 'E':
						WorkerFlow.Flow[E].Beep = 0;
						while( File.Buf[i]!='\n' )
						{
							if( File.Buf[i]=='X' )
								WorkerFlow.Flow[E].Beep = 'X';
							i++;
						}
						File.ReadPtr[E] = i+1;
						step = 5;
						wks++;
						break;
					default:
						break;
				}
				break;
			case 1:
				if( File.Buf[i]=='B' )
				{
					File.End[A] = i-1;
					i--;
					step = 0;
				}
				else if( i==File.Len-1 )
					File.End[A] = i+1;
				else if( !ValidChar(File.Buf[i]) )
					File.End[A] = i-1;
				break;
			case 2:
				if( File.Buf[i]=='C' )
				{
					File.End[B] = i-1;
					i--;
					step = 0;
				}
				else if( i==File.Len-1 )
					File.End[B] = i+1;
				else if( !ValidChar(File.Buf[i]) )
					File.End[B] = i-1;
				break;
			case 3:
				if( File.Buf[i]=='D' )
				{
					File.End[C] = i-1;
					i--;
					step = 0;
				}
				else if( i==File.Len-1 )
					File.End[C] = i+1;
				else if( !ValidChar(File.Buf[i]) )
					File.End[C] = i-1;
				break;
			case 4:
				if( File.Buf[i]=='E' )
				{
					File.End[D] = i-1;
					i--;
					step = 0;
				}
				else if( i==File.Len-1 )
					File.End[D] = i+1;
				else if( !ValidChar(File.Buf[i]) )
					File.End[D] = i-1;
				break;
			case 5:
				if( i==File.Len-1 )
					File.End[E] = i+1;
				else if( !ValidChar(File.Buf[i]) )
					File.End[E] = i-1;
				break;
			default:
				break;
		}
		i++;
	}
	//保存工人人数
	WorkerFlow.Workers = wks;
}

INT32 ReadLine( UINT8 worker )
{
	UINT16 size;
	UINT8 *src,*dst;
	src = &File.Buf[File.ReadPtr[worker]];
	dst = &String.Buf[0];
	if( NULL==dst )
		return -1;
	if( NULL==src || '\0'==*src )
		return -1;
	if( File.ReadPtr[worker]>=File.End[worker] )
		return -1;	
	size = STRING_SIZE;
	String.Len = 0;
	while( *src!='\n' && size-->0 && File.ReadPtr[worker]<File.Len )
	{
		*dst++ = *src++;
		File.ReadPtr[worker]++;
		String.Len++;
	}
	*dst++ = *src++;
	File.ReadPtr[worker]++;
	String.Len++;
	return 0;
} 

UINT8 ReadFile( INT8 *filepath ) 
{	
	if( !znFAT_Open_File(&FileInfo,filepath,0,1) ) //FileInfo是文件信息结构体,用来记录打开的文件的重要参数信息
	{
		File.Len=znFAT_ReadData(&FileInfo,0,FILE_SIZE,File.Buf); //读取打开的当前文件,0表示从0位置开始读,45表示读取45个字节,file_buf是数据缓冲区
		znFAT_Close_File(&FileInfo); //关闭文件
		if( FILE_SIZE == File.Len )
			return 2;
		InitFileInfo();
		return 0;
	}
	return 1;
}

void DecodeString( UINT8 Worker )
{
	UINT16 i,k,seg,word;
	BOOL segFlag,wordFlag;
	char str[5];
	//填充其它字符为空格
	for( k=0; k<String.Len; k++ )
	{
		if( String.Buf[k]>='0'&&String.Buf[k]<='9' || String.Buf[k]==',' || (String.Buf[k]>='A' && String.Buf[k]<='E') || String.Buf[k]=='X' )
		{
			continue;
		}
		String.Buf[k] = ' ';
	}
	i = 0;
	seg = word = 0;
	segFlag=wordFlag=0;
	memset( WorkerFlow.Flow[Worker].Sign, 0, 3*MAX_ITEMS );
	for( k=0; k<String.Len; k++ )
	{
		if( String.Buf[k]>='0'&&String.Buf[k]<='9')
		{
			str[i++] = String.Buf[k];
			segFlag = 1;
			wordFlag = 1;
		}
		//else if(String.Buf[k]>='A' &&  String.Buf[k]<='E' )
		//{ 
		//}
		if( (String.Buf[k]==' '||String.Buf[k]==',') && wordFlag )
		{
			wordFlag = 0;
			str[i++]='\n';
			if( seg<MAX_SEGS && word<MAX_ITEMS )
				WorkerFlow.Flow[Worker].Sign[seg][word] = (UINT8)atoi(str);

			if( word<MAX_ITEMS-1 )
				word ++;

			i = 0;
		}
		if( String.Buf[k]==' ' && segFlag )
		{
			segFlag = 0;
			seg ++;
			word = 0;
		}
	}
}
/*
BOOL SearchIndex( u8 *str,u8 *filename )
{
	u16 i,j,k;
	if( FAT32_Open_File(&FileInfo,"index.txt",0) )
	{
		File.Len=FAT32_Read_File(&FileInfo,0,FILE_SIZE,File.Buf);
		FAT32_File_Close(&FileInfo);
		while( i<File.Len )
		{
			if( strncmp((char*)str,(char*)&File.Buf[i],10)==0 )
			{
				while( (File.Buf[i++]!='=') && (i<File.Len) );
				j = i;
				while( (File.Buf[i++]!=0x0d) && (i<File.Len) );
				k = i-j;
				strncpy((char*)filename,(char*)&File.Buf[i],k);
				return 0;
			}
			while( (File.Buf[i++] != 0x0a) && (i<File.Len) );
		}
	}
	return 1;
}*/

看回去10多年前的程序,很稚嫩,还不会用太多的字符操作函数,直接字节比较,周期长不止还容易出错调试困难,后面学习不断累积新技术解决旧的问题,开发也是更加的轻而易举。

	for( k=0; k<String.Len; k++ )
	{
		if( String.Buf[k]>='0'&&String.Buf[k]<='9')
		{
			str[i++] = String.Buf[k];
			segFlag = 1;
			wordFlag = 1;
		}
		//else if(String.Buf[k]>='A' &&  String.Buf[k]<='E' )
		//{ 
		//}
		if( (String.Buf[k]==' '||String.Buf[k]==',') && wordFlag )
		{
			wordFlag = 0;
			str[i++]='\n';
			if( seg<MAX_SEGS && word<MAX_ITEMS )
				WorkerFlow.Flow[Worker].Sign[seg][word] = (UINT8)atoi(str);

			if( word<MAX_ITEMS-1 )
				word ++;

			i = 0;
		}
		if( String.Buf[k]==' ' && segFlag )
		{
			segFlag = 0;
			seg ++;
			word = 0;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ABAP是一种用于SAP系统开发的编程语言,其中pp模块是SAP系统中的生产计划模块,主要用于生产计划、生产过程控制和生产数据记录等。 ABAP开发在pp模块中的要点如下: 1. 熟悉pp模块的基础知识:了解pp模块的功能和流程,包括物料需求计划、生产订单、工作中心、生产版本等。这些知识对于正确理解和开发与pp模块相关的程序非常重要。 2. 掌握ABAP语言特性:ABAP作为SAP系统的开发语言,开发人员需要掌握其语法和特性,例如数据类型、变量声明、循环语句、条件语句等。这些知识将帮助开发人员编写高效且可靠的pp模块程序。 3. 理解生产计划数据结构:pp模块涉及的数据结构较为复杂,包括物料清单、工艺路线、生产订单等。开发人员需要了解这些数据结构的组成和关系,以便能够正确地读取和处理这些数据。 4. 开发报表和界面程序:PP模块通常需要输出各种类型的报表,如生产订单报表、工序报表等。开发人员需要根据用户需求设计和开发这些报表,并保证它们的准确性和易用性。 5. 数据验证和错误处理:在pp模块开发中,数据的准确性和可靠性非常重要。开发人员需要编写适当的代码来验证用户输入的数据,并能够处理各种可能的错误情况,以保证系统的稳定性和可靠性。 总之,ABAP开发在pp模块中需要掌握相关的知识和技术,包括pp模块的基础知识、ABAP语言特性、数据结构、报表和界面开发以及数据验证和错误处理等方面。只有掌握这些要点,才能够开发出高质量和高效率的pp模块程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵向深耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值