C,为什么我的'px'变量为零?

时间:2016-03-09 21:32:00

标签: c arduino avr

好的,这个bug很奇怪,我不知道发生了什么。 我在at90usb1286上运行我的代码。

这是有问题的代码:

        uint16_t r = rand();
        t1 = r;

        px = r%52;
        t2 = px;

        py = r%28;
        t3 = py;

        px = px * 6;
        t4 = px;

        py = py * 8;
        t5 = py;

        py += 8;

上下文

t#变量是我用来调试这个的临时变量... 它们显示在连接的显示器上。 px和py只是全局uint16_ts。

错误:

除了t4之外的所有t#变量都显示合理的值,但无论t2显示什么值,t4都保持为0。

为什么!!!?

几个小时以来,我一直在想着! :'(

感谢您的任何建议! :) 我知道这可能不是一个使用随机的好方法:P

(我标记了arduino,因为我怀疑它可能类似)

其余代码: (我已尝试过非静态的全球变量)

#include "util/cli.h"
#include "drivers/lcd/syscalls.h"
#include "drivers/input/syscalls.h"
#include "drivers/led/syscalls.h"
#include "drivers/scheduler/syscalls.h"
#include <util/delay.h>

static int x = 0, y = 0;

static int px;
static int py; /*Pickup*/

static uint16_t score = 0;

static uint8_t dir; /*0 -> NESW <- 3*/

static uint16_t t1, t2, t3, t4, t5;

void render_thread() {
    lcd_clear_screen();

    while(1) {
        cli();
        lcd_display_char_xy(' ', x, y);
        if(dir & 0x01)
            y -= 8;

        if(dir & 0x02)
            x += 6;

        if(dir & 0x04)
            y += 8;

        if(dir & 0x08)
            x -= 6;

        if(x < 0)
            x = 0;
        if(y < 8)
            y = 8;
        if(x > 312)
            x = 312;
        if(y > 232)
            y = 232;

        lcd_display_char_xy('.', px, py);
        lcd_display_char_xy('@', x, y);
        /*Display score*/
        lcd_display_move(0, 0);
        lcd_display_hex(&score, 2);

        /*Display test variables*/
        lcd_display_move(60, 0);
        lcd_display_hex(&t1, 2);
        lcd_display_move(100, 0);
        lcd_display_hex(&t2, 2);
        lcd_display_move(140, 0);
        lcd_display_hex(&t3, 2);
        lcd_display_move(180, 0);
        lcd_display_hex(&t4, 2);
        lcd_display_move(220, 0);
        lcd_display_hex(&t5, 2);
        sei();
        _delay_ms(16);
    }
}

void game_thread() {
    px = 24;
    py = 32;

    while(1) {
        cli();
        if(px == x && py == y) {
            uint16_t r = rand();
            t1 = r;

            px = r%52;
            t2 = px;

            py = r%28;
            t3 = py;

            px = px * 6;
            t4 = px;

            py = py * 8;
            t5 = py;

            py += 8;
            score++;
        }
        sei();
        scheduler_switch();
    }
}

void user_thread() {
    while(1) {
        if(switch_north())
            dir |= 1;
        else
            dir &= 0x0E;

        if(switch_east())
            dir |= 1<<1;
        else
            dir &= 0x0D;

        if(switch_south())
            dir |= 1<<2;
        else
            dir &= 0x0B;

        if(switch_west())
            dir |= 1<<3;
        else
            dir &= 0x07;

        scheduler_switch();
    }
}

void cli_start() {
    Task* game_task = scheduler_create_task(game_thread, 128);
    scheduler_submit_task(game_task);

    Task* render_task = scheduler_create_task(render_thread, 128);
    scheduler_submit_task(render_task);

    Task* user_task = scheduler_create_task(user_thread, 128);
    scheduler_submit_task(user_task);
}

3 个答案:

答案 0 :(得分:2)

rand()的初始值可能会被52分(按照Lashane的建议)。首先尝试确保在使用时调用srand() - 但确保您确切地调用它并且仅调用ONCE。对于简单的应用程序,您可以使用time()值来播种srand,但是对于更安全的应用程序,您应该找到一些不容易被猜到的种子。

你总是有可能将值除以52的风险,所以如果零是不合需要的值,请使用

px = (r%51)+1;

确保返回的值介于1到51之间

答案 1 :(得分:0)

你正在创建3个线程,但你并不关心写内存冲突。

两个线程正在使用px: game_thread render_thread ,也许 lcd_display_char_xy 在render_thread中引用了px,并在不需要的时间内修改它。

我建议您尝试使用“ int pxg ”专用于game_thread和其他“ int pxr ”,以便在render_thread中使用(并删除int px)。它必须解决问题。

或者,只是为了测试,你可以评论 lcd_display_char_xy('。',px,py); ,而game_thread中的px必须以预期的方式工作。

答案 2 :(得分:0)

好吧,这似乎是一个优化问题。我最初使用的是优化标志 -Os ,在将其更改为 -O3 -Ofast 后,它似乎完美运行:)

我不知道大小优化的代码究竟发生了什么,但似乎编译器已将game_thread代码拆分成几个混乱的部分......

感谢大家的帮助! :d