如何在数字显示中有效计数从0000到9999?

时间:2019-05-15 16:22:21

标签: c microcontroller

我将显示从0到9的数字。我想为C语言的micro编写高效的代码。我写的是:

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 个答案:

答案 0 :(得分:4)

您可以嵌套数字重置或递增

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我发现您希望将代码保留在微控制器上的依赖性最小。

如果您愿意将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) ...
    }
}

下一个要问的问题是,如何才能最小化更新分段显示以增加增量!

答案 4 :(得分:0)

模拟数学加法就足够了,从最低位到最高位进行检查。

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

答案 5 :(得分:-1)

在这里,我使用了方法backtracking,即遍历树的所有分支,并在缓冲区a在某片叶子上时将其打印出来。

可以随时更改参数Nbase的值。

树的最大深度为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;
}