Таблица кириллических символов для дисплеев Winstar

Мне понадобилась кириллица в двухстрочном винстаровском индикаторе, а китайцы её в знакогенераторе разместили не в соответствии с CP1251, а как им захотелось.



Для быстрого перекодирования в китайскую кириллицу сделал такую таблицу соответствия:

#ifndef __WEH1602CHARTABLE
#define __WEH1602CHARTABLE

const char charTable[256] = {
	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
	0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
	0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
	0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
	0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
	0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA2,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
	0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB5,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
	0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
	0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,0xAC,0xE2,0xAD,0xAE,0x62,0xAF,0xB0,0xB1,
	0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
	0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7};
	
#endif

Использовать таким образом (исходники должны быть в кодировке Windows-1251):

DrawString("кириллица",0,0);

А в функции отправки в индикатор так:

SendData(charTable[textBuffer[i]]); // отправка символа из буфера

Такой знакогенератор я видел в одно-, двух- и четырёхстрочных индикаторах.



Если было, то пусть модератор удалит.
  • +1
  • 04 ноября 2013, 00:30
  • ATAMAH

Комментарии (84)

RSS свернуть / развернуть
не брезгуй, удали самостоятельно :)
0
  • avatar
  • 21h
  • 04 ноября 2013, 02:04
Вполне стандартная (для этих индикаторов) кодовая таблица. Перекодировать можно и оптимальней по расходу памяти. Минимум, что я видел — 64 байта на таблицу.
0
  • avatar
  • Vga
  • 04 ноября 2013, 02:41
У меня стм32 с мегабайтом флеша, так что гуляю на все.
0
напрасно. очень напрасно.
640КБ хватит всем (с)?..
0
Ну а чо он без дела болтаться будет?? Для AVR, конечно, я бы диапазон выделил, но тут просто полную таблицу запостил, поправят кому надо.
0
да не. если стм32 — вопросов нет (оно лежит во флеши). просто у авр фишка в том, что все эти массивы в рантайме копируются в ОЗУ. которой традиционно мало.
-2
Даже те, что объявлены с __flash? Const я знаю, что жрёт память.
0
хех. курите матчасть.
у авр доступ к флеши чуть иначе. если коротко — массив будет копироваться в ОЗУ.
-2
Я замечал, что программа с длинными массивами иногда падает, но не думал, что настолько всё плохо. В таком случае можно пользовать байтовый указатель со смещением. Он не должен много памяти жрать.
0
Керниган и Ритчи утверждают, что массив и указатель эквивалентны в языке Си.
0
мнда. и вы тоже курите матчасть. K&R рассматривали совсем другую архитектуру. авр «чуть-чуть», самую малость, другие…
если вы не подкалываете, то уточним начальные условия в рамках этой ветки:
камень — авр и массив у нас лежит во флеши.
и что там вам подскажут K&R?
0
Вполне возможно, что в гарвардской архитектуре будет отличаться, будет использован другой индексный регистр.
K & R в книге не писали вообще ни о какой архитектуре.
Копировать массив или не копировать при доступе по чтению — на совести разработчиков компилятора. Для ускорения доступа есть смысл копировать, а иначе зачем это может быть нужно?
0
намека хватит, или надо разжевать? ;)
впрочем, там-же и вся остальная еда тоже есть… ;)
0
курите матчасть.
а ничего, что выборка данных их флеши и из рамы совсем чуть-чуть отличаются?.. ;)
гарвардская архитектура...
0
*из флеши
конечто-же
0
Да куда мне до эксперта по костылям, не вознесусь на такую высоту никогда.
0
не ёрничайте, а просто наберитесь мужества (собрав яйца в кулак при необходимости) и признайте недостаточное знание вопроса.
-2
Для достаточного знания вопроса мне нужно только через слово повторять «курите матчасть». Сразу стану просветлённым гурой.
+1
т.е. вы утверждаете, что запись
const char charTable[256] = {...}
...
SendData(charTable[textBuffer[i]]); // отправка символа из буфера

