|
Интересный глюк в CodeVisionAVR |
|
|
|
Apr 17 2008, 09:02
|

Частый гость
 
Группа: Свой
Сообщений: 120
Регистрация: 19-02-08
Пользователь №: 35 166

|
Обнаружил интересный глюк в CodeVision, целый день вчера просидел - думал во мне дело, оказалось, что нет. Если мы делаем сдвиг и результирующее число выходит из размера 1 байта, то, почему-то, компилятор не преобразует его к int (хотя обязан по стандарту). То есть вот такой код работает непрявильно: Код unisigned char s = 243; //... unsigned int d = (unsigned int)(s << 4); // d != 3888 а надо так делать, что глупо... Код unisigned char s = 243; //... unsigned int d = (unsigned int)(((unsigned int)s) << 4); // d = 3888 Интересно, зачем это надо или это просто баг??..
--------------------
Все будет хорошо! Я проверял!
|
|
|
|
|
Apr 17 2008, 09:17
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Да, выходит, это еще одно несоответствие стандарту этого компилятора. Можно написать проще: Код unsigned int d = (unsigned int)s << 4;
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 17 2008, 10:31
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(DMD @ Apr 17 2008, 16:02)  Обнаружил интересный глюк в CodeVision, целый день вчера просидел - думал во мне дело, оказалось, что нет. Код unisigned char s = 243; //... unsigned int d = (unsigned int)(s << 4); // d != 3888 А по моему - все правилно делает компилятор: 1. Выполняется выражение в скобках - 8-бит переменная сдвигается на четыре бита влево 2. Результат преобразуется к беззнаковому целому. А вот так: Код unisigned char s = 243; //... unsigned int d = (unsigned int)(((unsigned int)s) << 4); // d = 3888 1. Выполняется выражение во внутренних скобках - s преобразуется к беззнаковому целому. 2. Выполняется выражение во внешних скобках - 16-бит беззнаковое целое сдвигается на четыре бита влево 3. Результат преобразуется к беззнаковому целому Все правильно
--------------------
|
|
|
|
|
Apr 17 2008, 11:20
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(prottoss @ Apr 17 2008, 13:31)  А по моему - все правилно делает компилятор: "По-вашему" - вполне вероятно. Но по стандарту должно быть иначе: Цитата 6.3.1 Arithmetic operands 6.3.1.1 Boolean, characters, and integers .... 2 The following may be used in an expression wherever an int or unsigned int may be used: — An object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int. — A bit-field of type _Bool, int, signed int,or unsigned int. If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions. И раз есть отличие от стандарта, то оно должно быть явно указано в документации (например, в документации на микрочиповский C18 такое описание есть). А если в документации оно не упомянуто, то, извините, или бага или этот компилятор не может называться "компилятором языка высокого уровня С"
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 17 2008, 12:33
|

Знающий
   
Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768

|
Цитата(DMD @ Apr 17 2008, 13:02)  Обнаружил интересный глюк в CodeVision, целый день вчера просидел - думал во мне дело, оказалось, что нет. Если мы делаем сдвиг и результирующее число выходит из размера 1 байта, то, почему-то, компилятор не преобразует его к int (хотя обязан по стандарту). То есть вот такой код работает непрявильно: Код unisigned char s = 243; //... unsigned int d = (unsigned int)(s << 4); // d != 3888 Никогда бы и в голову не прошло так приводить типы,естесвенней и проше как написал Сергей. И насчет компилятора-все-ж написано чистым английским языком: it is important to note that if the Project|Configure|C Compiler|Code Generation|Promote char to int option isn't checked or the #pragma promotechar+ isn't used, the char, respectively unsigned char, type operands are not automatically promoted to int , respectively unsigned int, as in compilers targeted for 16 or 32 bit CPUs. This helps writing more size and speed efficient code for an 8 bit CPU like the AVR. To prevent overflow on 8 bit addition or multiplication, casting may be required. The compiler issues warnings in these situations. Варнинги то хоть генерились,или они подавлены?
--------------------
"Hello, word!" - 17 errors 56 warnings
|
|
|
|
|
Apr 18 2008, 02:01
|
Участник

