我有一个(有点)大型真值表/状态机,需要在我的代码(嵌入式C)中实现。我预计该状态机的行为规范会在将来发生变化,因此我希望将来可以轻松对其进行修改。
我的真值表有4个输入和4个输出。我将所有内容保存在Excel电子表格中,如果我可以将其粘贴到代码中并进行一些格式化,那将是理想的选择。
我当时想我想像这样访问我的真值表:
u8 newState[] = decisionTable[input1][input2][input3][input4];
然后,我可以使用以下命令访问输出值:
setOutputPin( LINE_0, newState[0] );
setOutputPin( LINE_1, newState[1] );
setOutputPin( LINE_2, newState[2] );
setOutputPin( LINE_3, newState[3] );
但是为了得到它,看来我必须要做一个相当困惑的表,如下所示:
static u8 decisionTable[][][][][] =
{{{{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }},
{{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }}},
{{{ 0, 0, 1, 1 },
{ 0, 1, 1, 1 }},
{{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }}}},
{{{{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }},
{{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }}},
{{{ 0, 1, 1, 1 },
{ 0, 1, 1, 1 }},
{{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }}}};
这些嵌套的括号可能有些令人困惑-是否有人对我如何在代码中保留漂亮的表有更好的主意?
谢谢!
根据HUAGHAGUAH的答案进行编辑:
使用每个人的输入的合并(谢谢-我希望我可以“接受”其中的3个或4个答案),我想我将以二维数组的形式尝试它。我将使用一个小的位移宏将其索引到数组中:
#define SM_INPUTS( in0, in1, in2, in3 ) ((in0 << 0) | (in1 << 1) | (in2 << 2) | (in3 << 3))
这将使我的真值表数组如下所示:
static u8 decisionTable[][] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }};
然后,我可以像下面这样访问我的真值表:
decisionTable[ SM_INPUTS( line1, line2, line3, line4 ) ]
我会试一试,看看效果如何。我还将用更有用的#define(表示每个状态的含义)以及/**/注释(解释输出的每一行的输入)来替换0和1。谢谢大家的帮助!
最佳答案
不需要多维表。通过4位=> 4位映射,您可以将单个u8 [16]阵列映射输入映射到输出。状态查找会便宜得多,并且您可以通过一些移位和屏蔽操作来提取单个位。
如果用于填充行的算法易于编码,则可以#define宏以按索引号填充每一行。