有一个奇怪的问题。我终于想出了如何将一个在循环内递增的变量“i”转换为一个字符串,我可以将它传递给一个函数,该函数将它转换为一个输出到显示器的字符。
问题是,值增加了 2 而不是 1!我尝试了一些不同的方法,但我不确定问题出在哪里。
最初,我想也许,如果你有一个调用另一个函数的函数,并且它们都使用相同的变量来递增(即 for(int i=0; i<10; ++i)),那么“外部”函数将使“i”增加 2,因为它在“外部”循环中增加一次,在“内部”循环中增加一次。但是,我认为情况并非如此。如果是这样,在我的情况下,“i”会增加两个以上,我尝试将所有计数器变量更改为不同的名称,而没有任何变化。无论如何,这将是一种愚蠢的语言工作方式。除非当然是这样,否则我很想开悟。
这是给我带来麻烦的代码块:
for (int i=0; i<100; i++){
char c[1]={0}; // Create variable to hold character
sprintf(c,"%d", i); // Copy value of "i" as string to variable
writeText(c,0,0,WHITE,BLACK,3); // Write the character "c" at position 0,0. Size 3
OLED_buffer(); // Send display buffer
delay_ms(500); // Delay before next increment
}
这是 writeText():
void writeText(unsigned char *string, int16_t x, int16_t y, uint16_t color, uint16_t bgcolor, uint8_t size){
unsigned char letter;
for (int i=0; i<strlen(string); ++i){
letter = string[i];
if (letter != NULL){
drawChar(x+(i*6*size),y,letter,color,bgcolor,size);
}
}
}
这是由 writeText 调用的 drawChar:
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size) {
if((x >= _width) || // Clip right
(y >= _height) || // Clip bottom
((x + 5 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0)) // Clip top
return;
for (int8_t i=0; i<6; i++ ) {
uint8_t line;
if (i == 5)
line = 0x0;
else
line = font[(c*5)+i];
for (int8_t j = 0; j<8; j++) {
if (line & 0x1) {
if (size == 1) // default size
drawPixel(x+i, y+j, color);
else { // big size
fillRect(x+(i*size), y+(j*size), size, size, color);
}
} else if (bg != color) {
if (size == 1) // default size
drawPixel(x+i, y+j, bg);
else { // big size
fillRect(x+i*size, y+j*size, size, size, bg);
}
}
line >>= 1;
}
}
}
最后是 drawPixel,由 drawChar 调用(尽管我真诚地怀疑问题是否如此之深):
void drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
break;
case 3:
swap(x, y);
y = HEIGHT - y - 1;
break;
}
// x is which column
if (color == WHITE)
buffer[x+(y/8)*SSD1306_LCDWIDTH] |= _BV((y%8));
else
buffer[x+(y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8));
}
所有这一切的结果是,显示器显示的数字增加了我的延迟长度的两倍。例如这里的延迟是 500 毫秒,所以它每 1 秒更新一次。而不是去
1、2、3、4、5...
正如它应该的那样
1、3、5、7、9……
有没有人可以提供任何建议?我确信在我的初始循环中这是一个愚蠢的简单问题,但我现在看不到它。
我正在使用 Atmel Studio 6 对 xmega32a4u 进行编程。显示的库函数是我移植到 Atmel Studio 的 SSD1306 128x32 OLED 的 Adafruit 图形库的一部分。
非常感谢你的帮忙!
更新:虽然我的代码确实存在一些问题,但真正的问题实际上在于 OLED 的处理方式。显然 Adafruit 忘记在他们的库中为显示设置正确的页面地址。由于显示器上的控制器可以支持 128x64 和 128x32 显示器,因此必须正确设置显示器的“结束”地址,以便控制器知道要访问显示 RAM 的哪些部分。那个功能不见了。由于显示器如何写入数据内存,并且因为它不“知道”显示器只有 32 像素高,所以发送到显示器的每隔一帧实际上都被写入了显示器内存的“底部”部分(即如果显示器是 128x64,高两倍时会出现的部分)。所以现在一切都很好!
非常感谢 unwind,如果不是因为他关于显示时间的建议让我想到了问题的另一面,我可能需要很长时间才能找出问题所在。