Группа: Свой
Сообщений: 37
Регистрация: 13-05-07
Из: Minsk, Belarus
Пользователь №: 27 694

|
Цитата(Сергей Борщ @ Apr 17 2008, 14:20)  или этот компилятор не может называться "компилятором языка высокого уровня С" А он и так не является компилятором C. В C нет возможности писать вещи вроде PORTA.0=1, нет конструкции interrupt[wtf] и ещё много чего. Даже в C99. Поэтому только avr-gcc. -- WBR, Andrew
|
|
|
|
|
Dec 2 2008, 15:52
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Выбрось каку  Прошу не пинать -- прошелся поиском по сайту и нашел сто-0-олько тем про глюконат-кодевижина, что прям ой! Вобщем, пощщу (от сл. "постить") в первый попавшийся топик по глюкам. Сегодня приспичило меня поднять старые исходники, которые я еще писал в CodeVision в хз каком мохнатом году... Думал, закопипащщу (опять, гы-гы) текст в ИАР, подправлю где надо порты/регистры и вперед! Тема-то изъезженная вдоль и поперек -- подключение текстового LCD. Чего тут думать-то!? Ан, нет! Старые грабли с новыми ручкам... Короче, IAR обнаружил ошибку на выходе из функции. Стыдно признаться, но это так, -- моя невнимательность. Но меня другое плющит -- Codevision эту ошибку в упор не видит. Пф-ф! Вот код функции (слегка урезанный): Код // // Перевод кодировки Win-1251 в LDC-кодировку // BYTE _Translate(BYTE data) { switch (data) { case 'Ё': return 0xA2; case 'ё': ... case '№': return 0xCC; case '\\': return 0xFF; }
if (data >= 0xC0) return rus[data - 0xC0]; } Для молодых поэтов поясняю -- собака порылась в последнем операторе if. Вопрос: что будет, если data будет меньше 0xC0? Какой код вернет функция? Правльный выход из функции должен быть, разумеется, такой: Код ... if (data >= 0xC0) return rus[data - 0xC0]; else return data; } (Может кому пригодится. Хех!)
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 3 2008, 00:15
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Apr 17 2008, 11:17)  Можно написать проще: Код unsigned int d = (unsigned int)s << 4; Можно написать еще проще Код unsigned int d = s << 4; зачем делать приведение типа в правой части, если в левой части и так unsigned int. к тому же Цитата Все операнды типа unsigned char или unsigned short преобразуются в тип unsigned int. Цитата(zhevak @ Dec 2 2008, 17:52)  разумеется, такой: Неочевидно, потому что ваш пример вообще неоткомилируется, неизвестно что такое rus  Очень странно как вы использовали этот код и не наткнулись на проблему раньше, ведь 3/4 символов, в т.ч. и цифры, были недоступными! По теме CV согласен - фтопку этот недоинструмент.
|
|
|
|
|
Dec 3 2008, 01:58
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(defunct @ Dec 3 2008, 02:15)  Можно написать еще проще Код unsigned int d = s << 4; зачем делать приведение типа в правой части, если в левой части и так unsigned int. Если опустить integer promotion rules, которые CV не соблюдает, то в остальном в этом выражении он действует по стандарту: сначала вычисляется правая часть, потом ее результат приводится к левой части. То, что вы написали другими словами можно представить примерно так: Цитата Код unsigned int s = 0x1234; unsigned long d = s << 4; зачем делать приведение типа в правой части, если в левой части и так unsigned long. Цитата(zhevak @ Dec 2 2008, 17:52)  Но меня другое плющит -- Codevision эту ошибку в упор не видит. Пф-ф! gcc без -Wall тоже пропускает такое. В свое время тоже был удивлен, когда старые проекты, писаные в оболочке Dev-C++ стал собирать со своим рукописным makefile. Тоже решил тогда для себя "нафиг оболочку, теперь makefiles только руками". А с -Wall gcc выдает не ошибку, а предупреждение.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 3 2008, 06:15
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 17-04-08
Пользователь №: 36 850

