Как эффективно считать от 0000 до 9999 на цифровом дисплее? - PullRequest
2 голосов
/ 15 мая 2019

Я не отображаю это число от 0 до 9. Я хотел бы сделать эффективный код для микро на языке Си. Я написал следующее:

dis_value[0]++;
if (dis_value[0] > 9) {
    dis_value[0] = 0;
    dis_value[1]++;
}
if (dis_value[1] > 9) {
    dis_value[0] = 0;
    dis_value[1] = 0;
    dis_value[2]++;
}
if (dis_value[2] > 9) {
    dis_value[0] = 0;
    dis_value[1] = 0;
    dis_value[2] = 0;
    dis_value[3]++;
}
if (dis_value[3] > 9) {
    dis_value[0] = 0;
    dis_value[1] = 0;
    dis_value[2] = 0;
    dis_value[3] = 0;
}

Где от 0 до 3 - номер модуля дисплея.

Это лучший способ?

Или, может быть, лучше один 16-битный счетчик, который разделен на 4 части?

Ответы [ 6 ]

4 голосов
/ 15 мая 2019

Вы можете вкладывать сброс или приращение цифры

dis_value[0]++;
if (dis_value[0] > 9) {
     dis_value[0] = 0;
     dis_value[1]++;

     if (dis_value[1] > 9) {
          dis_value[1] = 0;
          dis_value[2]++;

            if (dis_value[2] > 9) {
                dis_value[2] = 0;
                dis_value[3]++;

                if (dis_value[3] > 9) {
                    dis_value[3] = 0;
                }
           }
      }
  }

Делая выше, вы не выполняете все ненужные if s.

3 голосов
/ 15 мая 2019
char *inc(char *buff, unsigned *i)
{
    unsigned tmp = ++(*i);
    buff[0] = tmp % 10;
    tmp /= 10;
    buff[1] = tmp % 10;
    tmp /= 10;
    buff[2] = tmp % 10;
    tmp /= 10;
    buff[3] = tmp % 10;
    return buff;
}
0 голосов
/ 16 мая 2019

симуляция математического сложения будет достаточной, проверяя от самой младшей цифры к самой высокой.

#include <stdio.h>

void incr(int dis_value[], int n) {
    ++dis_value[0];
    for (int i=0; i+1<n; ++i) {
        if (dis_value[i] < 10) break;
        dis_value[i+1] += dis_value[i] / 10;
        dis_value[i] %= 10;
    }
    dis_value[n-1] %= 10;
}

void echo(int dis_value[], int n) {
    for (int i=n-1; i>=0; --i) printf("%d", dis_value[i]);
    printf("\n");
}

int main() {
    int dis_value[] = {0, 0, 0, 0};
    for (int i=0; i<10000; ++i) {
        incr(dis_value, 4);
        echo(dis_value, 4);
    }
    return 0;
}
0 голосов
/ 15 мая 2019

Я заметил, что вы хотите сохранить код с минимальной зависимостью от микроконтроллера.

Если вы хотите обрабатывать буфер dis_value как целое число с одним байтом на цифру, скажем, little-endian, что можетбудет храниться в регистре, который также должен быть быстрее, тогда вы можете объединить последовательность:

if (dis_value[N] > 9) {
  dis_value[N] = 0;
  dis_value[N+1]++;

Это становится (с вложением @kiran)

if ((dis_value&(0xf<<(N*8)))==(10<<(N*8)))
{
    dis_value+=(0x100-10)<<(N*8);
    if ...
}

Где я нахожусьПредполагая, что компилятор разрешит константные выражения.Также было бы хорошо отменить добавление и if для улучшения оценки условного конвейера, если у вашего контроллера есть конвейер, но это означает написание кода на ассемблере.

Следующий псевдокод должен дать идею.Следующее условие оценивается с использованием значения перед сложением, поэтому две операции могут выполняться параллельно.Если вы фактически кодировали это в схему, это очевидная оптимизация:

bool do0 = ((dis_value&(0xf<<(0*8)))==(9<<(0*8)))
dis_value++;
if (do0)
{
    bool do1 = ((dis_value&(0xf<<(1*8)))==(9<<(1*8)));
    dis_value += (0x100-10)<<(0*8);
    if (do1)
    {
        do2 = ((dis_value&(0xf<<(2*8)))==(9<<(2*8)));
        dis_value += (0x100-10)<<(1*8);
        if (do2) ...
    }
}

Следующий вопрос, который нужно задать, - как можно минимально обновить сегментированный дисплей для приращения!

0 голосов
/ 15 мая 2019
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void delay(int number_of_seconds)
{
    int milli_seconds = 1000 * number_of_seconds;
    clock_t start_time = clock();
    while (clock() < start_time + milli_seconds);
}

int main(int argc, const char *argv[])
{

    int arr[4] = {0};
    for(int i=0; i < 4; i++)
    {
        for(int j = 0; j<9; j++)
        {
            arr[i]++;
            delay(1000);
            printf("%i%i%i%i\n",arr[3], arr[2], arr[1], arr[0]);
        }
    }

    printf("\n");
    return 0;
}
0 голосов
/ 15 мая 2019

Здесь я использовал метод backtracking, т. Е. Обход всех ветвей дерева и печать буфера a, когда он находится на каком-то листе.

Не стесняйтесь изменять значения параметра N и base.

Дерево имеет максимальную глубину N.Каждый узел, кроме листьев, имеет ровно base ветвей.

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


int main(void)
{
  char a[100];
  int i;
  int N=4;
  int base_1='9', zero_1='0'-1;

  memset(a, 0, 100);
  memset(a, zero_1, N);

  i=0;
  while(i>=0)
  {
    if (++a[i]<=base_1)
      if (i==N-1) printf("%s\n", a);
      else i++;
    else
      a[i--]=zero_1;
  }

  return 0;
}
...