на авр не оказывает влияния на озу (ака RAM)?..
0
сорри, но учебный курс авр дихальта я повторять не намерен. тем более в комментах.
-2
Это про те пляски с бубном вокруг костылей компилятора? Может проще IDE поменять?
0
это не компилятор. это особенности архитектуры…
0
Если ты про это, то ICC AVR без дополнительных извратов даёт объявлять строки во флеше и читать их по указателю.
0
const __flash char charTable[256] = {...}

и:

SendData(*(charTablePtr + textBuffer[i]));

в ICC AVR никак чудовищно жрать память не будет. Похожее я уже делал для менюшек на разных языках.
0
эммм… ICC — это что?
(только не говорите, что это...)
0
www.imagecraft.com/ Редактор Code::Blocks, самый нормальный, из всех, что есть для AVR.

Прикинь, этот компилятор такое умеет:

const __FLASH char *menuInputsTitle[3] = { "Overload input logic  ", "Gong input logic  ", "Door input logic  " };

и не оправдывается Особой Архитектурой.
0
угу. SWG (земля ему пухом и все такое) вообще писался кипятком c микропаскаля. и что? это все только прятало от пользователя внутренности камня. но совсем не освобождало от ответственности.
0
Пиши в машинных кодах. Это труЪ.
0
еще раз повторю: не ёрничай.
0
Не выёбывайся, и всего делов.
0
слился.
0
Да-да, ты меня затроллил и у меня пукан бомбанул. Учи матчасть (с)
0
и вообще. почитайте про гарвардскую архитектуру. и дальше. просто чтобы не оказываться………… ..!
на этом диалог заканчиваю.
0
Конечно почитаю, это ты полезное подсказал. Но костыли я даже после этого нормой считать не буду.
0
пойми — простое чтение константы из флеши (без копирования в ОЗУ) на АВР == (фактически) костыли.
0
Пусть это компилятор делает, а не программист.
0
на этом полемику считаю законченной.
читайте про архитектуры. читайте про компиляторы. в общем, учите матчасть чуждых вам архитектур, раз уж решаетесь пытаться спорить о них…
Успехов!
0
Литературку порекомендуете?
Так чтобы ясным по белому было написано, что гарвардская архитектура непременнейше требует copy-on-read.
0
Я вот чего вычитал в доках на среду разработки (стр. 149):

data - this is the data area containing initialized global and static variables, and 
strings. The initial values of the global variables and strings are stored in the 
idata area and copied to the data area at startup time.

data — область, в которой находятся все переменные в процессе работы программы.
idata — область значений констант, из которой они копируются в ОЗУ при старте программы.
0
Интересная информация также на страницах 117 и 118, особенно в разделе Strings. Оказывается, стринги копируются в ОЗУ для того чтобы не было двух версий библиотечных функций для работы со стрингами. По всей видимости, отсюда кое у кого такая непоколебимая уверенность, что на гарвардской архитектуре данные из ПЗУ непременно обязаны копироваться в ОЗУ.
0
Я так понял, что он описал какой-то косяк с конкретной IDE, которая не умеет нормально работать со строками во флеше. Рахитектура тут не при чём.
0
Собственно архитектура не принуждает копировать стринги, это решение разработчиков компилятора.
В том документе, что вы дали ссылку, написано:
The problem is that, in C, strings are converted to char pointers. If strings are allocated in the program memory, either all the string library functions must be duplicated to handle different pointer flavors, or the strings must also be allocated in the data memory. The ImageCraft compiler offers two options for dealing with this.

The default is to allocate the strings in both the data memory and the program memory. All references to the strings are to the copies in data memory.

You can direct the compiler to place all literal strings in FLASH only by selecting the Build Options — Target “Strings In FLASH Only” checkbox. Again, be aware that you must be careful when calling library functions. When this option is checked, effectively the type for a literal string is __flash char *, and you must ensure the function takes the appropriate argument type.
С. 118.
0
А самое смешное вот тут: www.terraelectronica.ru/pdf/ST/CortexM3.pdf

STM32 key benefits