|
Цитата(zhevak @ Dec 2 2008, 17:52)  Вопрос: что будет, если data будет меньше 0xC0? Какой код вернет функция? Все зависит от того, что вы выкинули заменив точечками в switch'e возможно за этот if управление даже не выйдет. Кстати, насколько я припоминаю, у КодеВижена есть настройка какие варнинги выводить, а какие нет. Надо там глянуть не отключены ли.
|
|
|
|
|
Dec 3 2008, 11:48
|

Частый гость
 
Группа: Свой
Сообщений: 176
Регистрация: 2-04-08
Из: Днепропетровск
Пользователь №: 36 406

|
Цитата(ReAl @ Apr 18 2008, 16:50)  Уже обсуждалось. "Выбрось каку". Кака, конечно. Но если бы в IAR C было также просто вставлять ассемблерный код в текс программы как это сделано в CvAVR...
--------------------
Ребята, как же это вы без гравицапы пепелац выкатываете из гаража? Это непорядок. ©
|
|
|
|
|
Dec 3 2008, 21:26
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата defunct[/b]' date='Dec 3 2008, 05:15' post='510351'] Неочевидно, потому что ваш пример вообще неоткомилируется, неизвестно что такое rus  (1) Очень странно как вы использовали этот код и не наткнулись на проблему раньше, ведь 3/4 символов, в т.ч. и цифры, были недоступными! (2) 1. Извините, это моя ошибка. Я описывал проблему выхода из функции и не подумал, что людей могут заинтересовать совсем другие вопросы. Вы правы, конечно этот код в таком виде не откомпилируется! Ладно, попробую ответить на ваш вопрос. Начну с проблемы LCD, поскольку, у человека, который их ни разу не использовал возникают непонятки. У всех символьных LCD имеется встроенный знакогенератор (ну как минимум мне еще не попадались симольные LCD без оного). Младшая половина знакогенератора соответствует кодам ASCII. Проблемы заложены в старшей половине. Если у вас НЕ руссифицированный LCD, то, собственно, проблемы нет, т.к. в знакогенераторе кирилицы -- нет. Если LCD руссифицированный, то возникает проблема кодировки. Дело в том, что эта кодировка не совпадает ни с 866, ни с 1251. Я так понимаю, что производитель экономил память -- там, где изображение кириллических символов совпадает с изображением латинских символов, кириллические символы выкидывались. Например, кириллическая буква Р и латинская P, О и О, Н и Н, ну и т.д. Т.е. половина кириллического алфавита оказалась расположена в латинском. Понятно, что кодировка получилась весьма веселая. С другой стороны, поскольку мы все пишем свои проги под Виндой, то стринги в исходниках тоже имеют виндовую кодировку. Теперь если прогу откомпилировать и залить в МК, то на LCD русские сообщения исказятся до неузнаваемости. Стало быть нужно произвести перекодировку. Это можно сделать либо до компиляции, либо во время исполнения проги в МК. Поскольку, объем флешь-памяти меня не напрягал, а вывод текстовой инфы на LCD занимает очень незначительное время, я решил незаморачиваться с перекодировкой до компиляции, а выполнять ее во время вывода строк. Тем более, что в проектах могут встретиться задачи, где стринг может прийти извне, например по RS232. Соответственно во флешь-памяти МК располагалась таблица перекодировок. Имя этой таблицы -- rus. Функция перекодировки называлась translate. Мне показалось, что это очевидные вещи, и я поэтому не стал особо заострять на этом внимание. Надеюсь, что я ответил на Ваш первый вопрос. 2. Вопрос будет посложнее. Если честно, то ахренегознаеттоваришмайор! Я могу только предполагать, что это особенность CV. Т.е. переменная data и результат функции раполагались в одном и том же регистре. Иначе говоря, если "насильственной" перекодировки не происходило, то функция возвращала то, что получала в качестве аргумента. Еще раз повторю -- то, что я описал, такой код должен быть приравнен к ошибке. Компилятор пропустил. В моем случае, это не имело ни каких последствий (кроме, разве что, моего запоздалого испуга). 2 Nick_Shl Я обычно поднимаю все флаги на ошибки и предупреждения.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 3 2008, 23:53
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Сергей Борщ @ Dec 3 2008, 17:35)  Тогда вам в gcc. Такого шикарного инлайн-асма в других компиляторах не встречалось. Вставленный код не мешает оптимизатору, компилятор сам решает, в каких регистрах удобнее передать параметры в ваш ассемблерный кусок... Конфетка! Не знаю как CV, но ИАР встретив в функции инлайн-асм складывает крылья и выключает оптимизатор (где-то в описании было). А я не испытал серьёзных неудобств с асмовыми вставками в IARе. (Дальнейшее к Вам Сергей не относится, так как Вы всё это знаете лучше меня, это больше для delamoure и других, выбирающих инструмент) Начнём с того, что IAR позволяет использовать inline ассемблер. В том числе и с многострочными конструкциями. Во-вторых он позволяет писать на ассемблере законченные процедуры и подключать на этапе линковки. Это на мой взгляд намного правильнее и логичнее. Прога получается значительно нагляднее и завершённее. Использование регистров компилятором детально описано, и при таком варианте я не заметил ухудшения работы оптимизатора. (А inline ассемблер не применял, по причине вышеописанной) Во втором варианте возможно использовать общие символические имена. Причём я работал со структурами, массивами, флагами именно с символьными именами. Несколько напрягает в IARе перевод всех символьных имён в регистры и константы десятичные. И это перед выдачей листинга. Ну например исходный текст int i=1234; В распечатке асмового листинга мы увидим что-то типа ldi r26,210 ldi r27,4 Я бы предпочёл увидеть что-нибудь типа ldi R26,low(1234) ldi R27,high(1234) Аналогично и с именами символическими. Хотя наверное это брюзжание.
|
|
|
|
|
Dec 4 2008, 00:52
|

