您尚未登录。

楼主 # 2023-10-11 13:56:19

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

单片机板有8个输入信号以及若干个输出信号。客户提出要求,希望能通过上位机来配置这8个信号的逻辑关系实现与或操作。头大,不知道该怎么实现。想过如下办法:
1,上位机传递输入信号的序号,然后将所有逻辑关系按序号排出来,将逻辑关系序号也发给单片机,单片机按需要去反推逻辑关系。但是可能的逻辑关系也太多了...
因为只有与和或两种逻辑关系,有群友指出有2^8种排列。
2,上位机发送输入信号的序号,然后再发送几组数据,每组数据包含两个参与操作的信号打序号,再包含一个逻辑关系。这样的话,需要上位机先推算出运算打先后顺序。上位机这里有点麻烦。
3,上位机直接将逻辑运算发送给单片机,包括括号以及运算符,这样上位机就简单了,但是单片机这里就很难了。
如果单片机收到的是类似“x1 && (x2 || x3)"这样的字符串,能否直接转化为可执行语句来执行?

请大家给个思路。

最近编辑记录 Gentlepig (2023-10-11 14:49:11)

离线

#1 2023-10-11 14:33:07

4610
会员
注册时间: 2022-10-09
已发帖子: 101
积分: 82

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

传真值表呗,
8in 8out 也就256字节

离线

楼主 #2 2023-10-11 15:12:58

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

4610 说:

传真值表呗,
8in 8out 也就256字节

输入是8个,输出不确定,可能更多。

离线

#3 2023-10-11 16:52:26

DDER
会员
注册时间: 2023-08-16
已发帖子: 21
积分: 26

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

