
Оптимизация: Os.
Код
#define LCD_WIDTH 128U
#define LCD_HEIGHT 64U
#define LCD_STR_HEIGHT 8U
unsigned char lcd_vram[LCD_WIDTH][LCD_HEIGHT/LCD_STR_HEIGHT]; // Буфер видеопамяти LCD.
//====================================
void lcd_clrscr(void)
{
unsigned char*p = &lcd_vram[0][0];
#if (((LCD_WIDTH*LCD_HEIGHT/LCD_STR_HEIGHT)/8)>255)
# error "(sizeof(lcd_vram)/8)>255 !!!"
#endif
register unsigned char i = sizeof(lcd_vram)/8;
do
{
*p++ = 0; // 1
*p++ = 0; // 2
*p++ = 0; // 3
*p++ = 0; // 4
*p++ = 0; // 5
*p++ = 0; // 6
*p++ = 0; // 7
*p++ = 0; // 8
}
while (--i);
}
#define LCD_HEIGHT 64U
#define LCD_STR_HEIGHT 8U
unsigned char lcd_vram[LCD_WIDTH][LCD_HEIGHT/LCD_STR_HEIGHT]; // Буфер видеопамяти LCD.
//====================================
void lcd_clrscr(void)
{
unsigned char*p = &lcd_vram[0][0];
#if (((LCD_WIDTH*LCD_HEIGHT/LCD_STR_HEIGHT)/8)>255)
# error "(sizeof(lcd_vram)/8)>255 !!!"
#endif
register unsigned char i = sizeof(lcd_vram)/8;
do
{
*p++ = 0; // 1
*p++ = 0; // 2
*p++ = 0; // 3
*p++ = 0; // 4
*p++ = 0; // 5
*p++ = 0; // 6
*p++ = 0; // 7
*p++ = 0; // 8
}
while (--i);
}
Получаю листинг такого вида:
Код
lcd_clrscr:
ldi r30,lo8(lcd_vram)
ldi r31,hi8(lcd_vram)
.L2:
st Z,__zero_reg__
std Z+1,__zero_reg__
std Z+2,__zero_reg__
std Z+3,__zero_reg__
std Z+4,__zero_reg__
std Z+5,__zero_reg__
std Z+6,__zero_reg__
std Z+7,__zero_reg__
adiw r30,8
ldi r24,hi8(lcd_vram+1024)
cpi r30,lo8(lcd_vram+1024)
cpc r31,r24
brne .L2
ret
ldi r30,lo8(lcd_vram)
ldi r31,hi8(lcd_vram)
.L2:
st Z,__zero_reg__
std Z+1,__zero_reg__
std Z+2,__zero_reg__
std Z+3,__zero_reg__
std Z+4,__zero_reg__
std Z+5,__zero_reg__
std Z+6,__zero_reg__
std Z+7,__zero_reg__
adiw r30,8
ldi r24,hi8(lcd_vram+1024)
cpi r30,lo8(lcd_vram+1024)
cpc r31,r24
brne .L2
ret
Мне никак не удаётся заставить gcc использовать однобайтный счётчик цикла, отказаться от adiw и использовать st+,__zero_reg__. Так код стал бы и короче и быстрее...
И попутно вопрос №2:
Я считал, что static const является альтернативой define.
Но, видимо, я заблуждался...
Код
static const unsigned char MY_ARRAY_SIZE = 2;
//#define MY_ARRAY_SIZE 2
unsigned char my_array[MY_ARRAY_SIZE] = {0,0};
//#define MY_ARRAY_SIZE 2
unsigned char my_array[MY_ARRAY_SIZE] = {0,0};
получаю сообщение:
../../../arclib/common/lcd128x64.c:10: error: variably modified 'my_array' at file scope
../../../arclib/common/lcd128x64.c:10: warning: excess elements in array initializer
../../../arclib/common/lcd128x64.c:10: warning: (near initialization for 'my_array')
А если через #define MY_ARRAY_SIZE 2 - то всё ок.
Знающие люди, объясните такое поведение.
Спасибо!