Частый гость
 
Группа: Свой
Сообщений: 176
Регистрация: 2-04-08
Из: Днепропетровск
Пользователь №: 36 406

|
Впрочем, IAR для меня не новость  "Многострочные конструкции inline ассемблера" вызывают оторопь: "where \n (new line) separates each new assembler instruction". И это удобно? На этапе линковки свой ассемблерный код не подключал. Коллега мне демонстрировал как это делается еще года 3 назад. Также способ описан в инете, по-моему, кем-то из местных (Сергеем Борщом?). Показалось неудобно, долго. Когда код писать? Тут целый обряд с бубном протанцевать необходимо.
--------------------
Ребята, как же это вы без гравицапы пепелац выкатываете из гаража? Это непорядок. ©
|
|
|
|
|
Dec 4 2008, 04:57
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(SasaVitebsk @ Dec 4 2008, 02:53)  Во-вторых он позволяет писать на ассемблере законченные процедуры и подключать на этапе линковки. Это на мой взгляд намного правильнее и логичнее. Это очень спорный момент. Ассемблерные вставки обычно делаются для повышения быстродействия. Использование написанных на ассемблере законченных процедур однозначно порушит стратегию оптимизатора и вместо выигрыша по времени можно получить проигрыш. Особенно если ассемблерная функция маленькая и быстрая. Тут может быть и большой оверхед - регистровые переменные в стек, рабочие копии обычных сохранить по "месту прописки". По выходу из ассемблерной функции все проделать в обратном порядке. А ведь бедный ИАР не знает, что в этой внешней процедуре происходит с регистрами, вот и сохранит по максимуму. У GCC видимо при такой методике включения S файлов должны быть похожие трудности. А вот инлайн ассемблер у GCC выше всяких похвал. Именно его использование и позволяет достичь максимального быстродействия - в этом случае накладных расходов или вообще нет, или они малы. А в отдельных файлах удобно обработчики прерываний делать.
|
|
|
|
|
Dec 4 2008, 08:20
|