Leading-edge architecture with Cortex-M3 core:
■ Harvard architecture
0
Под гарвардской архитектурой они подразумевают, что хотя адресное пространство одно (как в фон-неймановской архитектуре), разные виды памяти висят на отдельных шинах, и потому ядро может одновременно читать данные из ОЗУ и очередную команду из флэша, а не по очереди по одной и той же шине. Примерно то же они пишут и про STM8, которые тоже имеют общее АП (AFAIK).
С точки зрения компиляторов и программистов, STM8 и STM32 — фон-неймановские.
0
Так гарвардская архитектура подразумевает и разные адресные пространства для данных и кода? Или это маркетологи писали? Везде обманывают.
0
А хрен знает. Некоторые называют вон то, что у стм «фон-неймановской с раздельными шинами», некоторые говорят что это чушь собачья и называют гарвардской. Лично я считаю все, у чего общее АП данных и программ — фон-неймановской, а у чего раздельно — гарвардской. STM8 и STM32, соответственно, тоже считаю фон-неймановскими, и пофиг, что там ST пишет.
0
А вообще смешно:

Executable region for program code. Can also put 
data here.
Executable region for data. Can also put code 
here.
0
Мне стыдно, что с таким авторитетом спорить решился! Из всех твоих советов обязательно составлю себе план на будущее!
0
Вопрос куда он ее кладет при этом. GCC кладет и в ПЗУ и в ОЗУ грузит сразу же после старта. Чтобы в GCC данные в ПЗУ не лезли в озу их надо объявлять как CONST, совать за пределы main и читать через функцию pgm_read_byte/word. Скармливая ей адрес. IAR вроде бы не требует таких заморочек.
0
В ПЗУ, память не жрёт при этом. Const переменные будут висеть в памяти, а если добавить при объявлении __flash, то во флеше. Объявлять, естественно, вне функции.
0
С какой это стати? Обьявить как флеш, вынести из main и доступ через pgm_read и все дела. IAR вроде бы это вообще прозрачно делает. В GCC есть затрахи некоторые.
0
Я ICC AVR пользую, там просто чтение по указателю работает ссылка да и среда удобнее IAR. Советую.
0
А вы уверены, что это работает именно так как вы думаете? Карту памяти во время работы смотрели?
0
Можно ассемблер глянуть:

.area lit(rom, con, rel) ; сама таблица в области констант
_charTable#A256_Kc::
	.byte 0,1
	.byte 2,3
	.byte 4,5
...

	.area data(ram, con, rel) ; указатель, который будем читать
_charTablePtr#Pc:
	.blkw 1
	.area idata(rom)
	.word _charTable#A256_Kc
...

_main#Fiv::
	lds R30,_charTablePtr#Pc
	lds R31,_charTablePtr#Pc+1
	ldd R2,z+48
	out 0x1b,R2 ; запись в PORTA
0
Ну так вот LDD это чтение из ОЗУ. Т.е. таблица лежит в ОЗУ. Чтение из флеша это LPM
0
Может у моей меги (ATM32) какой-то особый ассамблер, но даже если объявить во флеше массив, заведомо больший всего ОЗУ (2048 байт)

.area lit(rom, con, rel)
_charTable#A3072_Kc::

То программа компилится и работает. Даташит почитаю.
0
ROM 10% full. 3160 out of 32768 bytes used (does not include absolute areas).
  RAM 2 bytes used (does not include stack usage).
0
Хотя и при доступе к элементу массива ничуть не хуже:

.area lit(rom, con, rel)
_charTable#A256_Kc::
	.byte 0,1
	.byte 2,3
	.byte 4,5
...

_main#Fiv::
	ldi R30,<_charTable#A256_Kc+48
	ldi R31,>_charTable#A256_Kc+48
	lpm R2,Z
	out 0x1b,R2
0
Вот тут другое дело. Вообще тот же IAR без особых заморочек с флешем работет. ICC тоже должен, он ведь специально для AVR написан. В отличии от универсального GCC который AVR поддерживает на костылях т.к. гарвардская архитектура ему изначально неведома.
0
Оффтопом: тебе код для парсера скинуть, чтобы нормально видео ютубовское встраивалось даже с указанием времени? У меня сайт на таком же движке, я такое давно добавил, а тут только дефолтное работает.
0
const __flash char charTable[256] = { ... };

