sprintf正在输出一些奇怪的数据

时间:2012-09-29 06:21:01

标签: c embedded printf microchip c18

我正在开发一个嵌入式项目,涉及将结构读/写到EEPROM中。我正在使用sprintf来显示一些调试信息。

由于某些原因,此代码存在两个问题。首先; sprintf正在打印一个非常奇怪的输出。当我打印'addr ++'时,它将遵循'0,1,2,3,4,32 ......'模式,这是没有意义的。

void ee_read(char * buf, unsigned int addr, unsigned int len) {
    unsigned int i;

    sprintf(bf1, "Starting EEPROM read of %u bytes.\r\n", len); // Debug output
    debugr(bf1);

    IdleI2C1();
    StartI2C1();
    WriteI2C1(EE_ADDR | EE_W);
    IdleI2C1();
    WriteI2C1((unsigned char)addr>>8); // Address to start reading data from
    IdleI2C1();
    WriteI2C1((unsigned char)addr&0xFF);
    IdleI2C1();
    RestartI2C1();
    WriteI2C1(EE_ADDR | EE_R);
    IdleI2C1();
    for (i=0; i<len; i++) {
        buf[i] = ReadI2C1(); // Read a byte from EEPROM

        sprintf(bf1, "Addr: %u Byte: %c\r\n", addr, buf[i]); // Display the read byte and the address
        debugr(bf1);

        addr++; // Increment address

        IdleI2C1();
        if (i == len-1) { // This makes sure the last byte gets 'nAcked'
            NotAckI2C1();
        } else {
            AckI2C1();
        }
    }
    StopI2C1();
}

上面的输出在这里:https://gist.github.com/3803316请注意,约有输出是用%x作为地址值(所以addr是十六进制)

你可能已经注意到输出的第二个问题是,当我&gt;时它不会停止。 LEN。它比我提供的输出继续进行,并且在微控制器的看门狗重新启动之前不会停止。

修改 调用函数

Location loc;
ee_read(&loc, 0, sizeof(Location));

声明:

struct location_struct {
    char lat[12]; // ddmm.mmmmmm
    char latd[2]; // n/s
    char lon[13]; // dddmm.mmmmmm
    char lond[2]; // e/w
    char utc[11]; // hhmmss.sss
    char fix[2]; // a/v
};

typedef struct location_struct Location;

char bf1[BUFFER_SIZE];

我认为这不是竞争条件。我禁用使用bf1的中断。即使这样,如果发生这种情况,它也会破坏整个调试字符串,而且肯定不会那么可重复。

修改 addr的值从零开始,可以在这里看到:https://gist.github.com/3803411

修改 应该怎样做才能将位置结构逐字节复制到EEPROM中,然后在需要时调用它。

封闭 所以我从未解决过这个问题。该项目远离EEPROM,我已经改变了OS,编译器和IDE。我不太可能复制这个问题。

1 个答案:

答案 0 :(得分:0)

我告诉你一个错误的代码,这一行:

(unsigned char)addr>>8

没有做你认为需要的事情。

它将addr中的值转换为unsigned char(假设为8位char和16位int或仅使用低16位更宽int),总是会给你低8位。

如果你然后将它向右移8位,那么你总是会以零结束。

如果您的目的是获取地址的高八位,则需要使用:

(unsigned char)(addr>>8)

以便首先完成