Знающий
   
Группа: Свой
Сообщений: 966
Регистрация: 27-05-06
Из: СПб
Пользователь №: 17 499

|
Цитата(_Pasha @ Dec 3 2008, 17:22)  Интересно, какие грабельки еще подкинет 16-битная недо-арифметика  А вот я уже привык  ибо влом перелопачивать старые проекты под gcc... CV всегда под рукой... просто надо знать в каких случаях если справа у одного из операндов стоит младший тип и производится умножение/сложение/сдвиг что будет с результом ... например умножать char на int некорректно, а наоборот- можно  но вообще-то всегда варнинги генерятся их надо внимательно читать и все будет ок.
|
|
|
|
|
Dec 4 2008, 09:36
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(SasaVitebsk @ Dec 4 2008, 01:53)  А я не испытал серьёзных неудобств с асмовыми вставками в IARе. .... (А inline ассемблер не применял, по причине вышеописанной)  "Асмовые вставки" == inline assembler. Они, как правильно заметил Qwertty, хороши именно тем, что не надо тратить время на сохранение регистров и вызов функции. При этом gcc позволяет в такой вставке сделать все, что угодно, а ИАР в документации честно пишет: Цитата Inline assembler sequences have no well-defined interface with the surrounding code generated from your C or C++ code. This makes the inline assembler code fragile, and will possibly also become a maintenance problem if you upgrade the compiler in the future. ... Inline assembler is therefore often best avoided. If there is no suitable intrinsic function available, we recommend the use of modules written in assembler language instead of inline assembler, because the function call to an assembler routine normally causes less performance reduction.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 4 2008, 10:25
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(ARV @ Dec 4 2008, 14:51)  а как можно преобразовать строки для вывода на LCD на этапе компиляции? так, чтобы в исходном тексте они были в первозданном виде, а в объектном файле - уже перекодированные? понимаю, что надо как-то влезть в последовательность работы препроцессора, но как? Я не совсем точно выразился. Имел ввиду, что у программы (в общем смыле) имеются несколько этапов жизни (или как это правильно сказать?). Этап разработки, написания теста, компиляция -- это все есть первый этап. Второй этап -- это, собственно, работа бинарного модуля в изделии, ран-тайм. Первый этап я условно назвал -- "на этапе компиляции". Что, видимо, и внесло путаницу в понимание. На самом деле, вряд-ли кто осмелиться "отхачить" компилятор так чтобы тот "на этапе компиляции" (в буквальном смысле) конвертировал кодировку стрингов. Мою фразу "преобразовать строки для вывода на LCD на этапе компиляции" следует понимать так: на этапе написания исходных текстов вы должны стринги набирать как они есть -- в Виндовой кодировке. Вы ведь все равно будете компилировать прогу не один раз, пока не исправите все ошибки. И вам, скорее всего, понадобится видеть читаемые строки. А когда ошибки будут устранены (т.е. перед окончательной (последней) компиляцией, сборкой), вы должны или руками, или с помощью самопальной проги-конвертора, найти стринги и заменить в них символы на нужную кодировку. Когда стрингов не так много, это быстрее сделать руками по табличке-шпаргалке. Когда же проект достаточно большой и развесистый, то проще написать утилиту, которая будет выискивать в тексте скармливаемых ей файлов стринги и заменять в них байты. Кроме того, надо учитывать, что конвертации могут подвергаться не только стринги, а и одиночные символы. Т.е. проблема еще та! ЗЫ 1. Сергей Борщ немного раньше ответил. 2. Еще раз хочу напомнить, что стринги и символы могут приходить из внешнего мира. Т.е. задачу перекодировки удобнее решать на этапе ран-тайм, непосредственно в драйвере LCD. В этом случае вообще никаких проблем не будет. Единственная неудобство -- это незначительное снижение быстродействия при выводе и небольшое увеличение кода программы. Но поскольку, доля времени на перекодировку соизмерима или даже меньше, чем время на дергание лапок у LCD, а поток выводимой на LCD информации вообще никакой, то практически перекодировка в режиме ран-тайм не оказывает никакого торможения.
Сообщение отредактировал zhevak - Dec 4 2008, 10:37
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 4 2008, 10:26
|
Частый гость
 
