c - 读取数组并使用 C 中的查找表显示结果

标签 c

到目前为止,我有这段代码,我被告知我正在读取端口上的开关,而不是像我应该的那样读取数组(扫描仪)。

最初的问题是这样的:original problem

代码:

#include <stdio.h>
int main(void) {
    /******************* Declare the port addresses **********************/
    unsigned char *DDRA  = (unsigned char *)0x0002;
    unsigned char *PORTB = (unsigned char *)0x0001;
    unsigned char *DDRB  = (unsigned char *)0x0003;
    unsigned char *PTH   = (unsigned char *)0x0260;
    unsigned char *DDRH  = (unsigned char *)0x0262;
    unsigned char *PERH  = (unsigned char *)0x0264;

    /******************* Declare functions*******************************/
    unsigned char threshold;
    unsigned char read;
    unsigned char index;
    /************************** Scanner Data ******************************/

    unsigned char scanner[255] =  { 50,
                                     4,   9,  14,  18,  23,  26,  29,  30,  31,  32,
                                    34,  37,  41,  47,  54,  63,  71,  80,  87,  92,
                                    94,  94,  92,  89,  85,  83,  83,  86,  93, 102,
                                   115, 128, 141, 153, 161, 164, 164, 160, 152, 144,
                                   137, 132, 132, 136, 146, 161, 178, 196, 213, 226
                                  };

    /******************* Set up I/O ports ********************************/
    *DDRH = 0x00;                   /* make Port H an input port */
    *PERH = 0xFF;                   /* enable Port H */
    *DDRA = 0xFF;                   /* make Port A an output port */
    *DDRB = 0xFF;                   /* make Port B an output port */

    /******************* Main loop ***************************************/

    *PORTB = 255; // This clears the display on PORTB //
    threshold = *PTH; // Make PORTH equal to threshold //
    read = scanner[0];
    index = 1;

    do {
        *PORTB = pattern(scanner[index]/32);
        wait (1);
    } while ((index<=scanner[0]) && (read<threshold));

    if (index < threshold) {
        printf("threshold reached at reading %d with a current value %d.", index, scanner[index]);
    } else {
        printf("Threshold not reached after %d readings.", scanner[255]);
    }
    return 0 ;
}
/******************* Pattern Function **********************************/

void pattern(char threshold) {
    unsigned char LedTable [8] = {0b00000001,
                                  0b00000011,
                                  0b00000111,
                                  0b00001111,
                                  0b00011111,
                                  0b00111111,
                                  0b01111111,
                                  0b11111111
                                 };
    unsigned char index;
    unsigned char display;
    unsigned char sw_on;
    unsigned char sw_off;

    index = threshold;
    sw_on = ((unsigned char)LedTable[index]);
    sw_off = threshold & 0b11111111;

    if (sw_off & 0b00010000) {
        display = sw_on | 0b10000000 ;
    } else {
        display = sw_on & 0b01111111;
    }
}

/********************** Wait Function **********************************/

void wait(int seconds) {
    unsigned int i;
    unsigned int j;
    unsigned int k;

    for (k = 0; k <= seconds; k++) {
        for (i = 0; i <= 50; i++) {
            for (j = 0; j <= 2000; j++);
        }
    }
}

任何帮助将不胜感激。我正在尝试在模拟器上运行它,但没有正确的软件将代码转换为 s19 文件以正确运行它,我无法下载它,因为我目前正在下周工作。不过我已经使用 QT 清除了所有错误。

最佳答案

虽然问题不太清楚,但我想我已经明白了......

注释:

  • 我假设scanner包含虚拟数据并用于模拟设备。
  • 我使用的是 VStudio 10(在 64 位 Win10 上),因此代码中的某些内容将无法工作:

    • 二进制格式的数字(例如0b00000001),因此我必须将它们转换为(十六进制)。
    • 一些赋值(例如 unsigned char *DDRA = (unsigned char *)0x0002; 试图取消引用第二个内存字节,这是不允许的)。
  • 但是,我也发现了一些编译器不喜欢的问题:

    1. 作业:*PORTB = pattern(scanner[index]/32); ,而pattern不返回任何内容:void pattern(char threshold) .
    2. 引用文献patternwait来自main ,当它们尚未声明时。

所以,我有两个问题:

  • 代码是否可以编译?
  • 您使用什么编译器?

正如我所说,我必须修改代码才能在我的环境中进行编译(尤其是二进制数问题),我不会发布可以实现这一目的的整个代码片段,而是指示现有代码的哪些部分代码(在问题代码片段中,因此您必须使用问题中的内容更新计算机/设备上的代码)以替换为内容。

  • 对于问题1.(我上面提到的):函数应该返回 unsigned char :

    • 函数定义:void pattern(char threshold)应更改为unsigned char pattern(char threshold) .
    • 你必须从中返回一些东西(我假设它是 display ),所以添加 return display;在函数右大括号( } )之前。
  • 对于问题2.,可以:

    • 前向声明(添加下面两行代码)waitpattern 之前 main的声明 ( int main(void) { ):

      void wait(int seconds);
      unsigned char pattern(char threshold);

    • 移动waitpattern main 之前的函数体.

  • 我在编辑问题时修复的第三个(小问题,我想是拼写错误)问题是第四个 LedTable元素缺少 0b标记在开头。

现在,逻辑问题(以及其他一些问题)依赖于 do/while循环(正如你所说 - 或者更好:正如你所说)。因此,我建议替换该循环:

do {
    *PORTB = pattern(scanner[index]/32);
    wait (1);
} while ((index<=scanner[0]) && (read<threshold));

作者:

while (((index <= read) && (scanner[index] < threshold))) {
    *PORTB = pattern(scanner[index] / 32);
    //printf("pattern(scanner[%d]/32): %02X - %d\n", index, pattern(scanner[index] / 32), scanner[index]);
    wait(1);
    index++;
};

说明:

  • 通过更改 do/while进入while循环,我避免了可能出现的涉及数组中第一个或最后一个元素的一些极端情况。
  • index++; - 这就是 @DavidC.Rankin 发现的错误:如果你不增加 index它将具有相同的值(在进入循环之前分配给它的值),并且循环永远不会结束。
  • 循环条件(我将在原始代码中从右到左遍历它们):
    • 比较thresholdread或者数组索引没有意义。
    • 比较indexread而不是scanner[0] - 这是可选的这两个具有相同的值,我选择这种形式是因为它更有效。

最后的更改是:替换 if (index < threshold) {通过if (index < read) {因为将数组索引(退出 while 循环后)与值(可能位于该数组中)进行比较是没有意义的 - 与上面相同。

关于c - 读取数组并使用 C 中的查找表显示结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41171863/

相关文章:

c - 路径:在 `#include` 中是否有效?

c - linux kernel/sched.c - find_process_by_pid - 如何从 C 应用程序代码中使用它

c - 如何退出子进程 - _exit() 与 exit

c - 是否有动态检查实用程序可以标记结构中静态缓冲区的溢出?

c - FLT_MAX 宏在哪里定义?

c - 带有双向链表的歌名数据库

c - 某些 C 和 Unix 函数之间的关系是什么

C 不为函数创建堆栈帧

计算 C 中一个整数占用多少位

c - 了解 C 中的线程