Char 数组的问题,如何正确构造和显示它们
Trouble with Char arrays, how to properly construct and display them
对于我正在共同设计的产品,我想在 LCD 屏幕上显示位图图标。受其他 this 教程的启发,我创建了一个单独的 C 文件,其中包含我要显示的图标的字节数组。
当我尝试直接显示图标时,它似乎起作用了。但是当我尝试间接地做它时——这最终将是必要的——它失败了。
真正让我感到困惑和我想了解的是;当我将垃圾图标 (CHAR ARRAY) 的数组打印到串行监视器并将其与字节数组进行比较时,它应该表示它们正确匹配。
但是当我对正确显示的图像(ICON ARRAY)执行相同操作时,我打印到串行监视器的内容与它显示的字节数组不匹配,我打印的信息甚至不一致......这怎么可能?!
我已经为此苦思了一个星期了,如果能提供任何帮助,我们将不胜感激。
主文件:
// --------------------------------------------------------------------------------------
// | This program is made for an arduino mega 2560 used in conjunction with the |
// | (chinese) OPEN-SMART 3.2 inch TFT LCD Shield ILI9327 |
// | This version of the program is a slimmed down one to clearly convey the problem |
// | I am currenlty having drawing pictures on this setup |
// --------------------------------------------------------------------------------------
// This program is based on the library obtained from
// https://drive.google.com/open?id=0B6uNNXJ2z4CxYktCQlViUkI1Sms
// There is also a demo available on YouTube
// https://www.youtube.com/watch?v=JQHGYnKeC0M&t=2s
#include <Adafruit_GFX.h> // Core graphics library
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
// -------------------------------------------------------------------------------------
// | Variable declaration |
// -------------------------------------------------------------------------------------
// Set colors
#define BLACK 0x0000
#define BACKGROUND 0x07FF
// No idea with this does tbh
uint16_t g_identifier;
// Spacing variables
uint8_t cube_size = 75;
uint8_t padding = 3;
uint8_t ix1 = 5+2 * padding;
uint8_t ix2 = 5+3 * padding + cube_size;
uint8_t ix3 = 5+4 * padding + 2 * cube_size;
uint8_t ix4 = 5+5 * padding + 3 * cube_size;
uint16_t ix5 = 5+(6 * padding) + 4 * cube_size;
uint8_t iy1 = 5+1 * padding;
uint8_t iy2 = 5+3 * padding + cube_size;
uint8_t iy3 = 5+4 * padding + 2 * cube_size;
//Progmem Icon init
extern uint8_t icon_from_progmem[];
// -------------------------------------------------------------------------------------
// | Functions |
// -------------------------------------------------------------------------------------
// Standard drawbitmap function
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color) {
int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
uint8_t byte = 0;
for (int16_t j = 0; j < h; j++, y++) {
for (int16_t i = 0; i < w; i++) {
if (i & 7) byte <<= 1;
else byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]);
if (byte & 0x80) tft.drawPixel(x + i, y, color);
}
}
}
// -------------------------------------------------------------------------------------
// | Setup |
// -------------------------------------------------------------------------------------
// I just copied this part to get the screen to work
void setup(void) {
Serial.begin(9600);
Serial.println(F("TFT LCD test"));
// tft.reset(); //we can't read ID on 9341 until begin()
g_identifier = tft.readID(); //
Serial.print("ID = 0x");
Serial.println(g_identifier, HEX);
if (g_identifier == 0x00D3 || g_identifier == 0xD3D3) g_identifier = 0x9481; // write-only shield
if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial
// g_identifier = 0x9329; // force ID
tft.begin(g_identifier); //to enable ILI9327 driver code
tft.setRotation(3); //Change orientation (landscape and portrait)
}
// -----------------------------------------------------------------------------------
// | Loop |
// -----------------------------------------------------------------------------------
void loop(void) {
tft.fillScreen(BACKGROUND); //
unsigned char myCharArray[512];
byte myChar;
for (int k = 0; k < 512; k++) {
// Create myCharArray from icon_from_progmem
myChar = pgm_read_byte(icon_from_progmem + k);
myCharArray[k] = char(myChar);
// Print data from myCharArry to the serial monitor
Serial.print("CHAR ARRAY: ");
Serial.print(k);
Serial.print(" ");
Serial.println(myChar);
}
// Visual separtion string
Serial.println("------------------------------------------------------------------");
// Print data from icon_from_progmem to serial monitor
for (int k=0; k<512; k++){
Serial.print("ICONS ARRAY: ");
Serial.print(k);
Serial.print(" ");
Serial.println(icon_from_progmem[k]);
}
// Draw the two icons on the screen
drawBitmap(ix2, iy1, myCharArray, 64, 64, BLACK);
drawBitmap(ix4, iy1, icon_from_progmem, 64, 64, BLACK);
delay(600000);
} // end of void loop
位图的单独文件:
#include <avr/pgmspace.h>
// 'PlafLamp', 64x64px
const unsigned char icon_from_progmem [] PROGMEM = {
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xc0, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x7f, 0x00, 0x00,
0x00, 0x01, 0xfc, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00,
0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00,
0x00, 0x0f, 0x80, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
0x00, 0x00, 0x07, 0xc0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xe0, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x80, 0x3f, 0x00, 0x00,
0x00, 0x01, 0xf8, 0x03, 0xc0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x03, 0xc0, 0x0f, 0xc0, 0x00,
0x00, 0x07, 0xe0, 0x03, 0xc0, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x00,
0x00, 0x07, 0x80, 0x03, 0xc0, 0x01, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x03, 0xc0, 0x00, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00
};
What is displayed on the screen
左图为CHAR ARRAY,右图为ICON ARRAY。
在 drawBitmap() 中,您正在通过 pgm_read_byte()
遍历字节
在 avr-libc 文档中说
Read a byte from the program space with a 16-bit (near) address.
Note:
The address is a byte address. The address is in the program space.
作为位图副本的数组 "myCharArray" 不在程序 space 中,因此 pgm_read_byte() 无法正常运行。
对于我正在共同设计的产品,我想在 LCD 屏幕上显示位图图标。受其他 this 教程的启发,我创建了一个单独的 C 文件,其中包含我要显示的图标的字节数组。
当我尝试直接显示图标时,它似乎起作用了。但是当我尝试间接地做它时——这最终将是必要的——它失败了。
真正让我感到困惑和我想了解的是;当我将垃圾图标 (CHAR ARRAY) 的数组打印到串行监视器并将其与字节数组进行比较时,它应该表示它们正确匹配。 但是当我对正确显示的图像(ICON ARRAY)执行相同操作时,我打印到串行监视器的内容与它显示的字节数组不匹配,我打印的信息甚至不一致......这怎么可能?!
我已经为此苦思了一个星期了,如果能提供任何帮助,我们将不胜感激。
主文件:
// --------------------------------------------------------------------------------------
// | This program is made for an arduino mega 2560 used in conjunction with the |
// | (chinese) OPEN-SMART 3.2 inch TFT LCD Shield ILI9327 |
// | This version of the program is a slimmed down one to clearly convey the problem |
// | I am currenlty having drawing pictures on this setup |
// --------------------------------------------------------------------------------------
// This program is based on the library obtained from
// https://drive.google.com/open?id=0B6uNNXJ2z4CxYktCQlViUkI1Sms
// There is also a demo available on YouTube
// https://www.youtube.com/watch?v=JQHGYnKeC0M&t=2s
#include <Adafruit_GFX.h> // Core graphics library
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
// -------------------------------------------------------------------------------------
// | Variable declaration |
// -------------------------------------------------------------------------------------
// Set colors
#define BLACK 0x0000
#define BACKGROUND 0x07FF
// No idea with this does tbh
uint16_t g_identifier;
// Spacing variables
uint8_t cube_size = 75;
uint8_t padding = 3;
uint8_t ix1 = 5+2 * padding;
uint8_t ix2 = 5+3 * padding + cube_size;
uint8_t ix3 = 5+4 * padding + 2 * cube_size;
uint8_t ix4 = 5+5 * padding + 3 * cube_size;
uint16_t ix5 = 5+(6 * padding) + 4 * cube_size;
uint8_t iy1 = 5+1 * padding;
uint8_t iy2 = 5+3 * padding + cube_size;
uint8_t iy3 = 5+4 * padding + 2 * cube_size;
//Progmem Icon init
extern uint8_t icon_from_progmem[];
// -------------------------------------------------------------------------------------
// | Functions |
// -------------------------------------------------------------------------------------
// Standard drawbitmap function
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color) {
int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
uint8_t byte = 0;
for (int16_t j = 0; j < h; j++, y++) {
for (int16_t i = 0; i < w; i++) {
if (i & 7) byte <<= 1;
else byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]);
if (byte & 0x80) tft.drawPixel(x + i, y, color);
}
}
}
// -------------------------------------------------------------------------------------
// | Setup |
// -------------------------------------------------------------------------------------
// I just copied this part to get the screen to work
void setup(void) {
Serial.begin(9600);
Serial.println(F("TFT LCD test"));
// tft.reset(); //we can't read ID on 9341 until begin()
g_identifier = tft.readID(); //
Serial.print("ID = 0x");
Serial.println(g_identifier, HEX);
if (g_identifier == 0x00D3 || g_identifier == 0xD3D3) g_identifier = 0x9481; // write-only shield
if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial
// g_identifier = 0x9329; // force ID
tft.begin(g_identifier); //to enable ILI9327 driver code
tft.setRotation(3); //Change orientation (landscape and portrait)
}
// -----------------------------------------------------------------------------------
// | Loop |
// -----------------------------------------------------------------------------------
void loop(void) {
tft.fillScreen(BACKGROUND); //
unsigned char myCharArray[512];
byte myChar;
for (int k = 0; k < 512; k++) {
// Create myCharArray from icon_from_progmem
myChar = pgm_read_byte(icon_from_progmem + k);
myCharArray[k] = char(myChar);
// Print data from myCharArry to the serial monitor
Serial.print("CHAR ARRAY: ");
Serial.print(k);
Serial.print(" ");
Serial.println(myChar);
}
// Visual separtion string
Serial.println("------------------------------------------------------------------");
// Print data from icon_from_progmem to serial monitor
for (int k=0; k<512; k++){
Serial.print("ICONS ARRAY: ");
Serial.print(k);
Serial.print(" ");
Serial.println(icon_from_progmem[k]);
}
// Draw the two icons on the screen
drawBitmap(ix2, iy1, myCharArray, 64, 64, BLACK);
drawBitmap(ix4, iy1, icon_from_progmem, 64, 64, BLACK);
delay(600000);
} // end of void loop
位图的单独文件:
#include <avr/pgmspace.h>
// 'PlafLamp', 64x64px
const unsigned char icon_from_progmem [] PROGMEM = {
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xc0, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x7f, 0x00, 0x00,
0x00, 0x01, 0xfc, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00,
0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00,
0x00, 0x0f, 0x80, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
0x00, 0x00, 0x07, 0xc0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xe0, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x80, 0x3f, 0x00, 0x00,
0x00, 0x01, 0xf8, 0x03, 0xc0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x03, 0xc0, 0x0f, 0xc0, 0x00,
0x00, 0x07, 0xe0, 0x03, 0xc0, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x00,
0x00, 0x07, 0x80, 0x03, 0xc0, 0x01, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x03, 0xc0, 0x00, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00
};
What is displayed on the screen
左图为CHAR ARRAY,右图为ICON ARRAY。
在 drawBitmap() 中,您正在通过 pgm_read_byte()
遍历字节在 avr-libc 文档中说
Read a byte from the program space with a 16-bit (near) address. Note: The address is a byte address. The address is in the program space.
作为位图副本的数组 "myCharArray" 不在程序 space 中,因此 pgm_read_byte() 无法正常运行。