"правильнее" зависит от того, как вы потом обрабатываете кнопки.
Вопросы по С/С++ (СИ)
а словами написать, какие биты используются, для не желающих восстанавливать их по асму?
"правильнее" зависит от того, как вы потом обрабатываете кнопки.
"правильнее" зависит от того, как вы потом обрабатываете кнопки.
- Реклама
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3320283#p3320283"]а словами написать, какие биты используются...[/uquote]
0 и 4 бит каждого принятого байта.
В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?
0 и 4 бит каждого принятого байта.
В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?
Сдвигами и масками. Элементарно.
Если Вы сумели такое написать на АСМе, то на Си напишите запросто.
Добавлено after 42 seconds:
Можно написать линейный код - проверки битов+установки битов. Выполняться будет быстрей.
Если Вы сумели такое написать на АСМе, то на Си напишите запросто.
Добавлено after 42 seconds:
Можно написать линейный код - проверки битов+установки битов. Выполняться будет быстрей.
- Сообщения: 291
- Зарегистрирован: Чт ноя 06, 2014 13:09:06
[uquote="Пока_без_кота",url="/forum/viewtopic.php?p=3320295#p3320295"]0 и 4 бит каждого принятого байта.
В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?[/uquote]
В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?[/uquote]
Код: Выделить всё
u8_t button_byte (u8_t *p)
{
return ((p[0] & 0x11) << 0) | ((p[1] & 0x11) << 1) | ((p[2] & 0x11) << 2) | ((p[3] & 0x11) << 3);
}- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
[uquote="Пока_без_кота",url="/forum/viewtopic.php?p=3320295#p3320295"]0 и 4 бит каждого принятого байта. В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?[/uquote]
РЕШАЮЩАЯ разница.
Архетипичнейший сюжет кстати - когда общественность начинает "умничать" уточнениями "а вообще вы что сделать пытаетесь?" на конкретный вроде-бы вопрос. И соискателю кажется что над ним издеваются и рейтинг зарабатывают. Но дело в том, что первична задача, а не конкретные шаги по её исполнению. У ассемблерщика свои подходцы, у С-шника свои, у плюсиста - свои. Там где первый морочится упаковкой в байт - второй с третьим наложат на принятые данные структуру с битовыми полями и будут пользоваться этими полями напрямую - оставив всё побитное кунг-фу со сдвигами и масками на долю компилятора.
РЕШАЮЩАЯ разница.
Архетипичнейший сюжет кстати - когда общественность начинает "умничать" уточнениями "а вообще вы что сделать пытаетесь?" на конкретный вроде-бы вопрос. И соискателю кажется что над ним издеваются и рейтинг зарабатывают. Но дело в том, что первична задача, а не конкретные шаги по её исполнению. У ассемблерщика свои подходцы, у С-шника свои, у плюсиста - свои. Там где первый морочится упаковкой в байт - второй с третьим наложат на принятые данные структуру с битовыми полями и будут пользоваться этими полями напрямую - оставив всё побитное кунг-фу со сдвигами и масками на долю компилятора.
Код: Выделить всё
struct state {
unsigned char btn0 : 1;
unsigned char rsv0 : 3;
unsigned char btn1 : 1;
unsigned char rsv1 : 3;
unsigned char btn2 : 1;
unsigned char rsv2 : 3;
unsigned char btn3 : 1;
unsigned char rsv3 : 3;
unsigned char btn4 : 1;
unsigned char rsv4 : 3;
unsigned char btn5 : 1;
unsigned char rsv5 : 3;
};
unsigned char buf[4] = { 0 };
// приняли что положено и забыли подробности как страшный сон - жизнь и так коротка
struct state* pstate = (struct state*)buf;
if (p->btn2)
// цветомузыка
if (p->btn0)
// танцы
if (p->btn5)
// асисяй
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Реклама
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Всем спасибо. Я планировал делать примерно как viiv написал. Но способ Siarzhuk интересен с точки зрения познания.
- Сообщения: 7
- Зарегистрирован: Пт мар 02, 2018 16:31:19
Всем мяу! Помогите новичку разобраться с синтаксисом си для stm32. Среда разработки Keil, отладочная плата stm32f4discovery. Хочу сделать библиотеку для отображения на дисплее векторных шрифтов, в дальнейшем добавить сглаживание. Столкнулся с проблемой, что как таковых текстовых типов данных нет... А ведь хотел координаты полилиний записывать в текстовом виде:
но вот беда... не могу посимвольно читать строку...
Что-то тут не так:
Может кто подскажет, как это делать или как вообще лучше хранить такие цепочки? Думал по 4 байта разбить отрезки типа: , но тут тоже вопрос как их хранить?
Код: Выделить всё
struct TFont {
char *Lines;
} Font[255] ;
...
Font[48].Lines="010516364541301001|0541"; //0
Font[81].Lines="010516364541301001|2547"; //Q
...
Что-то тут не так:
Код: Выделить всё
for(i=0;i<strlen(Font[C].Lines);i++)
{
if (Font[C].Lines[i]!="|") { }
}
Код: Выделить всё
(X1 shl 12) or (Y1 shl 8) or (X2 shl 4) or Y2я, конечно, понимаю: ARM, 32 бита, много памяти и мегагерц, но храниить шрифт в текстовом виде?! до этого даже в Майкрософте не додумались!Shrike1987 писал(а):А ведь хотел координаты полилиний записывать в текстовом виде
шрифт, как очень активно используемый ресурс, должен быть предельно оптимальным, иначе рендеринг его на экране, да еще и со сглаживанием (вы уверены, что задачу себе по "зубам" выбрали? строку не умеете считать, а антиалиасинг - легко?)
имхо, шрифт должен быть в двоичном виде. Если векторный из отрезков прямых линий (если иначе - сразу TTF загружайте - чего там мелочиться), то в виде обычного массива стреуктур типа такого
Код: Выделить всё
typedef struct{
short int dx;
shoet int dy;
}vect_t;
typedef struct{
short int cnt; // количество векторов
vect_t nodes[]; // массив векторов
}symbol_t;если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 7
- Зарегистрирован: Пт мар 02, 2018 16:31:19
Да, текстовый вариант очень плох, это я понимаю. Пришел к нему, т.к. ооочень уж туго дается мне си после delphi... С точки зрения алгоритмизации - задача по зубам, причем исходники wuline сишные есть в интернете, библиотеку для своего дисплея переписал для вывода графики через буфер (благо RAM хватает) + реализация альфа канала, обновления нужного участка экрана... С периферией разобрался благодаря CubeMX. А вот синтаксис языка си ну вообще никак не лезет...
Да, я записываю действительно массив, только не векторов, а координат полилиний, где их нужно разорвать и начать рисовать новую полилинию - ставил символ "|". Прекрасно понимаю, что эта чушь будет и медленно работать и жрать много памяти. Поэтому и решил спросить совета в каком виде хранить массив типа uint16_t чисел, в которых по 4 бита будут записаны координаты отрезка (x1,y1,x2,y2) преобразованных по формуле ( X1 shl 12 ) or ( Y1 shl 8 ) or ( X2 shl 4 ) or Y2
Экономней вижу вариант писать в массив uint8_t пару координат, а разрыв полилинии - заранее определенная (невозможная или неиспользуемая) пара координат...
Ваш вариант возьму за основу, только вместо short int буду использовать uint8_t - всё таки на байт меньше )))
Благодарю, за помощь!!!
Добавлено after 41 minute 59 seconds:
Это абзац... я не могу создать массив, структура которого содержит динамический массив...
Компилятор, конечно же ругается: type containing an unknown-size array is not allowed
Да, я записываю действительно массив, только не векторов, а координат полилиний, где их нужно разорвать и начать рисовать новую полилинию - ставил символ "|". Прекрасно понимаю, что эта чушь будет и медленно работать и жрать много памяти. Поэтому и решил спросить совета в каком виде хранить массив типа uint16_t чисел, в которых по 4 бита будут записаны координаты отрезка (x1,y1,x2,y2) преобразованных по формуле ( X1 shl 12 ) or ( Y1 shl 8 ) or ( X2 shl 4 ) or Y2
Экономней вижу вариант писать в массив uint8_t пару координат, а разрыв полилинии - заранее определенная (невозможная или неиспользуемая) пара координат...
Ваш вариант возьму за основу, только вместо short int буду использовать uint8_t - всё таки на байт меньше )))
Благодарю, за помощь!!!
Добавлено after 41 minute 59 seconds:
Это абзац... я не могу создать массив, структура которого содержит динамический массив...
Код: Выделить всё
typedef struct{
uint8_t dx;
uint8_t dy;
} vect_t;
typedef struct{
uint8_t cnt;
vect_t nodes[];
} symbol_t;
symbol_t VFont[255];Си - не делфи, в нём нет никаких динамический массивов. Есть, конечно, стандартные функции для выделения/удаления памяти в куче, но об этом долго писать. Погуглите...
- Сообщения: 7
- Зарегистрирован: Пт мар 02, 2018 16:31:19
Ок. Разбираться со стеком, выделением памяти и т.д. для меня слишком муторно, поэтому возвращаюсь к варианту с типом char *Lines. Текст буду обновлять все равно редко, так что сойдет хранение координат в тексте...
Как же все-таки получить char от i-го элемента Lines структуры TFont?
Font[48].Lines - ругается
в коде программы загоняю примерно 25 строк в Font - все выполняется без ошибок. Теперь бы с этим научиться работать...
Добавлено after 8 minutes 12 seconds:
хотяб судя по содержимому, там полная каша...
Как же все-таки получить char от i-го элемента Lines структуры TFont?
Код: Выделить всё
struct TFont {
char *Lines;
} Font[255] ;
...
Font[48].Lines="010516364541301001|0541"; в коде программы загоняю примерно 25 строк в Font - все выполняется без ошибок. Теперь бы с этим научиться работать...
Добавлено after 8 minutes 12 seconds:
хотяб судя по содержимому, там полная каша...
Код: Выделить всё
struct TFont {
char *Lines;
} Font[255] ;
..............
Font[48].Lines="010516364541301001|0541";
Font[48].Lines[5] = 'A';
char ch = Font[48].Lines[10];
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3320964#p3320964"]но вот беда... не могу посимвольно читать строку...
Что-то тут не так:[/uquote]
Буквально формально но длина строчки будет пере-strlen-иться на каждой итерации цикла. Оптимизатор, конечно, дремать не будет - но иные пожилые обитатели сего места могут и инфаркт схватить почём зря увидев такое. Но это лирика и оффтоп. Обращение-же ваше к i-тому элементу строки Lines по индексу вполне легально - Lines это указатель и его можно читать как кому нравится - хоть массивно, хоть адресно-арифметично. Но, - Сравниваете вы с адресом строкового литерала "|" а не с байтом 0х7C как задумывалось. Для символьных литералов нужно использовать одиночные кавычки. В качестве мелкого пятничного издевательства вот вам немножко Ъ-шных пере-интерпретаций вашей идеи. Для разминки.
Но подход ваш зело эклектичный, и знание дельфи никак не освобождает от необходимости понимания сути творимых вещей. Так строчки в С - это последовательности байтов, которые завершаются нулём. И strlen в общем случае будет тупо перебирать их от начала до конца - а вы это в условие цикла вставили - видимо чтобы МК не скучал в главном цикле программы.
А "|" это строковая константа и состоит она из двух байтов 0x7C 0x00. И тип у этой константы const char*. А операция взятия элемента массива (в нашем случае строки char-ов) по индексу возвращает нам значение типа char. А вы его сравниваете с const char* - а для компилятора это всё равно как вам на завтрак огурцы солёные с молочком кто предложит, чтобы день прошёл не зазря.
Что-то тут не так:
Код: Выделить всё
for(i=0;i<strlen(Font[C].Lines);i++)
{
if (Font[C].Lines[i]!="|") { }
}
Буквально формально но длина строчки будет пере-strlen-иться на каждой итерации цикла. Оптимизатор, конечно, дремать не будет - но иные пожилые обитатели сего места могут и инфаркт схватить почём зря увидев такое. Но это лирика и оффтоп. Обращение-же ваше к i-тому элементу строки Lines по индексу вполне легально - Lines это указатель и его можно читать как кому нравится - хоть массивно, хоть адресно-арифметично. Но, - Сравниваете вы с адресом строкового литерала "|" а не с байтом 0х7C как задумывалось. Для символьных литералов нужно использовать одиночные кавычки. В качестве мелкого пятничного издевательства вот вам немножко Ъ-шных пере-интерпретаций вашей идеи. Для разминки.
Код: Выделить всё
char* p = NULL;
for (p = Font[C].Lines; *p; p++) {
if (*p != '|') { }
}
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
оффтоп
[uquote="ARV",url="/forum/viewtopic.php?p=3321203#p3321203"]храниить шрифт в текстовом виде?! до этого даже в Майкрософте не додумались![/uquote]
никто так не делает, да, но емнип патент на такое безумство таки есть)
Shrike, у вас в чем конкретно проблема? Первоначально - в ваших строках вида "010516364541301001|0541" все эти "01", "05", "16" и так далее по задумке должны соответстовать числам 1, 5, 16, или таки по счастливой случайности являются какими-никакими корректными строковыми представлениями двухбайтовых чисел?)
[uquote="ARV",url="/forum/viewtopic.php?p=3321203#p3321203"]храниить шрифт в текстовом виде?! до этого даже в Майкрософте не додумались![/uquote]
никто так не делает, да, но емнип патент на такое безумство таки есть)
Shrike, у вас в чем конкретно проблема? Первоначально - в ваших строках вида "010516364541301001|0541" все эти "01", "05", "16" и так далее по задумке должны соответстовать числам 1, 5, 16, или таки по счастливой случайности являются какими-никакими корректными строковыми представлениями двухбайтовых чисел?)
- Сообщения: 7
- Зарегистрирован: Пт мар 02, 2018 16:31:19
Спасибо всем, кто откликнулся и оказал помощь!
"01", "05", "16" это пара координат точек полилиний: (x=0;y=1); (x=0;y=5); (x=1;y=6) ... по оси х больше 4 не бывает, по у - не более 7. Шрифт 4х6 и хвосты у некоторых символов до 7
На глубокое изучение языка Си просто нет времени, для хобби "и так сойдет" =)
Задумку реализовать получилось, в качестве примера приведу фото дисплея с парочкой символов в оригинальном масштабе и в масштабе 7.5
Код приводить не буду, дабы, как написал Siarzhuk, "пожилые обитатели сего места могут и инфаркт схватить почём зря увидев такое" =)))
Следующий этап - антиалайзинг. Если интересно, могу выложить результаты.
"01", "05", "16" это пара координат точек полилиний: (x=0;y=1); (x=0;y=5); (x=1;y=6) ... по оси х больше 4 не бывает, по у - не более 7. Шрифт 4х6 и хвосты у некоторых символов до 7
На глубокое изучение языка Си просто нет времени, для хобби "и так сойдет" =)
Задумку реализовать получилось, в качестве примера приведу фото дисплея с парочкой символов в оригинальном масштабе и в масштабе 7.5
Код приводить не буду, дабы, как написал Siarzhuk, "пожилые обитатели сего места могут и инфаркт схватить почём зря увидев такое" =)))
Следующий этап - антиалайзинг. Если интересно, могу выложить результаты.
- Вложения
-
- IMG_20180303_143230.jpg
- Фото дисплея
- (182.54 КБ) 431 скачивание
Вашу пару можно сократить до 1 байта, при таких условиях.Shrike1987 писал(а):"01", "05", "16" это пара координат точек полилиний ... по оси х больше 4 не бывает, по у - не более 7.
Код: Выделить всё
typedef struct{
unsigned char x:3;
unsigned char y:3;
}t_point;
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3321640#p3321640"]по оси х больше 4 не бывает, по у - не более 7. Шрифт 4х6 и хвосты у некоторых символов до 7[/uquote]
Ну как закончится память - приходите заслушать про битовые поля.
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3321640#p3321640"]На глубокое изучение языка Си просто нет времени, для хобби "и так сойдет" =)[/uquote]
Будь такое сказано про С++ - возможно и прокатило-бы, но в С "глубоко" изучать попросту нечего - умели Люди делать инструмент в своё время.
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3321640#p3321640"]Задумку реализовать получилось, в качестве примера приведу фото дисплея с парочкой символов в оригинальном масштабе и в масштабе 7.5[/uquote]
Думаю не я один сейчас злорадно ухмыльнулся, зная как оно там у вас "оптимально" устроено, в желании задать вопрос: -"Кабы, барин, видео посмотреть. А фоточками сыт не будешь, вестимо."
Ну как закончится память - приходите заслушать про битовые поля.
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3321640#p3321640"]На глубокое изучение языка Си просто нет времени, для хобби "и так сойдет" =)[/uquote]
Будь такое сказано про С++ - возможно и прокатило-бы, но в С "глубоко" изучать попросту нечего - умели Люди делать инструмент в своё время.
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3321640#p3321640"]Задумку реализовать получилось, в качестве примера приведу фото дисплея с парочкой символов в оригинальном масштабе и в масштабе 7.5[/uquote]
Думаю не я один сейчас злорадно ухмыльнулся, зная как оно там у вас "оптимально" устроено, в желании задать вопрос: -"Кабы, барин, видео посмотреть. А фоточками сыт не будешь, вестимо."
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
И дописавВашу пару можно сократить до 1 байта, при таких условиях.
Код: Выделить всё
#pragma pack(1)
...
typedef struct
{
};
...
#pragma pack()И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
- Сообщения: 7
- Зарегистрирован: Пт мар 02, 2018 16:31:19
Уважаемые гуру!
Я прекрасно понимаю, что у меня дико криво реализован алгоритм хранения векторного шрифта, впрочем, как и его прорисовка. Я понимаю, что по хорошему пару координат нужно хранить в 1 байте. Но, мне крайне тяжело и долго нужно будет разбираться в том, как создать тип данных в виде структуры с динамическим массивом и этот тип назначить статическому массиву. Сама сложность для меня состоит в самом понимании где и когда нужно использовать указатель, выделять память, освобождать... При всем этом самого синтаксиса не знаю... Ну да ладно, будет время - разберемся. Правда в том, что действительно времени может и не быть, но возникнет необходимость.
По поводу видео: могу конечно записать, только что именно? пока у меня реализовано 25 символов и функция void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale), где C - индекс символа.
Добавлено after 11 minutes:
Решил все же показать код, только рассматривайте его как анекдот, не принимайте близко к сердцу =)
Так объявлен тип и переменная:
Так заполняется шрифт векторами:
А вот так отрисовывается символ:
Может найдется тот, кто сделает из этого конфетку...
Я прекрасно понимаю, что у меня дико криво реализован алгоритм хранения векторного шрифта, впрочем, как и его прорисовка. Я понимаю, что по хорошему пару координат нужно хранить в 1 байте. Но, мне крайне тяжело и долго нужно будет разбираться в том, как создать тип данных в виде структуры с динамическим массивом и этот тип назначить статическому массиву. Сама сложность для меня состоит в самом понимании где и когда нужно использовать указатель, выделять память, освобождать... При всем этом самого синтаксиса не знаю... Ну да ладно, будет время - разберемся. Правда в том, что действительно времени может и не быть, но возникнет необходимость.
По поводу видео: могу конечно записать, только что именно? пока у меня реализовано 25 символов и функция void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale), где C - индекс символа.
Добавлено after 11 minutes:
Решил все же показать код, только рассматривайте его как анекдот, не принимайте близко к сердцу =)
Так объявлен тип и переменная:
Код: Выделить всё
#pragma pack(1)
struct TFont {
char *Lines;
} Font[255] ;
#pragma pack()Код: Выделить всё
Font[48].Lines="010516364541301001|0541"; // 0
Font[49].Lines="112026|1636"; // 1
Font[50].Lines="01103041420646"; // 2
Font[51].Lines="0040224445361605"; // 3
Font[52].Lines="3630030444"; // 4
Font[53].Lines="400002324345361605"; // 5
Font[54].Lines="4130100105163645443303"; // 6
Font[55].Lines="0004412326"; // 7
Font[56].Lines="103041423344453616050413020110|1333"; // 8
Font[57].Lines="0516364541301001021343"; // 9Код: Выделить всё
void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale)
{
uint8_t i;
uint8_t xo=255;
uint8_t yo=255;
uint8_t xn=255;
uint8_t yn=255;
uint8_t n=0;
uint8_t nl=0; //new line
uint8_t k=48;
for(i=0; i<strlen(Font[C].Lines); i++)
{
if (Font[C].Lines[i]!="|"[0])
{
if (n%2==0) {xo=xn; xn=Font[C].Lines[i]; nl=0;}
if (n%2==1) {yo=yn; yn=Font[C].Lines[i]; nl=1;}
n++;
} else
{
xo=255;
yo=255;
xn=255;
yn=255;
nl=0;
}
if ((nl==1) && (xo<255) && (yo<255))
{
drawLine(X+xo*scale-k*scale,Y+yo*scale-k*scale,X+xn*scale-k*scale,Y+yn*scale-k*scale,Color565(255,255,255));
nl=0;
}
}
}- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
[uquote="da-nie",url="/forum/viewtopic.php?p=3321797#p3321797"]Иначе фокус может не получиться.
[/uquote]
Зачем паковать байт? Байт он всегда байт - как его ни пакуйте - а sizeof(t_point) в конкретном случае будет 1. Биты 0-2 отводятся под x, а 3-5 - под y. Биты-же 6,7 остаются неиспользуемы при любом раскладе кроме явного их указания в качестве поля(пары полей) размером 2 бита (либо по биту). Поле размером 3 бита займёт уже 0-2 биты следующего байта.
Для того-же, чтобы все биты лежали плотнячком - придется объявлять базовый тип поля пошире - т.е. unsigned short как минимум. Но, любителей накладывать такие "широкие" битовые маски на сырые данные прилетевшие из внешнего мира ждут некоторые сюрпризы - особенно на "остроконечниковых" (low endian) платформах. Да даже уже и в нашем примере пытливый глаз наверняка обнаружил некоторую странность - отчего-то "младшие" x,y лежат перед "старшим" z, не так-ли?
А вот вариант с short -ом:
Биты уплотнились как надо - но в байтовом массиве по прежнему "бардачат", а вот как unsigned short всё прекрасно - потому как собирал я этот примерчик на LE платформе.
Грустные выводы - не все возможные комбинации можно представить в битовых полях, а для low endian придётся порой ещё и байты в исходных данных переставлять (для кайловских ARM тулчейнов, кстати, есть интриниксы _REV16, _REV32)
Добавлено after 1 hour 11 minutes 1 second:
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3322007#p3322007"]Но, мне крайне тяжело и долго нужно будет разбираться в том, как создать тип данных в виде структуры с динамическим массивом и этот тип назначить статическому массиву.[/uquote]
С - это высокоуровневый ассемблер - понимая как компилятор с компоновщиком строят образ программы вы будет знать как работает железяка. Без всякой магии. Дело стоящее - не исключайте для себя такую возможность. :-D
Всё вышеприведенное объявляется в глобальной области (не в функциях!) - и вся работа будет сделана компилятором - функции DrawChar остаётся только воспользоваться уже набитым массивом данных. И не забудьте терминировать все данные символов байтом EOL - иначе оно отрисует вам содержимое всей памяти аж до случайно встреченного символа с установленным верхним битом. 
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3322007#p3322007"]По поводу видео: могу конечно записать, только что именно?[/uquote]
Не заморачивайтесь - подкалывал я вас. Скорость работы программы оценивается [тупым] юзером по времени отклика системы на его хотелки - и если шрифт рисуется с заметным анимационным эффектом - это медленная система с его [тупой] точки зрения. А если глаз не замечает - то и чёрт с ним - занимается ли там МК парсингом ваших строковых литералов на лету или просто хомячит инструкции в бесконечности главного цикла - всё едино лепота.
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3322007#p3322007"]Решил все же показать код, только рассматривайте его как анекдот, не принимайте близко к сердцу =)[/uquote]
Как по мне так это было правильное решение с вашей стороны.
Да, и ещё по описанию вектора отрисовки символа - идею с размещением х и y в полубайтах для большей наглядности вы поняли, кстати?
Зачем паковать байт? Байт он всегда байт - как его ни пакуйте - а sizeof(t_point) в конкретном случае будет 1. Биты 0-2 отводятся под x, а 3-5 - под y. Биты-же 6,7 остаются неиспользуемы при любом раскладе кроме явного их указания в качестве поля(пары полей) размером 2 бита (либо по биту). Поле размером 3 бита займёт уже 0-2 биты следующего байта.
Код: Выделить всё
struct t_point {
unsigned char x : 3;
unsigned char y : 3;
unsigned char z : 3;
};
unsigned char bb[2] = { 0 };
struct ccc* c = (struct ccc*)bb;
// содержимое bb -> 0х00, 0x00
c->x = 0x07; // содержимое bb -> 0х07, 0x00
c->y = 0x07; // содержимое bb -> 0х3F, 0x00
c->z = 0x07; // содержимое bb -> 0х3F, 0x07
А вот вариант с short -ом:
Код: Выделить всё
struct t_point {
unsigned short x : 3;
unsigned short y : 3;
unsigned short z : 3;
};
union uu {
unsigned char bb[2];
unsigned short s;
} u = { 0 };
struct sss* c = (struct sss*)&u;
// содержимое u.bb -> 0х00, 0x00, содержимое u.s -> 0х0000
c->x = 0x07; // содержимое u.bb -> 0х07, 0x00, содержимое u.s -> 0х0007
c->y = 0x07; // содержимое u.bb -> 0х3F, 0x00, содержимое u.s -> 0х003F
c->z = 0x07; // содержимое u.bb -> 0хFF, 0x01, содержимое u.s -> 0х01FF
Грустные выводы - не все возможные комбинации можно представить в битовых полях, а для low endian придётся порой ещё и байты в исходных данных переставлять (для кайловских ARM тулчейнов, кстати, есть интриниксы _REV16, _REV32)
Добавлено after 1 hour 11 minutes 1 second:
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3322007#p3322007"]Но, мне крайне тяжело и долго нужно будет разбираться в том, как создать тип данных в виде структуры с динамическим массивом и этот тип назначить статическому массиву.[/uquote]
С - это высокоуровневый ассемблер - понимая как компилятор с компоновщиком строят образ программы вы будет знать как работает железяка. Без всякой магии. Дело стоящее - не исключайте для себя такую возможность. :-D
Код: Выделить всё
typedef struct {
unsigned char x : 3; // 0x00 - 0x07
unsigned char brk : 1; // 0x08
unsigned char y : 3; // 0x00 - 0x70
unsigned char eol : 1; // 0x80
} t_point;
#define BRK 0x08
#define EOL 0x80
// [омномномном]
// Font[55].Lines="0004412326"; // 7
const t_point ch55[] = { 0x00, 0x04, 0x41, 0x23, 0x26, EOL } ; // 7
// Font[56].Lines="103041423344453616050413020110|1333"; // 8
const t_point ch56[] = { 0x10, 0x30, 0x41, 0x42, 0x33, 0x44, 0x45, 0x36, 0x16, 0x05, 0x04, 0x13, 0x02, 0x01, 0x10, BRK, 0x13, 0x33, EOL } ; // 8
// Font[57].Lines="0516364541301001021343"; // 9
const t_point ch57[] = { 0x05, 0x16, 0x36, 0x45, 0x41, 0x30, 0x10, 0x01, 0x02, 0x13, 0x43, EOL } ; // 9
// [омномномном]
const struct TFont {
const t_point *Line;
} Font[255] = {
ch00, ch01, ch02, и.т.д, и т.д..... , ch56, ch57,
};Код: Выделить всё
void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale)
{
t_point* p0 = NULL;
t_point* p = NULL;
for (p0 = Font[C].Line, p = Font[C].Line + 1; 0 == p->eol; p0 = p, p++) {
if (0 != p->brk )
continue;
drawLine( X + p0->x * scale - k * scale,
Y + p0->y * scale - k * scale,
X + p->x * scale - k * scale,
Y + p->y * scale - k * scale,
Color565(255, 255, 255));
}
}
Не заморачивайтесь - подкалывал я вас. Скорость работы программы оценивается [тупым] юзером по времени отклика системы на его хотелки - и если шрифт рисуется с заметным анимационным эффектом - это медленная система с его [тупой] точки зрения. А если глаз не замечает - то и чёрт с ним - занимается ли там МК парсингом ваших строковых литералов на лету или просто хомячит инструкции в бесконечности главного цикла - всё едино лепота.
[uquote="Shrike1987",url="/forum/viewtopic.php?p=3322007#p3322007"]Решил все же показать код, только рассматривайте его как анекдот, не принимайте близко к сердцу =)[/uquote]
Как по мне так это было правильное решение с вашей стороны.
Да, и ещё по описанию вектора отрисовки символа - идею с размещением х и y в полубайтах для большей наглядности вы поняли, кстати?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 