Группа: Участник
Сообщений: 127
Регистрация: 18-10-06
Пользователь №: 21 418

|
Цитата(zhevak @ Dec 4 2008, 01:26)  Если LCD руссифицированный, то возникает проблема кодировки. Дело в том, что эта кодировка не совпадает ни с 866, ни с 1251. Я так понимаю, что производитель экономил память -- там, где изображение кириллических символов совпадает с изображением латинских символов, кириллические символы выкидывались. Например, кириллическая буква Р и латинская P, О и О, Н и Н, ну и т.д. Т.е. половина кириллического алфавита оказалась расположена в латинском. Понятно, что кодировка получилась весьма веселая. Существуют индикаторы с 1251 кодировкой (как одной из возможных). Делает фирма МЭЛТ.
|
|
|
|
|
Dec 4 2008, 10:47
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(LordVader @ Dec 4 2008, 15:26)  Существуют индикаторы с 1251 кодировкой (как одной из возможных). Делает фирма МЭЛТ.
да. Спасибо. Я вам больше скажу -- в мире существуют LCD с SPI интерфейсом... правда я их как-то не видел в продаже. Давайте сойдемся на том, что все это из разряда экзотики. В магазинах в основном продают LCD с "компактной" кодировкой и с традиционным интерфейсом.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 4 2008, 18:22
|
Частый гость
 
Группа: Участник
Сообщений: 127
Регистрация: 18-10-06
Пользователь №: 21 418

|
Цитата(zhevak @ Dec 4 2008, 13:47)  Я вам больше скажу -- в мире существуют LCD с SPI интерфейсом... правда я их как-то не видел в продаже. Давайте сойдемся на том, что все это из разряда экзотики. В магазинах в основном продают LCD с "компактной" кодировкой и с традиционным интерфейсом. Ну не знаю. В пределах 'глобуса москвы' купить мэлтовские - не проблема. И даже тут есть http://www.terraelectronica.ru/catalog.php...e=2&PageS=1У них 2 странички кодировки - одна какая на картинке, другая непойми какая, видимо как раз та, о которой вы говорили. По дефолту включена она же.
|
|
|
|
|
Dec 4 2008, 19:15
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(LordVader @ Dec 4 2008, 23:22)  Ну не знаю. В пределах 'глобуса москвы' купить мэлтовские - не проблема. И даже тут есть http://www.terraelectronica.ru/catalog.php...e=2&PageS=1У них 2 странички кодировки - одна какая на картинке, другая непойми какая, видимо как раз та, о которой вы говорили. По дефолту включена она же. все хорошо, но ведь не все живут в пределах Московского глобуса. Имея большое желание получить себе на стол "экзотику", согласитесь, за ценой и временем можно не следить. Только почему-то в жизни часто получается так, что мы выбираем то, что легче достать, а потом это подгоняем напильниками. Мы рукастые, не ленивые, да и копейку умеем считать. Поэтому вопрос бы и не возникал, если бы у нас были МЭЛТы в магазинах. А если еще по конкурентноспособной цене, да с кодировкой 1251 ... ха-ха-ха! Есть реальная жизнь, и есть понятие "как надо жить". Это разные вещи, и очень часто они не совпадают. Поэтому, простите, живем, как умеем! // Не обижайтесь! :-/ Это правда. (С) С легим паром!
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 4 2008, 20:56
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Стоимость LCD от 3.5$ за 2х16 до 11 за 4х20. Думаю экзотика в виде SPI LCD будет на 1$ дороже (За счёт экзотичности). Таким образом применив ATMega8, к примеру, и зашив там свою кодовую таблицу (Или несколько) вы можете получить за теже деньги LCD модуль с любым интерфейсом. SPI,I2C,RS232. Если туда добавить клаву, звук, светодиоды, то вообще такой законченный переферийный модуль будет себя оправдывать. Остаётся вопрос конструкции.  По поводу ASM вставок. Как то не совсем себе представляю ASM текст прямо по тексту Си программы. Если это работа с оборудованием, то как правило IAR её делает не хуже, а если просто прога, то смутно себе представляю. С другой стороны вызов законченной процедуры вполне уместен и не портит картину. Ну или там прерывание полностью на ASMе. Это я понимаю. Это как раз делается легко на IAR и просто. Какие сложности? Просто берёшь и пишешь отдельным файлом все свои процедуры ASM. Никакого гимора нет. Ну и включаешь в проект общий, да и всё! Никаких дополнительных танцев с бубном не надо.
|
|
|
|
|
Dec 4 2008, 21:25
|

