Cum pot crea o tabelă de căutare într-un microcontroler folosind C? Am o intrare și o ieșire și vreau să implementez un tabel de căutare în C.
Răspuns
Voi da un general răspuns deoarece întrebarea nu are informații:
Să presupunem că aveți un uint8_t
ca intrare și un uint8_t
ca ieșire și doriți să creați un tabel complet de căutare (adică fiecare intrare are o ieșire). Ați avea nevoie de 256 de valori, deoarece intrarea poate avea 256 de valori diferite. Acum puteți crea un tabel cu:
const uint8_t the_table[256] = { ... }
Cuvântul cheie const
este de a stoca tabelul în memoria flash , nu în RAM. Acest lucru se datorează faptului că memoria RAM este redusă în microcontrolere, așa cum subliniază prezie în comentarii.
În parantezele buclate, valorile ar trebui să meargă. Acum puteți căuta cu ușurință o valoare de intrare cu the_table[input_value]
.
În general, am putea spune că un tabel de căutare ar arăta după cum urmează:
const OutputType the_table[CountOfInputValues] = { ... };
Un mic exemplu pentru un tabel de căutare pentru a face această conversie (din cod gri , mulțumită lui Anindo Ghosh ):
input -> output 0b000 0b000 0b001 0b001 0b010 0b011 0b011 0b010 0b100 0b110 0b101 0b111 0b110 0b101 0b111 0b100
Poate fi implementat după cum urmează, utilizând uint8_t
sau un octet, ca tip de ieșire:
const uint8_t gray_code[8] = {0b000, 0b001, 0b011, 0b010, 0b110, 0b111, 0b101, 0b100};
Puteți căuta o valoare cu:
some_var = gray_code[input];
Comentarii
Răspuns
Iată un exemplu despre cum aș crea un tabel de căutare pentru unele valori precomputate. Voi folosi un exemplu de schimb de biți față-înapoi în cadrul unui octet. este uneori util pentru algoritmii FFT sau perifericele SPI care doresc o ordine greșită.
Mai întâi creez un program care creează tabelul. Menținerea tabelului cu mâna este obositoare și predispusă la erori, deci această sarcină ar trebui să fie dată la computer.
#!/usr/bin/python def swapbits(x): ret=0 for i in range(8): if x&(1<<i): ret |= 1<<(7-i) return ret print "const uint8_t bitswap[] = {", print ", ".join("0x%02x"%swapbits(x) for x in range(256)), print "}"
Numesc acest fișier „bitend.py”. Observați că am folosit un limbaj de scriptare în loc de un program C pentru aceasta. Generarea tabelului este fundamental o problemă de procesare a șirurilor, iar C este o problemă de prelucrare a șirurilor. Deoarece tabelul este necesar doar în timpul compilării, pot folosi un algoritm simplu ca peșterilor care este mai evident corect decât unul optimizat.
Acum, pentru a integra acest lucru în compilare. În Makefile, am pus o secțiune de genul acesta:
generated_swapbits.c: bitend.py echo "/* generated by bitend.py, do not edit */" > generated_swapbits.c python bitend.py >> generated_swapbits.c
Aici am făcut o dependență de scriptul Python, astfel încât, dacă editez scriptul, C fișierul va fi regenerat automat.
În codul meu principal C, includ doar fișierul generat:
#include <stdio.h> #include "generated_swapbits.c" int main(void) { printf("Swapped 0x0f is %0x\n", swapbits[0x0f]); }
Acum în Makefile, Trebuie să includ fișierul generat ca o dependență a codului C:
a.out: main.c generated_swapbits.c $(CC) $(CFLAGS) main.c
Și ultimul lucru este să adăugăm „generated_swapbits.c” la Makefile ” s țintă „curată”, astfel încât fișierul va fi eliminat după „make clean”.
Dacă utilizați un IDE în loc de make, va trebui să consultați documentația despre rularea scripturilor pentru a satisface dependențele. (Dacă IDE nu acceptă acest lucru, alegeți un IDE diferit.)
uint32_t gray( uint32_t number ) { return number ^= ( number >> 1 ); }
Nu ' nu aveți nevoie de un tabel pentru asta.EOR Rn,Rn,Rn,LSR 1
, în niciun caz un tabel de căutare nu poate învinge acest lucru.