Pergunta

Eu tenho uma máquina (um pouco) a tabela grande verdade / estado que eu preciso para implementar no meu código (C incorporado). Eu antecipo a especificação comportamento desta máquina de estado para a mudança no futuro, e por isso eu gostaria de manter isso facilmente modificável no futuro.

Meu tabela verdade tem 4 entradas e 4 saídas. Eu tenho tudo em uma planilha do Excel, e se eu pudesse colar isso em meu código com um pouco de formatação, que seria o ideal.

Eu estava pensando que eu gostaria de acessar minha tabela de verdade assim:

u8 newState[] = decisionTable[input1][input2][input3][input4];

E então eu poderia acessar os valores de saída com:

setOutputPin( LINE_0, newState[0] );
setOutputPin( LINE_1, newState[1] );
setOutputPin( LINE_2, newState[2] );
setOutputPin( LINE_3, newState[3] );

Mas para conseguir isso, parece que eu teria que fazer uma tabela bastante confuso assim:

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 }}}};

Os colchetes aninhados pode ser um pouco confuso? - alguém tem uma idéia melhor de como eu posso manter uma tabela bonita olhando no meu código

Obrigado!

Editar com base na resposta do HUAGHAGUAH:

Usando uma amálgama de entrada de todos (graças - Eu gostaria de poder "aceitar" 3 ou 4 destas respostas), eu acho que eu vou experimentá-lo como uma matriz bidimensional. Vou índice em minha matriz usando uma macro-deslocando pouco pequeno:

#define SM_INPUTS( in0, in1, in2, in3 ) ((in0 << 0) | (in1 << 1) | (in2 << 2) | (in3 << 3))

E isso vai deixar a minha verdade matriz da tabela semelhante a este:

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 }};

E eu posso acessar minha tabela de verdade assim:

decisionTable[ SM_INPUTS( line1, line2, line3, line4 ) ]

Vou dar que um tiro e ver como ele funciona. Eu também vou estar substituindo os 0 e 1 do com #defines mais votos que expressam o que cada um dos meios do Estado, juntamente com / ** / comentários que explicam as entradas para cada linha de saídas. Obrigado pela ajuda, todos!

Foi útil?

Solução

Não há necessidade de uma tabela multidimensional. Com um mapeamento => 4 bit de 4 bits, você pode ter um único u8 [16] entradas de mapeamento de matriz para saídas. pesquisas estaduais será muito mais barato, e você pode extrair bits individuais com alguns ops de deslocamento e máscara.

Se o algoritmo para linhas Preencher é fácil de codificar, você poderia #define uma macro para preencher cada linha pelo número de índice.

Outras dicas

Eu sugiro qualquer um (preferido se aproxima primeiro):

  • Use uma macro para intialize cada "linha" -. Isso irá esconder as chaves dentro da chamada de macro
  • Use comentários para romper as linhas.
  • Use uma função init para inicializar o contexto explicitamente - talvez usar funções para inicializar cada seção. Isto é semelhante à primeira opção acima, mas tem uma desvantagem que a função init deve ser chamado antes da máquina de estado pode ser usado.

Pessoalmente, eu lê-lo a partir de um arquivo de configuração. CSV, talvez, que é fácil de exportação para a partir do Excel. Ou você pode simplesmente copiar e colar a partir de Excel em texto simples, que lhe dá valores separados por espaços, que é igualmente fácil de importação.

Isto também significa, uma vez que você está trabalhando com C, que você não vai ter que recompilar seu código de cada vez que a tabela de decisão alterações.

Se a sua tabela de verdade é todos booleans, você poderia apenas reduzi-la a uma lista de pares, por exemplo.

1111,0000
1110,0110
...

para compressão de dados, representam os valores como bytes (dois nybbles) ...

onde / como armazená-la para codificação suave em sua configuração de sistema embarcado particular, só você pode dizer; -)

Se a tabela de verdade é realmente só 4x4x4x4, então eu usar macros. Se ele nunca vai crescer além disso, eu usaria Ragel . As chances são de que vai fazer menor mais rápido código, C do que você.

Não vejo qualquer referência ao estado atual, a fim de obter o seu estado de saída. Isso significa que ele não é uma máquina de estado, mas apenas uma tabela verdade. Existem quatro entradas, de modo que há apenas 16 combinações possíveis de entrada. Assim, uma tabela com 16 posições deve fazê-lo.

Normalmente, quando você tem um problema como este, tenta-se reduzi-la a uma fórmula booleana simples. Eu não vejo por que não seria a melhor abordagem aqui. Seria muito mais compacto e mais legível, mais ele tem o potencial para ser mais rápido (eu imagino um punhado de ANDs e ORs iria executar mais rapidamente do que a coleção de multiplica / turnos + acesso à memória necessária para a abordagem tabela de pesquisa). A maneira mais fácil de reduzir essa tabela para uma fórmula booleana é com um K-Map.

scroll top