Частый гость
 
Группа: Свой
Сообщений: 176
Регистрация: 2-04-08
Из: Днепропетровск
Пользователь №: 36 406

|
Цитата(SasaVitebsk @ Dec 4 2008, 22:56)  По поводу ASM вставок. Как то не совсем себе представляю ASM текст прямо по тексту Си программы. Если это работа с оборудованием, то как правило IAR её делает не хуже, а если просто прога, то смутно себе представляю. С другой стороны вызов законченной процедуры вполне уместен и не портит картину. Ну или там прерывание полностью на ASMе. Это я понимаю. Это как раз делается легко на IAR и просто.
Какие сложности? Просто берёшь и пишешь отдельным файлом все свои процедуры ASM. Никакого гимора нет. Ну и включаешь в проект общий, да и всё! Никаких дополнительных танцев с бубном не надо. Если действительно "прямо по тексту" я тоже смысла не вижу. А обработчики прерываний пишу очень часто целиком на асме. В CodeVision ставишь себе pragma savereg- и - вперед. В IAR буду разбираться, пробовать. Настал момент смены компилятора. С переходом на CodeVision2 старые проекты без переработок не компилируются.
--------------------
Ребята, как же это вы без гравицапы пепелац выкатываете из гаража? Это непорядок. ©
|
|
|
|
|
Dec 4 2008, 23:39
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(delamoure @ Dec 5 2008, 01:25)  В CodeVision ставишь себе pragma savereg- и - вперед. В IAR буду разбираться, пробовать. Настал момент смены компилятора. С переходом на CodeVision2 старые проекты без переработок не компилируются. А в IAR и pragma никакая не нужна. Просто создаёшь отдельный файл с расширением ASM, пишешь в нём свою прогу, с синтаксисом ASM, и подключаешь его к проекту. Ключевые слова ассемблера IAR не критично отличаются от стандартного набора. Я бы даже сказал, что он "более стандартен", чем ассемблер AVR Studio. Есть доки. В том числе и дока по переходу со студии на IAR ASM. К слову сказать документ простой, так как различий практически нет. Если есть какие вопросы - задавай. Много кто ответит. Вот попытался резануть кусочек для примера:  Код PUBLIC crc8
#define crc r10 #define data485 r16
RSEG CODE
// Расчёт CRC // r10 - crc485, 16 - data, портятся r17,r18,r19 crc8: ldi r17,8 // mov r12,data485 ldi r18,0x18 cCRC8: mov r19,crc eor r19,data485 lsr r19 // Сдвинули бит в С brcc nCRC8 eor crc,r18 nCRC8: ror crc lsr data485 dec r17 brne cCRC8 ret
END Соответственно в Си проге я её могу вызвать следующим образом Код __regvar __no_init uint8_t crc @10; ....
crc8(ADDR_DEFAULT); // Подсчитать crc Может это и не характерный пример. Дело в том, что это кусок вырезанный из бутлоадера для меги 8. Для уменьшения размера кода пришлось запретить компилятору использовать несколько регистров (в том числе R10 как вы видите) и разместить там переменные, обращение к которым является найболее частым. В результате в 2к влез бутлоадер с WakeUp протоколом с шифрованием 128 битным ключём. С выдачей полной информации по кристаллу, изделию, фирмваре и хардваре. Ну и некоторый другой сервис. Пришлось дешифрацию и некоторые распространённые процедуры (типа crc) написать на ASM. Очень доволен результатом.
|
|
|
|
|
Dec 5 2008, 02:41
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(SasaVitebsk @ Dec 4 2008, 22:56)  По поводу ASM вставок. Как то не совсем себе представляю ASM текст прямо по тексту Си программы. Иногда бывает полезно: Код //Нету у arm-???-gcc intrinsic-функций для запрета/разрешения прерываний. Пишем inline-функцию доступа к регистру состояния процессора. Точно такие же intinsic-и намертво вшиты в ИАР для ARM : INLINE inline TStatusReg __get_CPSR() { TStatusReg cpsr; asm volatile ( " MRS %0,CPSR \r\n" :"=r"(cpsr) : ); return cpsr; } INLINE inline void __set_CPSR_c(TStatusReg cpsr) { asm volatile ( " MSR CPSR_c, %0 \r\n" : :"r"(cpsr) ); }
// Загрузчик для msp430. Объем критичен. На С короче не получится: inline uint16_t CRC_XMODEM(uint16_t crc, uint8_t byte) { static const uint16_t CRC_POLYNOME = 0x8408;
asm volatile( "\r\n" " XOR %1, %0 \r\n" "1: \r\n" " RRA %2 \r\n" " JNC 2f \r\n" " XOR %3, %2 \r\n" "2: \r\n" " DEC %4 \r\n" " JNE 1b \r\n" :"=r"(crc) :"r"(byte), "0"(crc), "i"((uint16_t)CRC_POLYNOME), "r"((uint8_t)8) ); /* crc ^= byte; uint8_t i = 8; do { if (crc & 0x01) { crc >>= 1; crc ^= CRC_POLYNOME; } else crc >>= 1; } while(--i); */ return crc; }
// Есть у меня в области загрузчика AVR функции, написанные на ИАРе. Они хотят параметр в R16. А gcc передает его в R24. Пишем обертку: inline static void SynthInit(uint16_t FrequencyCoeff) { register uint16_t Tmp asm("r16"); Tmp = FrequencyCoeff; asm volatile ( " .extern SynthInit_driver \n\t" " RCALL SynthInit_driver \n\t" :"=r" (Tmp) :"r" (Tmp) ); }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 5 2008, 11:06
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(ARV @ Dec 4 2008, 12:19)  это очевидный способ, просто я почему-то думал, что существует более простой  типа макросов каких-нибудь или binutils готовых... pyLCDstringby bialix aka Александр Бельченко В проект включается файл messages.lcd и правило нужное в makefile - и жизнь прекрасна Что-то в духе. Код PYLCD := c:/bin/pylcdstr/pylcdstr
%.c : %.lcd echo ==== Converting $< to source files; \ $(PYLCD) $<
%.h : %.lcd echo ==== Converting $< to source files; \ $(PYLCD) $<
messages.c : messages.lcd messages.h : messages.lcd Широкие возможности по управлению формированием выходных строк и перекодировоками.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|