int main(void) {
    PORTA = charTable[0x30];

.area lit(rom, con, rel)
_charTable#A256_Kc::
        .byte 0,1
        .byte 2,3
        .byte 4,5
...

_main#Fiv::
        ldi R30,<_charTable#A256_Kc+48
        ldi R31,>_charTable#A256_Kc+48
        lpm R2,Z
        out 0x1b,R2

ROM 2% full. 338 out of 32768 bytes used (does not include absolute areas).
RAM 0 bytes used (does not include stack usage).
0
Зачем удалять, пусть висит, авось полезна будет.
0
ну тогда уж в теги и LCD добавить. для облегчения поиска…
0
Согласен.
0
Каких не хватает?
0
не тупи. LCD
0
А чего таблицу то разместил в ОЗУ памяти, а не во флешь? Или делал не для AVR?
0
Я для стм32 делал. Кстати OLED-индикатор прекрасно работает без преобразования уровней, в отличие от LCD.
0
Первые 10 строчек можно заменить простой проверкой
Но и в таком виде сэкономит кому-нибудь несколько часов тупого долбокодерства :)
0
Я делаю так:
const char abc[64] ={0x41,0xA0,
0x42,0xA1,0xE0,0x45,0xA3,0xA4,
0xA5,0xA6,0x4B,0xA7,0x4D,0x48,
0x4F,0xA8,0x50,0x43,0x54,0xA9,
0xAA,0x58,0xE1,0xAB,0xAC,0xE2,
0xAD,0xAE,0x62,0xAF,0xB0,0xB1,
0x61,0xB2,0xB3,0xB4,0xE3,0x65,
0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,
0xBC,0xBD,0x6F,0xBE,0x70,0x63,
0xBF,0x79,0xE4,0x78,0xE5,0xC0,
0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,
0xC6,0xC7};

void LCD_put_string(uint8_t *str)
{
char k,j;
while (k=*str++)
{
if (k>=192)
{
j=abc[k-192];
LCD_putchar(j);
}
else LCD_putchar(k);
}
}
0
Букву Ё можно добавить. Заглавная 0xA8 в знакогенераторе, строчная 0xB8.
0
Согласен! Только как-то не надо было....) Код впихивался в STM8S003K3, в меньшие не пробовал...(
0
Кончаем срач.

Для Winavr:


const unsigned char convert_HD44780[256] PROGMEM =
{

0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,
0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,
0xAC,0xE2,0xAD,0xAE,0xAD,0xAF,0xB0,0xB1,
0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,
0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,
0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7
};


unsigned char lcd_epson_rus(unsigned char c){

//	const unsigned char *fontpointer;

   if  (c > 191){
	   c = c - 192;
	   c= pgm_read_byte(&convert_HD44780[c]);
   	   }

return c;
}
0
  • avatar
  • Omul
  • 06 ноября 2013, 05:23
А воообще по фэншую так:

const unsigned char convert_HD44780[64] PROGMEM =
{

0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,
0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,
0xAC,0xE2,0xAD,0xAE,0xAD,0xAF,0xB0,0xB1,
0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,
0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,
0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7
};

unsigned char lcd_epson_rus(unsigned char c){

   if  (c > 191){
           c -=192;
           c= pgm_read_byte(&convert_HD44780[c]);
           }

return c;
}

Почему кстати нельзя редактировать свои комменты? И окошко комментариев маленькое.
0
  • avatar
  • Omul
  • 06 ноября 2013, 05:37
Почему кстати нельзя редактировать свои комменты?
Ограничение движка. С хабра слизано. Возможно связано с тем, что некоторые толстые и зеленые злоупотребляют сей возможностью там, где она есть.
И окошко комментариев маленькое.
Растяни, в правом нижнем углу стандартная «ручка» для ресайза.
0
Есть плагин для редактирования. Только здесь он не установлен.
0
Ок, спасибо. Модеры — мой первый коммент можно удалить, а второй забыл заключить в тег code.
0
  • avatar
  • Omul
  • 06 ноября 2013, 07:46
А еще тут под каждым комментарием есть кнопка «ответить». Ей следует пользоваться, если ты отвечаешь на комментарий, а не оставляешь комментарий к самому посту.
0
Ок.
0
говнокод жесть :)
сконвертировать макросом ума не хватило :)
0
Хуякросом.
-4
:)
-2
-1
Раз уж ты такой настойчивый, скажи, какой макрос даст на выходе более быстрый код, чем с этой таблицей?
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.