ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
2 июля
411730 Топик полностью
SciFi (23.05.2013 08:41, просмотров: 101) ответил Adept на вот выбрал TFT дисплей MT22G07B (контроллер HX8312A) покритикуйте посоветуйте, правильно или нет выбрал.Критерии такие :
Отчего все так боятся графическую библиотеку? Вот вам пример (всего-то 400 строк, поддерживает 2 дисплея - HX8346 и S6D04H0): /** * @file lcd.h */ #ifndef LCD_H #define LCD_H #include <stdint.h> #define LCD_WIDTH 320 #define LCD_HEIGHT 240 #define LCD_BLACK 0x000000 #define LCD_WHITE 0xFFFFFF #define LCD_RED 0x0000FF #define LCD_GREEN 0x00FF00 #define LCD_BLUE 0xFF0000 #define LCD_YELLOW 0x00FFFF typedef uint32_t lcd_color; enum text_align { ALIGN_RIGHT, ALIGN_LEFT }; struct font_char { uint32_t width : 8; uint32_t index : 24; }; struct font { uint8_t height; uint8_t first; const struct font_char* chars; const uint32_t* bitstream; }; struct bitmap { uint16_t width; uint16_t height; const uint32_t* palette; const uint8_t* bitstream; }; extern void lcd_init(void); extern void lcd_fillrect(int left, int top, int right, int bottom, lcd_color rgb); extern void lcd_settextattr(const struct font* font, lcd_color fgrgb, lcd_color bgrgb, enum text_align align); extern int lcd_getcharwidth(char c); extern int lcd_gettextwidth(const char* str); extern void lcd_outputchar(char c, int x, int y); extern void lcd_outputtext(const char* str, int x, int y); extern void lcd_drawbitmap(const struct bitmap* bitmap, int x, int y); #endif /* LCD_H */ /** * @file lcd.c */ #include "lcd.h" #include "timer.h" #include "stm32f2regs.h" #include <string.h> #include <stdbool.h> #define HTONS(x) (__builtin_constant_p(x) ? ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8)) : rev16(x)) #define HTONL(x) __builtin_bswap32(x) #define LCD_BASE 0x60000000 #define LCD_CMDOFS 0x00100000 #define LCD_CMD(n) do *(uint8_t volatile*)LCD_BASE = (n); while (0) #define LCD_WRITE8(x) do *(uint8_t volatile*)(LCD_BASE + LCD_CMDOFS) = (x); while (0) #define LCD_WRLE16(x) do *(uint16_t volatile*)(LCD_BASE + LCD_CMDOFS) = (x); while (0) #define LCD_WRLE32(x) do *(uint32_t volatile*)(LCD_BASE + LCD_CMDOFS) = (x); while (0) #define LCD_WRBE16(x) do *(uint16_t volatile*)(LCD_BASE + LCD_CMDOFS) = HTONS(x); while (0) #define LCD_WRBE32(x) do *(uint32_t volatile*)(LCD_BASE + LCD_CMDOFS) = HTONL(x); while (0) #define LCD_REG(n, x) do { LCD_CMD(n); LCD_WRITE8(x); } while (0) #define LCD_IDX(n) LCD_CMD(n) #define LCD_READ8() (*(uint8_t volatile*)(LCD_BASE + LCD_CMDOFS)) enum lcd_type { LCD_SAMSUNG, LCD_HIMAX }; static enum text_align align; static const struct font* font; static lcd_color shades[8]; static enum lcd_type type; static int rev16(int x) { __asm("rev16 %0, %1" : "=r" (x) : "r" (x)); return x; } static void write_array(int len, const char *src) { timer_delay(TIMER_TPS / 1000000); while (len-- > 0) { LCD_WRITE8(*src++); timer_delay(TIMER_TPS / 1000000); } } static bool init_samsung(void) { LCD_CMD(0x11); /* Sleep Out */ LCD_CMD(0xF3); /* Power Control */ write_array(5, "\x01\xFF\x1F\x00\x03"); LCD_CMD(0xF2); /* Display Control */ write_array(17, "\x28\x78\x7F\x08\x08\x00\x00\x15\x48\x00\x07\x01\x00\x00\x94\x08\x08"); LCD_CMD(0xF4); /* Power Control */ write_array(20, "\x09\x00\x00\x00\x21\x47\x01\x02\x2A\x69\x03\x2A\x00\x03\x00\x00\x00\x00\x00\x00"); LCD_CMD(0xF5); /* VCOM Control */ write_array(12, "\x00\x34\x56\x00\x00\x12\x00\x00\x0D\x01\x00\x00"); LCD_CMD(0xF6); /* Source Control */ write_array(9, "\x01\x01\x07\x00\x02\x0C\x02\x08\x03"); LCD_CMD(0xF7); /* Interface Control */ write_array(4, "\x01\x00\x10\x00"); LCD_CMD(0xF8); /* Panel Control */ write_array(3, "\x99\x00\x00"); LCD_CMD(0xF9); /* Gamma Selection */ LCD_WRITE8(0x01); LCD_CMD(0xFA); /* Positive Gamma Control */ write_array(12, "\x00\x17\x0C\x18\x23\x36\x2B\x2C\x2A\x28\x25\x00\x00\x00\x00\x00"); LCD_CMD(0xFB); /* Negative Gamma Control */ write_array(12, "\x00\x0A\x26\x23\x23\x26\x1A\x3B\x27\x1E\x0D\x00\x00\x00\x00\x00"); LCD_CMD(0x36); /* Memory Data Access Control */ LCD_WRITE8(0x28); LCD_CMD(0x29); /* Display ON */ LCD_CMD(0x0A); /* read power status */ (void)LCD_READ8(); /* dummy read */ return (0x1C == (0x7F & LCD_READ8())); } static void init_himax(void) { LCD_REG(0x26, 0x00); LCD_REG(0x1B, 0x08); LCD_REG(0x43, 0x00); /* Set VCOMG */ timer_delay(TIMER_TPS / 100); LCD_REG(0x1C, 0x06); /* Set AP[2-0] */ LCD_REG(0x1B, 0x10); timer_delay(TIMER_TPS / 25); LCD_REG(0x43, 0x80); /* Set VCOMG */ LCD_REG(0x01, 0x06); /* Display Mode */ LCD_REG(0x16, 0x60); /* MX, MY, MV, BGR */ LCD_REG(0x46, 0x94); /* Gamma */ LCD_REG(0x47, 0x41); /* Gamma */ LCD_REG(0x48, 0x00); /* Gamma */ LCD_REG(0x49, 0x33); /* Gamma */ LCD_REG(0x4A, 0x23); /* Gamma */ LCD_REG(0x4B, 0x45); /* Gamma */ LCD_REG(0x4C, 0x44); /* Gamma */ LCD_REG(0x4D, 0x77); /* Gamma */ LCD_REG(0x4E, 0x12); /* Gamma */ LCD_REG(0x4F, 0xCC); /* Gamma */ LCD_REG(0x50, 0x46); /* Gamma */ LCD_REG(0x51, 0x82); /* Gamma */ LCD_REG(0x06, 0x00); LCD_REG(0x08, 0x00); timer_delay(TIMER_TPS / 16); LCD_REG(0x26, 0x04); timer_delay(TIMER_TPS / 100); LCD_REG(0x26, 0x24); LCD_REG(0x26, 0x2C); timer_delay(TIMER_TPS / 100); LCD_REG(0x26, 0x3C); } void lcd_init(void) { /* enable clocking of PORT A, B, D, E */ RCC_AHB1ENR |= 0x0000001B; /* enable clocking of FSMC */ REGBIT(RCC_AHB3ENR, 0) = 1; FSMC_BWTR1 = ( 0 << 28) /* access mode A */ | ( 1 << 20) /* max. CLK out freq., don't care */ | ( 8 << 8) /* data phase: 8 HCLK cycles */ | ( 0 << 4) /* address hold: 0 HCLK cycles */ | ( 7 << 0); /* address setup: 7 HCLK cycle */ FSMC_BTR1 = ( 0 << 28) /* access mode A */ | ( 1 << 20) /* max. CLK out freq., don't care */ | (11 << 16) /* delay of 11 HCLK cycles between consecutive reads */ | (42 << 8) /* data phase: 42 HCLK cycles */ | ( 0 << 4) /* address hold: 0 HCLK cycles */ | ( 1 << 0); /* address setup: 1 HCLK cycle */ FSMC_BCR1 = ( 1 << 14) /* enable FSMC_BTWR register */ | ( 1 << 12) /* enable write operations */ | ( 1 << 6) /* access enable */ | ( 0 << 4) /* memory width: 8 bits */ | ( 0 << 2) /* memory type: SRAM, ROM */ | ( 0 << 1) /* non-multiplexed */ | ( 1 << 0); /* bank enable */ GPIOD_BSRR = (1 << 7); /* set CS high */ GPIOD_AFRL |= 0x00CC00CC; GPIOD_AFRH |= 0xCC000000; GPIOE_AFRL |= 0xC00C0000; GPIOE_AFRH |= 0xC0000CCC; /* configure PD0,1,4,5,14,15 as AF, PD7 as GP output */ GPIOD_MODER |= 0xA0004A0A; /* configure PE4,7,8,9,10 as AF */ GPIOE_MODER |= 0x002A8200; /* configure PB7 as GP output */ GPIOB_MODER |= 0x00004000; timer_delay(TIMER_TPS / 100000); /* 10 us reset pulse */ /* set RESET high */ GPIOB_BSRR = (1 << 7); timer_delay(TIMER_TPS / 200); /* 5 ms delay */ /* set CS low */ GPIOD_BSRR = (0x10000u << 7); /* configure PA4 as GP output */ GPIOA_MODER |= 0x00000100; if (init_samsung()) { type = LCD_SAMSUNG; lcd_fillrect(0, 0, 319, 239, LCD_BLACK); timer_delay(TIMER_TPS / 10); } else { type = LCD_HIMAX; init_himax(); timer_delay(TIMER_TPS / 20); } GPIOA_BSRR = (1 << 4); /* backlight on */ } static void putpixel(lcd_color rgb) { switch (type) { case LCD_SAMSUNG: LCD_WRLE16(rgb & 0xFFFF); LCD_WRITE8(rgb >> 16); break; case LCD_HIMAX: LCD_WRITE8(rgb >> 16); LCD_WRBE16(rgb & 0xFFFF); break; } } void lcd_fillrect(int left, int top, int right, int bottom, lcd_color rgb) { int i; uint32_t pdata[3]; switch (type) { case LCD_SAMSUNG: LCD_CMD(0x2A); LCD_WRBE16(left); LCD_WRBE16(right); LCD_CMD(0x2B); LCD_WRBE16(top); LCD_WRBE16(bottom); LCD_CMD(0x2C); break; case LCD_HIMAX: rgb = HTONL(rgb) >> 8; LCD_REG(0x02, left >> 8); LCD_REG(0x03, left & 0xFF); LCD_REG(0x04, right >> 8); LCD_REG(0x05, right & 0xFF); LCD_REG(0x07, top); LCD_REG(0x09, bottom); LCD_IDX(0x22); break; } pdata[0] = (rgb << 24) | rgb; pdata[1] = (rgb << 16) | (rgb >> 8); pdata[2] = (rgb << 8) | (rgb >> 16); for (i = (right - left + 1) * (bottom - top + 1); i > 0; i -= 4) { LCD_WRLE32(pdata[0]); LCD_WRLE32(pdata[1]); LCD_WRLE32(pdata[2]); } } void lcd_settextattr(const struct font* font_arg, lcd_color fgrgb_arg, lcd_color bgrgb_arg, enum text_align align_arg) { int i; font = font_arg; memset(shades, 0, sizeof(shades)); /* Calculate 8 shades between BG and FG colors for each of R, G, B */ shades[0] = bgrgb_arg; for (i = 0; i < 24; i += 8) { int mask, j, diff; mask = 0xFF << i; diff = (((int)fgrgb_arg & mask) - ((int)bgrgb_arg & mask)) >> i; diff *= 128; diff /= 7; for (j = 1; j < 8; j++) { int tmp; tmp = j * diff; tmp /= 128; tmp <<= i; tmp += bgrgb_arg; shades[j] |= (tmp & mask); } } align = align_arg; } void lcd_outputchar(char c, int x, int y) { char buf[2]; buf[0] = c; buf[1] = 0; lcd_outputtext(buf, x, y); } void lcd_outputtext(const char* str, int x, int y) { const struct font_char* firstchar; int h; switch (align) { case ALIGN_LEFT: break; case ALIGN_RIGHT: x -= lcd_gettextwidth(str); break; } firstchar = font->chars; h = font->height; switch (type) { case LCD_SAMSUNG: LCD_CMD(0x2B); LCD_WRBE16(y); LCD_WRBE16(y + h - 1); break; case LCD_HIMAX: LCD_REG(0x07, y); LCD_REG(0x09, y + h - 1); break; } while (*str != 0) { const struct font_char* pchar; int idx, left; pchar = firstchar + ((uint8_t)*str - font->first); str++; switch (type) { case LCD_SAMSUNG: LCD_CMD(0x2A); LCD_WRBE16(x); LCD_WRBE16(x + pchar->width - 1); LCD_CMD(0x2C); break; case LCD_HIMAX: LCD_REG(0x02, x >> 8); LCD_REG(0x03, x & 0xFF); LCD_REG(0x04, (x + pchar->width - 1) >> 8); LCD_REG(0x05, (x + pchar->width - 1) & 0xFF); LCD_IDX(0x22); break; } x += pchar->width; idx = pchar->index; left = pchar->width * h; while (left > 0) { uint8_t c; c = (font->bitstream[idx >> 3] >> ((idx & 7) << 2)) & 0xF; idx++; if ((c & 8) == 0) { putpixel(shades[c]); left--; } else { int n; n = (font->bitstream[idx >> 3] >> ((idx & 7) << 2)) & 0xF; idx++; n += 1; c &= 7; left -= n; while (n > 0) { putpixel(shades[c]); n--; } } } } } int lcd_getcharwidth(char c) { return font->chars[(uint8_t)c - font->first].width; } int lcd_gettextwidth(const char* str) { int sum = 0; while (*str != 0) { sum += lcd_getcharwidth(*str); str++; } return sum; } void lcd_drawbitmap(const struct bitmap* bitmap, int x, int y) { const uint32_t* palette; const uint8_t* bitstream; int n; palette = bitmap->palette; bitstream = bitmap->bitstream; n = bitmap->width * bitmap->height; switch (type) { case LCD_SAMSUNG: LCD_CMD(0x2A); LCD_WRBE16(x); LCD_WRBE16(x + bitmap->width - 1); LCD_CMD(0x2B); LCD_WRBE16(y); LCD_WRBE16(y + bitmap->height - 1); LCD_CMD(0x2C); break; case LCD_HIMAX: LCD_REG(0x02, x >> 8); LCD_REG(0x03, x & 0xFF); LCD_REG(0x04, (x + bitmap->width - 1) >> 8); LCD_REG(0x05, (x + bitmap->width - 1) & 0xFF); LCD_REG(0x07, y); LCD_REG(0x09, y + bitmap->height - 1); LCD_IDX(0x22); break; } while (n > 0) { int len; if (*bitstream == 0) { bitstream++; len = *bitstream; bitstream++; n -= len; do { putpixel(palette[*bitstream]); bitstream++; len--; } while (len > 0); } else { len = *bitstream; bitstream++; n -= len; do { putpixel(palette[*bitstream]); len--; } while (len > 0); bitstream++; } } } Если интересно, выложу проги для импорта шрифтов и картинок.
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้