可以用第3种方法 关键字  后缀表达式 
这里要用到 栈 ,前提是上位机发送过来的句子是完整的。以下是复制过来的,可以参考一下。
1、首先从左到右扫描每一个字符。如果扫描到的字符是操作数(如a、b等),就直接将操作数push进操作数栈中。
2、如果扫描到的字符是一个操作符,分三种情况:
(1) 如果操作符栈是空的,直接将操作符push到操作符栈中。
(2) 如果该操作符的优先级大于操作符栈栈顶的操作符,就直接将操作符push到操作符栈中。(因为该操作符运算会比栈中的优先级低的先进行运算)
(3)如果该操作符为+、-、*、/等且优先级低于栈顶的操作符,就将栈顶的操作符pop, 直到该操作符的优先级大于栈顶端的操作符,将扫描到的操作符push到栈中。
3、如果遇到的操作符是左括号"(”,就直接将该操作符push到操作符栈中。
4、如果扫描到的操作符是右括号“)”,将操作符栈中的操作符(pop)且操作数栈中出栈两个元素进行运算,运算完之后再push回操作数栈,直到遇见左括号“(”,最后将操作符栈中的左括号pop掉。
5、如果输入的中缀表达式已经扫描完了,但是操作符栈中仍然存在操作符的时候,我们应该将操作符栈中的操作符pop,然后进行操作数栈的运算。

离线

#4 2023-10-12 02:55:09

4610
会员
注册时间: 2022-10-09
已发帖子: 101
积分: 82

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

Gentlepig 说:
4610 说:

传真值表呗,
8in 8out 也就256字节

输入是8个,输出不确定,可能更多。

线性的,不是指数关系
32个输出  表1kb

离线

#5 2023-10-12 08:21:59

搬石头者
会员
注册时间: 2020-03-13
已发帖子: 7
积分: 7

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

他是要你实现一个 PLC 啊

离线

#6 2023-10-12 09:00:04

kin
会员
注册时间: 2020-04-06
已发帖子: 31
积分: 75.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

用3楼说的方法就可以了,这是非常经典的计算表达式的算法

离线

#7 2023-10-12 09:31:56

duanlin
会员
注册时间: 2023-10-09
已发帖子: 13
积分: 44

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

做法的决定,要看需求。
如果可变逻辑中可以转变成单线顺序计算,则可以以“【INx】【运算符enum】【INx】【运算符enum】。。。”形式下发给单片机运行,执行机构以循环就可以算结果。较为简单。
如果可变逻辑中包含类似(INx + INx) * (INx + INx)这种计算,这个在编译器领域叫做未决表达式,计算中途需要临时存储,需要分配寄存器或临时栈变量。这种较为复杂需要编译行为,最好在上机做,要有临时变量的表示手段,需要以类似“【INx】【运算符enum】【INx】【变量x】。。。【变量x】【运算符enum】【变量x】“形式下发单片机运行,执行机需要有几个变量槽位。

离线

#8 2023-10-12 10:03:09

muxi01
会员
注册时间: 2020-10-24
已发帖子: 62
积分: 144

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

字符串解析呗+递归

离线

楼主 #9 2023-10-12 14:07:08

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

感谢各位。

关于1里的真值表,我是没搞明白的,分别用1和0表示输入信号的有无,8个输入信号的话,组合就是2^8=256种。那么需要上位机算出这种比如(x1||x2)&&(x3||x4)这种情况下,对应的8个输入有那几种组合,如何输入满足的话,就控制输出。
问了gpt,列出来上式的真值表:

x1 | x2 | x3 | x4 | Output
---------------------------
 0  |  0  |  0  |  0  |   0
 0  |  0  |  0  |  1  |   1
 0  |  0  |  1  |  0  |   1
 0  |  0  |  1  |  1  |   1
 0  |  1  |  0  |  0  |   0
 0  |  1  |  0  |  1  |   1
 0  |  1  |  1  |  0  |   1
 0  |  1  |  1  |  1  |   1
 1  |  0  |  0  |  0  |   0
 1  |  0  |  0  |  1  |   1
 1  |  0  |  1  |  0  |   1
 1  |  0  |  1  |  1  |   1
 1  |  1  |  0  |  0  |   1
 1  |  1  |  0  |  1  |   1
 1  |  1  |  1  |  0  |   1
 1  |  1  |  1  |  1  |   1

可以看到output是1的就有13项,那么我需要判断输入信号是否是这13项里的其中一个,是的话,就满足。

这种方法的话,需要上位机计算出真值表里output为1的项目,把对应的输入状态,发给单片机吧?比如上式,就需要将

x1 | x2 | x3 | x4 | Output
---------------------------
 0  |  0  |  0  |  1  |   1
 0  |  0  |  1  |  0  |   1
 0  |  0  |  1  |  1  |   1
 0  |  1  |  0  |  1  |   1
 0  |  1  |  1  |  0  |   1
 0  |  1  |  1  |  1  |   1
 1  |  0  |  0  |  1  |   1
 1  |  0  |  1  |  0  |   1
 1  |  0  |  1  |  1  |   1
 1  |  1  |  0  |  0  |   1
 1  |  1  |  0  |  1  |   1
 1  |  1  |  1  |  0  |   1
 1  |  1  |  1  |  1  |   1

这些发给单片机去进行判断吧?
这样倒是简单些,但是实际应该把8个输入都考虑进去,这样最后就是就是一种输出结果可能对应着非常多的输入情况,比如几十个。

又想了想,应该真值表里的256项都写入单片机。单片机里利用switch()判断输入是否在真值表里对应的output是否为1,为1的话,说明输入满足逻辑关系。

最近编辑记录 Gentlepig (2023-10-12 14:32:40)

离线

楼主 #10 2023-10-12 14:35:44

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

4610 说:
Gentlepig 说:
4610 说:

传真值表呗,
8in 8out 也就256字节

输入是8个,输出不确定,可能更多。

线性的,不是指数关系
32个输出  表1kb

没明白这里为啥是1kb?
输入的每种逻辑关系,只对应一种输出形式。所以表应该还是按输入的数量8来决定大小吧?输出只是一个4字节变量来控制32个输出,这样?

离线

楼主 #11 2023-10-12 14:48:25

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

对于方法3,别墅业主群里很多群友推荐了。其中有朋友推荐了c4.c,我看到简介里写的c in four function。我以为是四则运算呢?结果晚上刷知乎搜c4.c才知道是实现了编译器...虽然里边也有四则运算符,也有与或逻辑运算符,但是我觉得对于我来说内容有深度了...
搜  使用栈完成算术表达式  搜到这么一篇文章,觉得不多:
https://www.cnblogs.com/inghzhang/p/3901334.html
还没仔细看。

最近编辑记录 Gentlepig (2023-10-12 16:25:47)

离线

楼主 #12 2023-10-12 17:29:26

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@Gentlepig

才发现gpt给的真值表不对...
(x1|x2)&(x3|x4),就是1和2中有一个输入有效,且3和4中有一个输入有效,则满足条件。
结果发现2、3、4行,x1和x2都是零的情况下,out为1了...

离线

#13 2023-10-12 18:41:47

4610
会员
注册时间: 2022-10-09
已发帖子: 101
积分: 82

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@Gentlepig
对,8个输入决定了有256种状态,32路输出即4byte,相乘=1kb

既然是真值表,直接根据输入算出储存的位置就是了
o = b^c
a b c o
0 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 0

map = {0, 1, 1, 0, 0, 1, 1, 0}
o = map[a<<2 | b<<1 | c]
mcu上处理多简单

离线

楼主 #14 2023-10-12 19:14:17

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@4610
可是,单片机c语言没有map这种数据结构啊...

另外的问题就是,上位机如何根据输入逻辑关系,计算出真值表来...

-------------------------------------

好像有一点明白了,这是上位机计算真值表的方式,上位机枚举出256种组合,然后代入到表达式里看结果。

最近编辑记录 Gentlepig (2023-10-13 09:02:40)

离线

#15 2023-10-13 10:07:03

4610
会员
注册时间: 2022-10-09
已发帖子: 101
积分: 82

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@Gentlepig
不需要map,普通的线性表,数组表示
3in:map[8]
8in:map[256]

离线

#16 2023-10-13 10:14:10

小智
会员
注册时间: 2019-10-16
已发帖子: 112
积分: 84

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

可以通过多维数字实现,定义一个多维数组uint32 map[2][2][2][2][2][2][2][2];上位机生成遍历数值,不就行了,8路输入,依次填入下标,输出值完成,最多是1K的真值表,搞定

离线

楼主 #17 2023-10-13 12:11:41

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

小智 说:

可以通过多维数字实现,定义一个多维数组uint32 map[2][2][2][2][2][2][2][2];上位机生成遍历数值,不就行了,8路输入,依次填入下标,输出值完成,最多是1K的真值表,搞定

看不懂这个map[2][2][2][2][2][2][2][2],每一个[2]对应一个输入的0和1两种状态吗?

依次填入下标,这句话也没看明白。是将遍历输入值,代入逻辑表达式吗?

离线

#18 2023-10-13 14:47:28

skrlaoshiren
会员
注册时间: 2019-12-03
已发帖子: 42
积分: 102

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

上位机解析输入表达式,然后把256种输入结果全算出来,然后凑成真值表发给下位机,下位机最差的情况就是256种情况全判断。上位机负责解析表达式和计算真值表,下位机就解析真值表。解析表达式就用c4.c,加减乘除运算不需要,只用到与和或。

最近编辑记录 skrlaoshiren (2023-10-13 14:50:34)

离线

楼主 #19 2023-10-13 15:10:55

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

4610 说:

@Gentlepig
不需要map,普通的线性表,数组表示
3in:map[8]
8in:map[256]

明白了,感谢。

@skrlaoshiren @小智
感谢。

最近编辑记录 Gentlepig (2023-10-13 15:11:22)

离线

楼主 #20 2023-10-14 14:59:41

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

https://blog.csdn.net/crr411422/article/details/130306750

按这个文章里的代码抄了一遍,没用malloc申请栈空间,而是用了固定数组,把浮点数变量改成了uint8类型,在pc上gcc编译后,可以运行进行整数四则运算。
又将里边的“+-*/”改成了“&|”,可以进行逻辑运算。

$ ./test5
Enter an infix expression: 1&1
infix notation: 1&1
Postfix notation: 1 1 &
Result: 1
$ ./test5
Enter an infix expression: 1&(0|1)
infix notation: 1&(0|1)
Postfix notation: 1 0 1 | &
Result: 1
$ ./test5
Enter an infix expression: (1|1)&(0|1)
infix notation: (1|1)&(0|1)
Postfix notation: 1 1 | 0 1 | &
Result: 1
$ ./test5
Enter an infix expression: (0|1)&(1&0)
infix notation: (0|1)&(1&0)
Postfix notation: 0 1 | 1 0 & &
Result: 0
$ ./test5
Enter an infix expression: (0|1)&(1|0)
infix notation: (0|1)&(1|0)
Postfix notation: 0 1 | 1 0 | &
Result: 1

最近编辑记录 Gentlepig (2023-10-14 15:00:04)

离线

#21 2023-10-14 22:52:01

kin
会员
注册时间: 2020-04-06
已发帖子: 31
积分: 75.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

移植这个函数,返回指定引脚电平:

uint8_t get_pin_value(char pin)
{
	switch (pin) {
	case '1': return 1;
	case '2': return 0;
	case '3': return 1;
	case '4': return 0;
	case '5': return 1;
	case '6': return 0;
	case '7': return 0;
	case '8': return 0;
	default: break;
	}
	return 0;
}

计算表达式算法:

#include <stdint.h>
#include <stdbool.h>

#define STACK_SIZE			64
static char stkbuf[STACK_SIZE];
static int stk_top_idx = -1;

static int stk_size(void)
{
	return stk_top_idx + 1;
}

static char stk_top(void)
{
	if (stk_top_idx < 0)
		return 0;
	return stkbuf[stk_top_idx];
}

static void stk_push(char chr)
{
	if (stk_top_idx >= (STACK_SIZE - 1))
		return;
	stkbuf[++stk_top_idx] = chr;
}

static void stk_pop(void)
{
	if (stk_top_idx >= 0)
		stk_top_idx--;
}

static void stk_clear(void)
{
	stk_top_idx = -1;
}

#define RPN_BUF_SIZE		64
static char rpnbuf[RPN_BUF_SIZE];
static int rpn_cnt = 0;


bool reverse_polish_notatio_append_chr(char chr)
{
	bool ok;

	if (chr == '(') {
		stk_push(chr);
	}
	else if (chr == ')') {
		ok = false;
		while (stk_size() > 0) {
			chr = stk_top();
			stk_pop();
			if (chr == '(') {
				ok = true;
				break;
			}
			rpnbuf[rpn_cnt++] = chr;
		}
		if (!ok)
			return false;
	}
	else if (chr == '|' || chr == '&') {
		if (stk_size() > 0) {
			char chr_top = stk_top();
			if (chr_top != '(') {
				stk_pop();
				rpnbuf[rpn_cnt++] = chr_top;
			}
			stk_push(chr);
		}
		else {
			stk_push(chr);
		}
	}
	else if ((chr >= '1') && (chr <= '8')) {
		rpnbuf[rpn_cnt++] = chr;
	}
	else {
		return false;
	}

	return true;
}

bool run_exp(const char *exp, uint8_t *result)
{
	int i;
	char chr, v1, v2, v;
	uint8_t flag_result = 0x80;

	rpn_cnt = 0;
	stk_clear();

	while ((chr = exp[0])) {
		switch (chr) {
		case 'x':
			chr = exp[1];
			if ((chr < '1') && (chr > '8'))
				return false;
			if (!reverse_polish_notatio_append_chr(chr))
				return false;
			exp += 2;
			break;
		case '&':
		case '|':
			if (exp[1] != chr)
				return false;
			if (!reverse_polish_notatio_append_chr(chr))
				return false;
			exp += 2;
			break;
		case '(':
		case ')':
			if (!reverse_polish_notatio_append_chr(chr))
				return false;
			exp++;
			break;
		case ' ':
			exp++;
			break;
		default:
			break;
		}
	}

	stk_clear();
	for (i = 0; i < (int)rpn_cnt; i++) {
		chr = rpnbuf[i];
		if (chr >= '1' && chr <= '8') {
			stk_push(chr);
		}
		else if ((chr == '|') || (chr == '&')) {

			if (stk_size() <= 0)
				return false;
			v2 = stk_top();
			stk_pop();

			if (stk_size() <= 0)
				return false;
			v1 = stk_top();
			stk_pop();

			if ((v2 & flag_result) == 0)
				v2 = get_pin_value(v2);
			if ((v1 & flag_result) == 0)
				v1 = get_pin_value(v1);

			v1 &= ~flag_result;
			v2 &= ~flag_result;

			v = (chr == '|') ? v1 || v2 : v1 && v2;

			stk_push(flag_result | v);
		}
	}

	if (stk_size() == 1) {
		*result = (stk_top() & 0x7f);
		return true;
	}

	return false;
}

测试:

int main(int argc, char *argv[])
{
	const char *exp = "(((x1 || x2 && x3)) && (x4 || x5))";
	uint8_t result;

	if (run_exp(exp, &result)) {
		printf("rst: %d\n", result);
	}
	else {
		printf("calc fail\n");
	}

	return 0;
}

输出结果:

rst: 1

离线

楼主 #22 2023-10-16 09:17:01

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@kin

这是专门为了我的需求写了个程序?太感谢了。

-----------------------------------

因为没有注释,有不少地方没看明白,比如各函数的用途,rpnbuf[ ]数组的用途。

reverse_polish_nnotatio_append_char()这个函数,
如果给的是'(',则压入stk里;
如果是')',则从stk里取出数据放到rpnbuf里;
如果是'&'或者'|',如果栈里没数据,则入栈,如果有数据,取栈顶数据,如果是'(',则将符号入栈,否则,将栈顶字符串出栈,存到rpnbuf数组里,不知道这里为什么要存到rpnbuf里。
如果是字符1-8,则直接存到rpnbuf里。

感觉rpnbuf像是完成后缀表达式的存放位置,但不确定。


run_exp( )函数里也有不明白的地方:
while((chr = exp[0])){...}这里只是判断下表达式的第一个字符吗?(这个明白了,while循环里有exp+=2,这样就会遍历整个输入字符串了)
那么这个while循环里,就会把输入表达式里的‘0-9, & , | ( )'分别代入到reverse_polish_notatio_append_chr( )函数里去处理
根据我在上一段落分析,‘0-9’是存到rpnbuf数组里的,‘(xxxx)'括号里的内容,也会存到rpnbuf里。
我的理解是,rpnbuf数组存放的是后缀表达式,但没看明白什么时候把逻辑符号放进去的。而stk是中缀转后缀时存放临时数据的,比如有括号情况下,将左括号及数据先放到stk里,如果再遇到右括号,则将数据从stk里取出来放到rpnbuf数组里。

最近编辑记录 Gentlepig (2023-10-16 10:47:13)

离线

#23 2023-10-16 11:17:07

Jeason1997
会员
注册时间: 2022-06-09
已发帖子: 7
积分: 22

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

通过spi不行吗

离线

#24 2023-10-16 18:03:29

kin
会员
注册时间: 2020-04-06
已发帖子: 31
积分: 75.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@Gentlepig
抱歉,我那代码可能写得不太好,也欠缺相关注释。你的理解是对的,rpnbuf储存的就是后缀表达式。
首先建立一个空栈和用来储存后缀表达式的缓冲区,然后遍历整个字符串,根据以下原则做处理:
    遇到操作数(这里是x1、x2和x3之类),直接将x后面的字符(如'1'、'2'、'3'等)追加到rpnbuf中。
    遇到'(',将其入栈。
    遇到')',将栈顶元素依次弹出并追加到rpnbuf中,直到遇到')',然后将'('从栈中弹出。
    遇到运算符(这里是||和&&,但是为方便后续处理,储存的时候只储存'|'和'&'):
    1、如果栈为空或者栈顶是'(',则直接将当前运算符入栈。。
    2、如果该运算符的优先级高于栈顶运算符,则直接将其入栈。
    3、如果该运算符的优先级低于或等于栈顶运算符,则将栈顶运算符弹出并追加到rpnbuf中,然后将当前运算符入栈。

由于本案例中只涉及'||'和'&&'这两个运算符,并且它们的优先级是相等的,因此我的代码里并没有优先级判定这部分代码,也就是说,在上面的”遇到运算符“的处理中,只处理了第1点和第3点。

对于rpnbuf的处理:
    先建立一个空栈,然后按顺序遍历后缀表达式(即rpnbuf)的每个字符:
        遇到操作数时,将其入栈。
        遇到操作符时,从栈顶依次取出2个操作数进行计算,并将计算结果重新入栈。
    遍历完后缀表达式后,栈中的唯一元素就是最终的计算结果。

另外,因为本案例中,表达式中的操作数是个不确定的值,需要从芯片引脚获取电平来确定实际的值,所以在处理rpnbuf操作数的时候,需要标记这个操作数到底是中间运算结果还是需要从芯片引脚读取。我的代码只做了个简单的处理,就是如果是中间运算结果,那就位或0x80(即最高位置1),如果直接是'1'~'8',那就从芯片引脚中取电平来确定这个值是0还是1,根据最高位来判定是直接计算还是从芯片引脚读取电平。

不知道我说明白了没有,希望能对你有用。关于中缀表达式转后缀表达式的方法,网上也有其他相关资料可以参考一下。

离线

楼主 #25 2023-10-17 09:23:13

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@kin 感谢,讲得很详细了,使我进一步加深了对栈和后缀表达式的理解。

最近编辑记录 Gentlepig (2023-10-17 09:23:35)

离线

#26 2023-10-17 10:55:42

4610
会员
注册时间: 2022-10-09
已发帖子: 101
积分: 82

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

上位机直接选个支持eval的语言就完事了…

离线

#27 2023-10-20 17:12:07

xiaohui
会员
注册时间: 2019-01-15
已发帖子: 259
积分: 122.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

啥也不想说,直接看代码

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

// str: x1&&(x2||x3)&&(x4||x5)
// planA
// ra0 = X3 || X2
// ra1 = ra0 && x1
// ra0 = x4 || x5
// ra1 = ra0 && ra1
// planB
// ra0 = X3 || X2
// ra1 = x4 || x5
// ra0 = ra0 && ra1
// ra0 = ra0 && x1

/*
x1&&(x2||(x3&&x4))&&(x5||x6)

ra1= x3 &&  x4
ra0=ra1 ||  x2
ra1= x5 ||  x6
ra0=ra1 && ra0
ra0=ra0 &&  x1

X1
X2
X3
POP -> X3
    POP -> X2
        X1
        ra0
        X5
            POP -> X5
            X1
            ra0




                            I_LOAD X1
                            I_PUSH
                        I_LOAD X2
                        I_PUSH
                            I_LOAD X3
                            I_PUSH
                            I_LOAD X4
                            I_AND1
                            ra1 = x3 && x4
                        I_OR1
                        ra0 = ra1 || x2
                    I_PUSH
                I_LOAD X5
                I_PUSH
            I_LOAD X6
            I_OR1
            ra1 = X5 || x6
        I_AND1
        ra0 = ra1 && ra0
    I_AND1
    ra0=ra0 && X1
I_PUSH
*/

#define is_letter(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
#define is_num(c) (c >= '0' && c <= '9')
#define is_id(c) (is_letter(c) || )
enum{
    STA_IDLE,
    STA_ID,
    STA_AND,
    STA_OR,
    STA_LPAR,
    STA_RPAR,
    STA_EOL,
}sta;

enum{
    I_PUSH,
    // I_POP,
    I_ENTER,
    I_EXIT,
    I_LOAD_A0,
    I_LOAD_A1,
    I_AND1_A0,
    I_AND1_A1,
    I_OR1_A0,
    I_OR1_A1,
    I_AND2_RA0_X_X,
    I_AND2_RA0_RA0_X,
    I_AND2_RA0_RA1_X,
    I_AND2_RA0_RA1_RA0,
    I_AND2_RA0_RA0_RA1,
    // I_AND2_RA0_RA1_RA1,
    I_AND2_RA1_X_X,
    I_AND2_RA1_RA0_X,
    I_AND2_RA1_RA1_X,
    I_AND2_RA1_RA1_RA0,
    // I_AND2_RA1_RA0_RA1,
    I_OR2_RA0_X_X,
    I_OR2_RA0_RA0_X,
    I_OR2_RA0_RA1_X,
    I_OR2_RA0_RA1_RA0,
    I_OR2_RA0_RA0_RA1,
    // I_OR2_RA0_RA1_RA1,
    I_OR2_RA1_X_X,
    I_OR2_RA1_RA0_X,
    I_OR2_RA1_RA1_X,
    I_OR2_RA1_RA1_RA0,
    I_OR2_RA1_RA0_RA1,
    // I_OR2_RA1_RA1_RA1,
    I_UIMP, // end
};
struct {
    int t;
    int i;
} lex_list[1024];
union{
    uint32_t code;
    struct{
        unsigned char op;
        unsigned char a0;
        unsigned char a1;
    }i;
}code_list[100];
union{
    uint32_t code;
    struct{
        unsigned char op;
        unsigned char a0;
        unsigned char a1;
    }i;
}opt_code_list[100];
int lex_list_i;
int code_list_i;
int opt_code_list_i;
int g_parse_i;
static void parse(void);
static void opt(int lev,int ra_i,int init);
static void prt(int lev,int ra_i);
static int vm(void);
int main(int argc,const char** argv){
    int c;
    uint32_t id;
    int res = 0;


	int size = 1024; 
	char* buff = (char*)malloc(size);
    int tmp_c_i = 0;
    lex_list_i = 0;
    code_list_i = 0;
    sta = STA_IDLE;
    if(NULL == fgets(buff,size,stdin)){
        return 0;
    }
    // sprintf(buff,"x1&&(x2||(x3&&x4))&&(x5||x6)\n");
    printf("str: %s\n",buff);
    // buff[strlen(buff)] = '\n';
    while(tmp_c_i <= strlen(buff)){
        c = buff[tmp_c_i];
        tmp_c_i++;
        // printf("c: %c(0x%x) sta: %d\n",c,c,sta);
        // printf("c: %c(0x%x) sta: %d\n",c,c,sta);
    retry:
        
        if(c == '\r' || c == ' ' || c == '\t'){continue;}
        switch(sta){
            case STA_IDLE:
                id = 0;
                // if(is_letter(c)){
                if(c == 'x'){
                    // id = c;
                    sta = STA_ID;
                // }else if(is_num(c)){
                //     id = c;
                //     sta = STA_ID;
                }else if(c == '&'){
                    sta = STA_AND;
                }else if(c == '|'){
                    sta = STA_OR;
                }else if(c == '('){
                    lex_list[lex_list_i].t = STA_LPAR;
                    lex_list[lex_list_i].i = 0;
                    lex_list_i++;
                }else if(c == ')'){
                    lex_list[lex_list_i].t = STA_RPAR;
                    lex_list[lex_list_i].i = 0;
                    lex_list_i++;
                }else if(c == '\n'){
                    goto input_ok;
                }else{
                    // error
                }
            break;
            case STA_ID:
                // if(is_id(c)){
                if(is_num(c)){
                    id = id * 10 + c - '0';
                }else{
                    printf("sta: STA_ID lex_list_i: %d id: %d\n",lex_list_i,id);
                    lex_list[lex_list_i].t = STA_ID;
                    lex_list[lex_list_i].i = id;
                    lex_list_i++;
                    sta = STA_IDLE;
                    goto retry;
                }

            break;
            case STA_AND:
                if(c == '&'){
                    printf("sta: STA_AND\n");
                    lex_list[lex_list_i].t = STA_AND;
                    lex_list[lex_list_i].i = 0;
                    lex_list_i++;
                    sta = STA_IDLE;
                }else{
                    // error
                }
            break;
            case STA_OR:
                if(c == '|'){
                    // printf("sta: STA_OR\n");
                    lex_list[lex_list_i].t = STA_OR;
                    lex_list[lex_list_i].i = 0;
                    lex_list_i++;
                    sta = STA_IDLE;
                }else{
                    // error
                }
            break;
            default:

            break;
        }
        // refresh();
    }
    input_ok:
    free(buff);

    printf("parse lex_list_i:%d\n",lex_list_i);
    g_parse_i = 0;
    if(lex_list_i <= 0){
        // error
        return -1;
    }
    lex_list[lex_list_i].t = STA_EOL;
    lex_list[lex_list_i].i = 0;
    lex_list_i++;
    
    printf("=parse==================================================================================\n");
    parse();

    printf("=prt==================================================================================\n");
    prt(0,0);
    // return 0;
    printf("opt code_list_i:%d\n",code_list_i);
    printf("=opt==================================================================================\n");
    opt(0,0,1);
    opt_code_list[opt_code_list_i].i.op = I_UIMP;
    printf("set opt_code_list[%d] to I_UIMP\n",opt_code_list_i);
    opt_code_list_i++;
    printf("=vm==================================================================================\n");
    res = vm();
    printf("return %d\n",res);
    // while(1);
    return 0;
}

static void parse(void){
    static int s_lpar_cnt = 0;
    // printf("parse g_parse_i:%d lex_list[g_parse_i].t:%d lex_list_i: %d code_list_i:%d\n",g_parse_i,lex_list[g_parse_i].t,lex_list_i,code_list_i);
    // refresh();
    if(g_parse_i > lex_list_i){
        return;
    }
    if(lex_list[g_parse_i].t == STA_EOL){
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == STA_EOL code_list_i:%d\n",g_parse_i,code_list_i);

        return;
    }
    if(lex_list[g_parse_i].t == STA_ID){
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == STA_ID code_list_i:%d lex_list[g_parse_i].i:%d\n",g_parse_i,code_list_i,lex_list[g_parse_i].i);
        // refresh();
        code_list[code_list_i].i.op = I_LOAD_A0;
        code_list[code_list_i].i.a0 = lex_list[g_parse_i].i;
        code_list_i++;
        g_parse_i++;
    }else if(lex_list[g_parse_i].t == STA_AND){
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == STA_AND code_list_i:%d\n",g_parse_i,code_list_i);
        // refresh();
        code_list[code_list_i].i.op = I_PUSH;
        code_list_i++;
        g_parse_i++;
        parse();
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == I_AND1 code_list_i:%d\n",g_parse_i,code_list_i);
        code_list[code_list_i].i.op = I_AND1_A0;
        code_list_i++;
    }else if(lex_list[g_parse_i].t == STA_OR){
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == STA_OR\n",g_parse_i);
        // refresh();
        code_list[code_list_i].i.op = I_PUSH;
        code_list_i++;
        g_parse_i++;
        parse();
        code_list[code_list_i].i.op = I_OR1_A0;
        code_list_i++;
    }else if(lex_list[g_parse_i].t == STA_LPAR){
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == STA_LPAR\n",g_parse_i);
        // refresh();
        // code_list[code_list_i].i.op = I_PUSH;
        // code_list_i++;
        code_list[code_list_i].i.op = I_ENTER;
        code_list_i++;
        g_parse_i++;
        s_lpar_cnt++;
        parse();
        if(lex_list[g_parse_i].t != STA_RPAR){
            // error
        }
        code_list[code_list_i].i.op = I_EXIT;
        code_list_i++;
        return;
    }else if(lex_list[g_parse_i].t == STA_RPAR){
        // printf("parse g_parse_i:%d lex_list[g_parse_i].t == STA_RPAR\n",g_parse_i);
        // refresh();
        if(s_lpar_cnt == 0){
            // error
        }
        s_lpar_cnt--;
        // code_list[code_list_i].i.op = I_POP;
        // code_list_i++;
        g_parse_i++;
        return;
    }else{
        // error
    }
    parse();
}


static void prt(int lev,int ra_i){
    static int pc = 0;
    while(1){
        // printf("opt pc:%d code_list[pc].i.op: %d code_list_i: %d\n",pc,code_list[pc].i.op,code_list_i);
        // refresh();
        if(pc > code_list_i){
            return;
        }
        switch(code_list[pc].i.op){
            case I_PUSH:
                printf("I_PUSH\n");
            break;
            // case I_ENTER:
            //     printf("I_ENTER\n");
            // break;
            // case I_EXIT:
            //     printf("I_EXIT\n");
            //     // return;
            // break;
            case I_LOAD_A0:
                printf("I_LOAD X%d\n",code_list[pc].i.a0);
            break;
            case I_AND1_A0:
                printf("I_AND1\n");
            break;
            case I_OR1_A0:
                printf("I_OR1\n");
            break;
            // case I_AND2:
            // break;
            // case I_OR2:
            // break;
            case I_UIMP:
                return;
            break;
            default:
            break;
        }
        pc++;
    }
}

static void opt(int lev,int ra_i,int init){
    static int pc = 0;
    static struct{
        unsigned char is_ra;
        unsigned char a0;
    } stack[100],cur_ra={1,0};
    static int ra0_isused=0;
    static int ra1_isused=0;
    static int stack_pos_start = (sizeof(stack)/sizeof(stack[0]));
    static int stack_pos_i = (sizeof(stack)/sizeof(stack[0]));
    if(init){
        ra0_isused=0;
        ra1_isused=0;
        stack_pos_start = (sizeof(stack)/sizeof(stack[0]));
        stack_pos_i = (sizeof(stack)/sizeof(stack[0]));
        cur_ra.is_ra = 1;
        cur_ra.a0 = 0;
        opt_code_list_i = 0;
    }
    // cur_ra.is_ra = 1;
    while(1){
        // printf("opt ra0_isused: %d ra1_isused: %d stack_pos_start: %d stack_pos_i: %d\n",ra0_isused,ra1_isused,stack_pos_start,stack_pos_i);
        // printf("opt pc:%d code_list[pc].i.op: %d code_list_i: %d\n",pc,code_list[pc].i.op,code_list_i);
        if(pc > code_list_i){
            return;
        }
        switch(code_list[pc].i.op){
            case I_PUSH:
                // printf("I_PUSH is_ra: %d a0: %d\n",cur_ra.is_ra,cur_ra.a0);
                stack[stack_pos_i].is_ra = cur_ra.is_ra;
                stack[stack_pos_i].a0 = cur_ra.a0;
                stack_pos_i--;
            break;
            case I_ENTER:
                // printf("I_ENTER ra0_isused: %d ra1_isused: %d\n",ra0_isused,ra1_isused);
                pc++;
                if(ra0_isused == 0){
                    ra0_isused=1;
                    ra1_isused=0;
                    opt(lev+1,0,0);
                }else if(ra0_isused == 1){
                    ra0_isused=1;
                    ra1_isused=1;
                    opt(lev+1,1,0);
                }else if(ra1_isused == 1){
                    printf("ra1_isused == 1\n");exit(-1);
                }else{
                    printf("ra0_isused: %d ra1_isused: %d\n",ra0_isused,ra1_isused);exit(-1);
                }
            break;
            case I_EXIT:
                // printf("I_EXIT\n");
                // stack_pos_i++;
                // printf("I_EXIT is_ra:%d a0:%d\n",stack[stack_pos_i].is_ra,stack[stack_pos_i].a0);
                // cur_ra.is_ra = stack[stack_pos_i].is_ra;
                // cur_ra.a0 = stack[stack_pos_i].a0;
                return;
            break;
            case I_LOAD_A0:
                // printf("I_LOAD X%d\n",code_list[pc].i.a0);
                cur_ra.is_ra = 0;
                cur_ra.a0 = code_list[pc].i.a0;
            break;
            case I_AND1_A0:
                stack_pos_i++;
                // printf("I_AND1 cur_ra.is_ra: %d cur_ra.a0: %d stack_pos_i: %d stack[stack_pos_i].is_ra: %d\n",cur_ra.is_ra,cur_ra.a0,stack_pos_i,stack[stack_pos_i].is_ra);
                if(cur_ra.is_ra == 0 && stack[stack_pos_i].is_ra == 0){
                    // a0 && a1
                    if(ra_i == 0){
                        opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_X_X;
                        opt_code_list[opt_code_list_i].i.a0 = cur_ra.a0;
                        opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                        printf("ra0 = X%d && X%d\n",cur_ra.a0,stack[stack_pos_i].a0);
                    } else if(ra_i == 1){
                        opt_code_list[opt_code_list_i].i.op = I_AND2_RA1_X_X;
                        opt_code_list[opt_code_list_i].i.a0 = cur_ra.a0;
                        opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                        printf("ra1 = X%d && X%d\n",cur_ra.a0,stack[stack_pos_i].a0);
                    }
                    opt_code_list_i++;
                }else if(cur_ra.is_ra == 1 && stack[stack_pos_i].is_ra == 0){
                    if(ra_i == 0){
                        if(cur_ra.a0 == 0){
                            opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_RA0_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra0 = ra0 && X%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_RA1_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra0 = ra1 && X%d\n",stack[stack_pos_i].a0);
                        }
                    } else if(ra_i == 1){
                        if(cur_ra.a0 == 0){
                            opt_code_list[opt_code_list_i].i.op = I_AND2_RA1_RA0_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra1 = ra0 && X%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            opt_code_list[opt_code_list_i].i.op = I_AND2_RA1_RA1_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra1 = ra1 && X%d\n",stack[stack_pos_i].a0);
                        }
                    }
                    opt_code_list_i++;
                }else if(cur_ra.is_ra == 1 && stack[stack_pos_i].is_ra == 1){
                    if(ra_i == 0){
                        if(cur_ra.a0 == 0){
                            if(stack[stack_pos_i].a0 == 0){
                                // opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_RA0_RA0;
                                printf("ra0 = ra0 && ra0\n");exit(-1);
                            }else if(stack[stack_pos_i].a0 == 1){
                                opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_RA0_RA1;
                            }
                            printf("ra0 = ra0 && ra%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            if(stack[stack_pos_i].a0 == 1){
                                // opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_RA0_RA0;
                                printf("ra0 = ra1 && ra1\n");exit(-1);
                            }else if(stack[stack_pos_i].a0 == 0){
                                opt_code_list[opt_code_list_i].i.op = I_AND2_RA0_RA1_RA0;
                            }
                            printf("ra0 = ra1 && ra%d\n",stack[stack_pos_i].a0);
                        }
                        opt_code_list_i++;
                    } else if(ra_i == 1){
                        if(cur_ra.a0 == 0){
                            opt_code_list[opt_code_list_i].i.op = I_AND2_RA1_RA0_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra1 = ra0 && X%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            opt_code_list[opt_code_list_i].i.op = I_AND2_RA1_RA1_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra1 = ra1 && X%d\n",stack[stack_pos_i].a0);
                        }
                        opt_code_list_i++;
                    }
                }
                cur_ra.is_ra = 1;
                cur_ra.a0 = ra_i;
            break;
            case I_OR1_A0:
                stack_pos_i++;
                // printf("I_OR1 cur_ra.is_ra: %d cur_ra.a0: %d stack_pos_i: %d stack[stack_pos_i].is_ra: %d\n",cur_ra.is_ra,cur_ra.a0,stack_pos_i,stack[stack_pos_i].is_ra);
                if(cur_ra.is_ra == 0 && stack[stack_pos_i].is_ra == 0){
                    // a0 || a1
                    if(ra_i == 0){
                        opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_X_X;
                        opt_code_list[opt_code_list_i].i.a0 = cur_ra.a0;
                        opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                        printf("ra0 = X%d || X%d\n",cur_ra.a0,stack[stack_pos_i].a0);
                    } else if(ra_i == 1){
                        opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_X_X;
                        opt_code_list[opt_code_list_i].i.a0 = cur_ra.a0;
                        opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                        printf("ra1 = X%d || X%d\n",cur_ra.a0,stack[stack_pos_i].a0);
                    }
                    opt_code_list_i++;
                }else if(cur_ra.is_ra == 1 && stack[stack_pos_i].is_ra == 0){
                    if(ra_i == 0){
                        if(cur_ra.a0 == 0){
                            opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_RA0_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra0 = ra0 || X%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_RA1_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra0 = ra1 || X%d\n",stack[stack_pos_i].a0);
                        }
                        opt_code_list_i++;
                    } else if(ra_i == 1){
                        if(cur_ra.a0 == 0){
                            opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_RA0_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra1 = ra0 || X%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_RA1_X;
                            opt_code_list[opt_code_list_i].i.a1 = stack[stack_pos_i].a0;
                            printf("ra1 = ra1 || X%d\n",stack[stack_pos_i].a0);
                        }
                        opt_code_list_i++;
                    }
                }else if(cur_ra.is_ra == 1 && stack[stack_pos_i].is_ra == 1){
                    if(ra_i == 0){
                        if(cur_ra.a0 == 0){
                            if(stack[stack_pos_i].a0 == 0){
                                // opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_RA0_RA0;
                                printf("ra0 = ra0 || ra0\n");exit(-1);
                            }else if(stack[stack_pos_i].a0 == 1){
                                opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_RA0_RA1;
                            }
                            printf("ra0 = ra0 || ra%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            if(stack[stack_pos_i].a0 == 1){
                                // opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_RA1_RA1;
                                printf("ra0 = ra1 || ra1\n");exit(-1);
                            }else if(stack[stack_pos_i].a0 == 0){
                                opt_code_list[opt_code_list_i].i.op = I_OR2_RA0_RA1_RA0;
                            }
                            printf("ra0 = ra1 || ra%d\n",stack[stack_pos_i].a0);
                        }
                        opt_code_list_i++;
                    } else if(ra_i == 1){
                        if(cur_ra.a0 == 0){
                            if(stack[stack_pos_i].a0 == 0){
                                // opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_RA0_RA0;
                                printf("ra1 = ra0 || ra0\n");exit(-1);
                            }else if(stack[stack_pos_i].a0 == 1){
                                opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_RA0_RA1;
                            }
                            printf("ra1 = ra0 || ra%d\n",stack[stack_pos_i].a0);
                        }else if(cur_ra.a0 == 1){
                            if(stack[stack_pos_i].a0 == 1){
                                // opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_RA0_RA0;
                                printf("ra1 = ra1 || ra1\n");exit(-1);
                            }else if(stack[stack_pos_i].a0 == 0){
                                opt_code_list[opt_code_list_i].i.op = I_OR2_RA1_RA1_RA0;
                            }
                            printf("ra1 = ra1 || ra%d\n",stack[stack_pos_i].a0);
                        }
                        opt_code_list_i++;
                    }
                }
                cur_ra.is_ra = 1;
                cur_ra.a0 = ra_i;
            break;
            case I_UIMP:
                return;
            break;
            default:
            break;
        }
        pc++;
    }
}

// 只有vm需要存放在单片机里,只需要把opt_code_list数组从上位机传输到单片机里,vm函数只依赖opt_code_list数组。
static int vm(void){
    int pc = 0;
    int ra0 = 0;
    int ra1 = 0;
    static int x[6];
    int run = 1;
    x[0] = 0;
    x[1] = 0;
    x[2] = 2;
    x[3] = 3;
    x[4] = 4;
    x[5] = 5;
    x[6] = 6;
    while(run){
        printf("pc: %d ->",pc);
        switch(opt_code_list[pc].i.op){
            case I_PUSH:
            case I_ENTER:
            case I_EXIT:
            case I_LOAD_A0:
            case I_LOAD_A1:
            case I_AND1_A0:
            case I_AND1_A1:
            case I_OR1_A0:
            case I_OR1_A1:
                printf("vm error\n");exit(-1);
            break;
            case I_AND2_RA0_X_X:
                printf("RA0 = X%d && X%d\n",opt_code_list[pc].i.a0,opt_code_list[pc].i.a1);
                ra0 = x[opt_code_list[pc].i.a0] && x[opt_code_list[pc].i.a1];
            break;
            case I_AND2_RA0_RA0_X:
                printf("RA0 = RA0 && X%d\n",opt_code_list[pc].i.a1);
                ra0 = ra0 && x[opt_code_list[pc].i.a1];
            break;
            case I_AND2_RA0_RA1_X:
                printf("RA0 = RA1 && X%d\n",opt_code_list[pc].i.a1);
                ra0 = ra1 && x[opt_code_list[pc].i.a1];
            break;
            case I_AND2_RA0_RA1_RA0:
                printf("RA0 = RA1 && RA0\n");
                ra0 = ra1 && ra0;
            break;
            case I_AND2_RA0_RA0_RA1:
                printf("RA0 = RA0 && RA1\n");
                ra0 = ra0 && ra1;
            break;
            case I_AND2_RA1_X_X:
                printf("RA1 = X%d && X%d\n",opt_code_list[pc].i.a0,opt_code_list[pc].i.a1);
                ra1 = x[opt_code_list[pc].i.a0] && x[opt_code_list[pc].i.a1];
            break;
            case I_AND2_RA1_RA0_X:
                printf("RA1 = RA0 && X%d\n",opt_code_list[pc].i.a1);
                ra1 = ra0 && x[opt_code_list[pc].i.a1];
            break;
            case I_AND2_RA1_RA1_X:
                printf("RA1 = RA1 && X%d\n",opt_code_list[pc].i.a1);
                ra1 = ra1 && x[opt_code_list[pc].i.a1];
            break;
            case I_AND2_RA1_RA1_RA0:
                printf("RA1 = RA1 && RA0\n");
                ra1 = ra1 && ra0;
            break;
            case I_OR2_RA0_X_X:
                printf("RA0 = X%d || X%d\n",opt_code_list[pc].i.a0,opt_code_list[pc].i.a1);
                ra0 = x[opt_code_list[pc].i.a0] || x[opt_code_list[pc].i.a1];
            break;
            case I_OR2_RA0_RA0_X:
                printf("RA0 = RA0 || X%d\n",opt_code_list[pc].i.a1);
                ra0 = ra0 || x[opt_code_list[pc].i.a1];
            break;
            case I_OR2_RA0_RA1_X:
                printf("RA0 = RA1 || X%d\n",opt_code_list[pc].i.a1);
                ra0 = ra1 || x[opt_code_list[pc].i.a1];
            break;
            case I_OR2_RA0_RA1_RA0:
                printf("RA0 = RA1 || RA0\n");
                ra0 = ra1 || ra0;
            break;
            case I_OR2_RA0_RA0_RA1:
                printf("RA0 = RA0 || RA1\n");
                ra0 = ra0 || ra1;
            break;
            case I_OR2_RA1_X_X:
                printf("RA1 = X%d || X%d\n",opt_code_list[pc].i.a0,opt_code_list[pc].i.a1);
                ra1 = x[opt_code_list[pc].i.a0] || x[opt_code_list[pc].i.a1];
            break;
            case I_OR2_RA1_RA0_X:
                printf("RA1 = RA0 || X%d\n",opt_code_list[pc].i.a1);
                ra1 = ra0 || x[opt_code_list[pc].i.a1];
            break;
            case I_OR2_RA1_RA1_X:
                printf("RA1 = RA1 || X%d\n",opt_code_list[pc].i.a1);
                ra1 = ra1 || x[opt_code_list[pc].i.a1];
            break;
            case I_OR2_RA1_RA1_RA0:
                printf("RA1 = RA1 || RA0\n");
                ra1 = ra1 || ra0;
            break;
            case I_OR2_RA1_RA0_RA1:
                printf("RA1 = RA0 || RA1\n");
                ra1 = ra0 || ra1;
            break;
            case I_UIMP:
                printf("I_UIMP\n");
                run = 0;
            break;
            default:
            break;
        }
        pc++;
    }
    printf("RA0: %d RA1: %d\n",ra0,ra1);
    return ra0;
}

离线

楼主 #28 2023-10-21 08:41:32

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,380
积分: 1345.5

Re: 单片机有8个信号输入,想通过上位机配置这8个信号与、或操作,该如何实现?

@xiaohui

感谢。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn