Например TDA7294

Форум РадиоКот • Просмотр темы - CodeVision AVR в вопросах и ответах
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пн сен 08, 2025 00:09:02

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 8295 ]     ... , , , 348, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Вт ноя 24, 2015 21:40:22 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4573
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
COKPOWEHEU писал(а):
А разве сработает?
Сработает.
Выделится в памяти константный массив символов (строка) и присвоится на неё указатель.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Вт ноя 24, 2015 23:29:52 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Ладно, поверю вам на слово (проверить пока неначем). Но обращение к массиву в любом случае быстрее, чем к указателю, да и надежнее явно определять тип:
Код:
volatile char p[]="AAA";
 PORTB = p[1];
  4e:   80 91 63 00     lds     r24, 0x0063
  52:   88 bb           out     0x18, r24       ; 24

Код:
volatile char *p="AAA";
  PORTB = p[1];
  4e:   e0 91 62 00     lds     r30, 0x0062
  52:   f0 91 63 00     lds     r31, 0x0063
  56:   81 81           ldd     r24, Z+1        ; 0x01
  58:   88 bb           out     0x18, r24       ; 24


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Ср ноя 25, 2015 17:49:25 
Мучитель микросхем

Карма: 3
Рейтинг сообщений: 44
Зарегистрирован: Вс авг 30, 2015 03:52:59
Сообщений: 469
Рейтинг сообщения: 0
COKPOWEHEU писал(а):
Указатель не выделяет себе память при создании.
А если прочитать данный пример повнимательнее? Или еще лучше - почитать букварь?
COKPOWEHEU писал(а):
обращение к массиву в любом случае быстрее, чем к указателю
Во-первых, не в любом случае, а во-вторых - было явно указано: "Иногда и так бывает полезно. Хотя, это не общий случай.". Читайте внимательно прежде чем делать категоричные заявления.
COKPOWEHEU писал(а):
да и надежнее явно определять тип:
А где в примере было неявное определение типа?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Чт ноя 26, 2015 07:58:10 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4573
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
COKPOWEHEU писал(а):
Но обращение к массиву в любом случае быстрее, чем к указателю, да и надежнее явно определять тип:

Это, всего-лишь потому, что p[] - указаеть-константа, адрес которой известен компилятору, а *p - указатель-переменная, из которой нужно ещё забрать адрес.
Тут сравнение немного неуместно, это совсем разные вещи. Через указатели обращение всегда занимает больше ресурсов, чем напрямую к переменной.
Попробуйте подкинуть массиву переменный индекс, и у Вас код также развернётся в более чем 2 инструкции. В этом случае, обращение будет практически эквивалентно обращению через указатель.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Чт ноя 26, 2015 16:25:34 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Pnjom-Penb писал(а):
Во-первых, не в любом случае, а во-вторых - было явно указано: "Иногда и так бывает полезно. Хотя, это не общий случай.". Читайте внимательно прежде чем делать категоричные заявления.
Хотелось бы не голословные ругательства, а конкретные примеры.
Пример, при котором обращение к данным по указателю, объявленному вашим способом (не к абстрактному, а именно *p="AAA") быстрее, чем к массиву.
Пример, при котором такое объявление удобнее. Мне в голову приходит только вариант, когда указатель потом меняется, но тогда доступ к прежним данным будет потерян.
Pnjom-Penb писал(а):
А где в примере было неявное определение типа?
Указатель вместо массива, очевидно.
Аlex писал(а):
Попробуйте подкинуть массиву переменный индекс, и у Вас код также развернётся в более чем 2 инструкции. В этом случае, обращение будет практически эквивалентно обращению через указатель.
Проверил:
Код:
volatile char *p="AAA";
volatile char str[]="BBB";
char i = PINB;
  4e:   86 b3           in      r24, 0x16       ; 22
PORTC = p[i];
  5c:   99 27           eor     r25, r25
  5e:   87 fd           sbrc    r24, 7
  60:   90 95           com     r25
  62:   e0 91 64 00     lds     r30, 0x0064
  66:   f0 91 65 00     lds     r31, 0x0065
  6a:   e8 0f           add     r30, r24
  6c:   f9 1f           adc     r31, r25
  6e:   20 81           ld      r18, Z
  70:   25 bb           out     0x15, r18       ; 21
DDRC = str[i];
  68:   ff 27           eor     r31, r31 //при другой компиляции, переменная i оказалась не в r24, а в r30
  6a:   e7 fd           sbrc    r30, 7
  6c:   f0 95           com     r31
  6e:   e0 5a           subi    r30, 0xA0       ; 160
  70:   ff 4f           sbci    r31, 0xFF       ; 255
  72:   80 81           ld      r24, Z
  74:   84 bb           out     0x14, r24       ; 20

Как и следовало ожидать - обращение к массиву быстрее, чем к указателю, даже с переменным индексом. Единственное, если обращаться к указателю, как к указателю, это будет короче. Вот только к данной записи это отношения не имеет.
Код:
PORTC = *p;
  5c:   a0 91 64 00     lds     r26, 0x0064
  60:   b0 91 65 00     lds     r27, 0x0065
  64:   8c 91           ld      r24, X
  66:   85 bb           out     0x15, r24       ; 21


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Чт ноя 26, 2015 21:50:15 
Мучитель микросхем

Карма: 3
Рейтинг сообщений: 44
Зарегистрирован: Вс авг 30, 2015 03:52:59
Сообщений: 469
Рейтинг сообщения: 0
COKPOWEHEU, один из вариантов (пример) был приведен еще до вашего поста. Впрочем, если использование указателя воспринимается вами, как неявное определение типа, то ни о каких примерах и говорить не следует. Попросту рано.
Это следовало еще из "указатель не выделяет себе память при создании", зря я тогда понадеялся. :dont_know:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Чт ноя 26, 2015 22:35:49 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Про "указатель не выделяет памяти" я и написал, что поверю на слово. Если ошибаюсь с механизмом, поправьте. Запись char *p="ABC"; выделяет в ОЗУ 4 байта со значениями 'A', 'B', 'C', '\0', но создает туда не постоянную ссылку (как при объявлении массива), а только переменную, p.
Поэтому массив (строку) и стоит объявлять как массив, а не как указатель. Его нельзя переназначить, то есть на случайное присвоение компилятор уже будет ругаться и мешать потерять единственную ссылку на данные. Ну и скорость обращения к данным в массива больше.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Чт ноя 26, 2015 22:45:53 
Мучитель микросхем

Карма: 3
Рейтинг сообщений: 44
Зарегистрирован: Вс авг 30, 2015 03:52:59
Сообщений: 469
Рейтинг сообщения: 0
COKPOWEHEU писал(а):
Поэтому массив (строку) и стоит объявлять как массив, а не как указатель.
Вот так вот, независимо ни от чего? :)))
Цитата:
Вроде не бездельники
И могли бы жить,
Им бы указатели
Взять и отменить...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Чт ноя 26, 2015 23:02:52 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Особые извращенцы могут и вручную адреса считать, как на ассемблере. Но какой смысл, если для стандартных задач в языке есть стандартные решения. Если считаете иначе - попробуйте все-таки аргументировать свою позицию, а не просто пытаться поймать меня на незнании предмета.
Есть примеры, при котором выгоднее объявлять массив указателем-переменной?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 02:11:15 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4573
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
COKPOWEHEU писал(а):
Проверил:
Код:
volatile char *p="AAA";
volatile char str[]="BBB";
char i = PINB;
  4e:   86 b3           in      r24, 0x16       ; 22
PORTC = p[i];
  5c:   99 27           eor     r25, r25
  5e:   87 fd           sbrc    r24, 7
  60:   90 95           com     r25
  62:   e0 91 64 00     lds     r30, 0x0064
  66:   f0 91 65 00     lds     r31, 0x0065
  6a:   e8 0f           add     r30, r24
  6c:   f9 1f           adc     r31, r25
  6e:   20 81           ld      r18, Z
  70:   25 bb           out     0x15, r18       ; 21
DDRC = str[i];
  68:   ff 27           eor     r31, r31 //при другой компиляции, переменная i оказалась не в r24, а в r30
  6a:   e7 fd           sbrc    r30, 7
  6c:   f0 95           com     r31
  6e:   e0 5a           subi    r30, 0xA0       ; 160
  70:   ff 4f           sbci    r31, 0xFF       ; 255
  72:   80 81           ld      r24, Z
  74:   84 bb           out     0x14, r24       ; 20

Как и следовало ожидать - обращение к массиву быстрее, чем к указателю, даже с переменным индексом.
Опять же, не совсем правильное сравнение.
Адрес str компилятору известен на этапе компиляции, а из p его ещё нужно забрать.
Вы снова привели сравнение по типу обращения к переменной напрямую и через указатель, для чего-то доказывая, что указатели - плохо, а массивы - хорошо, подбирая какие-то варианты, где с указателем код становится жирнее. Хорошо, ни кто не спорит, но не всегда можно обойтись без указателей. for тоже, в некоторых случаях, можно заменить while-ом, но не всегда, т.к. это, также, как и переменная с указателем - разные вещи.
Даже моему коту понятно, что при p-указателе, кострукция p[i] развернётся х.з. во что. Нужно просто понимать что ты пишешь и подбирать более оптимальные варианты реализации задуманного.

Вот это:
Цитата:
В этом случае, обращение будет практически эквивалентно обращению через указатель.
я имел в виду, сравнения типа
Код:
a = str[i];
и
Код:
a = *p;
Должно получится примерно одно и тоже.
Но опять же, я не подталкиваю на какие то там сравнения что лучше чего. Нельзя сравнивать ножовку по металлу с ножовкой по дереву. Они обе пилят, но какую лучше использовать в конкретном случае - уже решать тому, кому нужно что-то отпилить. А в некоторых случаях, они подойдут обе.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 03:06:49 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4573
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
COKPOWEHEU писал(а):
Есть примеры, при котором выгоднее объявлять массив указателем-переменной?
Есть конечно. Когда массив - константная строка, которая никогда не изменится.
В случае с
Код:
char str[]="Мама мыла раму";
данные в массиве str Вы сможете дальше в программе поменять. Т.е. Вы выделили себе массив определённого размера (в данном случае, без числа в скобках - размер строки), с которым дальше собираетесь работать, проинициализированный какой-то строкой.
Но если Вам не нужно этого, зачем выделять лишнюю память в ОЗУ под массив и мучить компилятор, заставляя его при инициализации копировать всю строку в этот массив, при том, что экземпляр строки уже где-то есть (вероятнее всего он во флеши) ?
Достаточно просто получить адрес этой строки в указатель :
Код:
char* p="Мама мыла раму.";
и дальше работать с ним :
Код:
p="Мама домыла раму.";
......

Если не хотите случайно потерять ссылку на строку, либо не собираетесь дальше использовать этот указатель для других строк, то объявите указатель константой :
Код:
char* const p="Мама мыла раму.";
......
p="Мама домыла раму.";    // ОШИБКА !
В таком случае, если компилятор будет сильно умным, есть вероятность, что он даже память не будет выделять под указатель, а просто будет заменять его сразу на адрес строки.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 06:51:43 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Аlex писал(а):
я имел в виду, сравнения типа a = str[i]; и a = *p;Должно получится примерно одно и тоже.
я же приводил дизассемблерный код: второй вариант сработает быстрее, и его в некоторых случаях лучше использовать. Например, при копировании строк (strcpy), но это не объявление массива. Впрочем, если надо обрабатывать данные строго последовательно, это лучше, но и то, я бы записал как
Код:
char str[]="string"; //объявление и инициализация отдельно. Все равно, память занимается под данные, а не под их адрес, так что ничего не потеряем, зато сразу ясно что str - массив.
char *p=str; //обработка отдельно

Цитата:
при том, что экземпляр строки уже где-то есть (вероятнее всего он во флеши) ?
Зависит от компилятора. В avr-gcc и, вроде, cvavr, для размещения в ПЗУ есть специальный модификатор - PROGMEM, flash или как-то так. А уже для работы с существующей строкой можно использовать как указатель, так и прямой адрес (вот как это выглядит в avr-gcc)
Код:
PROGMEM char str[] = "string"; //опять объявление отдельно
char *p = str;
char dst[6];
memcpy_P(dst, p, 6); memcpy_P(dst, str,6); memcpy_P(dst, &str[2], 3); //использование отдельно
А вот указатель как раз скорее зарезервирует память под данные, доступ к которой легко потерять. Сами бы проверили в отладчике, что и где хранится
Цитата:
Если не хотите случайно потерять ссылку на строку, либо не собираетесь дальше использовать этот указатель для других строк, то объявите указатель константой :
В таком случае, если компилятор будет сильно умным, есть вероятность, что он даже память не будет выделять под указатель, а просто будет заменять его сразу на адрес строки.
Так в чем преимущество? Зачем полагаться на то, что "компилятор будет сильно умным", если можно ему явным образом указать?
Цитата:
для чего-то доказывая, что указатели - плохо, а массивы - хорошо, подбирая какие-то варианты, где с указателем код становится жирнее
Я не доказывал преимущества массивов во всех случаях. Я доказывал только то, что объявление строки через массив лучше, чем через указатель.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 08:03:44 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4573
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
COKPOWEHEU писал(а):
Зависит от компилятора. В avr-gcc и, вроде, cvavr, для размещения в ПЗУ есть специальный модификатор - PROGMEM
Ни от чего это не зависит. Строка в массив откуда то копируется (пусть даже байтами по-очереди, командами в ряд), а значит она занимает память. И причём тут PROGMEM ? Речь совсем не о том, где размещается строка. А о том, что она уже где-то есть.

COKPOWEHEU писал(а):
Так в чем преимущество? Зачем полагаться на то, что "компилятор будет сильно умным", если можно ему явным образом указать?
Вы, по всей видимости, меня не поняли. Не надо ни на кого полагаться, это я для примера сказал, если ссылку не хотите терять.
Преимущество в том, что Вы под строку, которая никогда не будет меняться, занимаете ещё драгоценное ОЗУ, объявляя массив. А зачем он Вам в этом случае ? Вам только строка нужна, которая итак уже где-то лежит. Дак почему бы её оттуда и не забирать ?

COKPOWEHEU писал(а):
Я доказывал только то, что объявление строки через массив лучше, чем через указатель.
Объявление строки, с присваиванием указателя на неё ничем не отличается от присваивания её массиву. Строка не объявляется через чего-то, она объявляется в виде текста, обрамлённого кавычками. Когда Вы пишете в коде "Строка", она уже объявлена ,и под неё уже выделено место. Единственное, когда Вы объявляете ещё и массив, она тупо копируется в него.
У меня начинается складываться впечатление о Вашей некомпетентности в этой области. Очень надеюсь, что ошибаюсь.

Цитата:
Сами бы проверили в отладчике, что и где хранится
Зачем мне проверять очевидные вещи ? Что Вы вообще прицепились к этим областям хранения ? Речь не о том, что и где лежит - это уже другая тема, к которой Вы потихоньку перебираетесь, уходя от основной темы разговора :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 17:32:54 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Аlex писал(а):
Ни от чего это не зависит. Строка в массив откуда то копируется (пусть даже байтами по-очереди, командами в ряд), а значит она занимает память. И причём тут PROGMEM ? Речь совсем не о том, где размещается строка. А о том, что она уже где-то есть.
Если она объявлена как размещенная в ПЗУ, автоматически копироваться в ОЗУ она не будет, и не займет там ни одного байта.
Аlex писал(а):
Преимущество в том, что Вы под строку, которая никогда не будет меняться, занимаете ещё драгоценное ОЗУ, объявляя массив. А зачем он Вам в этом случае ? Вам только строка нужна, которая итак уже где-то лежит. Дак почему бы её оттуда и не забирать ?

Вот именно. Объявление массива не создает лишних переменных. То есть запись char str[]="AAA"; занимает 4 байта, а запись char *p="AAA"; - 6 байт (для AVR, где указатель двухбайтный).
Если, например, мне нужна скорость и критична разница в пару тактов, я размещу строку в ОЗУ, зная, что в начале программы она будет скопирована из флеша. В обычном же случае пусть будет во flash.
Аlex писал(а):
Объявление строки, с присваиванием указателя на неё ничем не отличается от присваивания её массиву. Строка не объявляется через чего-то, она объявляется в виде текста, обрамлённого кавычками. Когда Вы пишете в коде "Строка", она уже объявлена ,и под неё уже выделено место. Единственное, когда Вы объявляете ещё и массив, она тупо копируется в него.
Объявление массива само по себе места не занимает, как и объявление переменной. Место резервируется под данные. В случае указателя, отдельно резервируется место и под строку (причем, по умолчанию, в ОЗУ), и под ее адрес.
Аlex писал(а):
У меня начинается складываться впечатление о Вашей некомпетентности в этой области. Очень надеюсь, что ошибаюсь.

Знаете, у меня закрадываются схожие сомнения на ваш счет. Впрочем тут мы можем сравнить компетентность друг друга. Есть записи
Код:
char rstr[] = "RAM str";
char *rptr = "RAM ptr";
PROGMEM const char fstr[] = "ROM str";
PROGMEM const char *fptr = "ROM ptr";
char *fptr2 = PSTR("ROM PTR");
Все они так или иначе создают строку длиной 8 байт. Как считаете, сколько байт ОЗУ занимает каждый из вариантов и сколько тактов нужно для получения элемента по переменному индексу? Если дополните этот список вариантами расположения строки, будет только лучше.
Аlex писал(а):
Зачем мне проверять очевидные вещи ? Что Вы вообще прицепились к этим областям хранения ? Речь не о том, что и где лежит - это уже другая тема, к которой Вы потихоньку перебираетесь, уходя от основной темы разговора :)
Потому что, как показало это обсуждение, эти вещи не очевидны. А от какой темы я ухожу? Пока что я общаюсь на тему "преимущества объявления строки как массива перед указателем".


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 20:42:21 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4573
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Давайте сделаем вот как. Что бы мы общались "на одной волне", Вы скинете мне весь свой набор (компиль, ИДЕ, ..). Ибо я под АВР никогда не программил и понятия не имею ни поведения Вашего компилятора, ни тем более количество тактов, требуемых для определённых действий. А в угадайку играть не хочется.
Скиньте, плз, в личку ссылочки для скачивания. Там же потом может и продолжим этот интересный разговор. А то так всю тему зафлудим этими спорами.

Скажу только то, что знаю точно. char rstr[] = "RAM str"; займёт минимум 8 байт флеши, не считая команд копирования + минимум 8 байт ОЗУ под массив. О чём я и твержу, что для строки бессмысленно выделять в ОЗУ память, если она и так заняла флешь и можно оттуда её выдёргивать, потратив всего-лишь пару байтов на указатель. Да и тот, также, можно закинуть в флешь.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Пт ноя 27, 2015 22:15:27 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1524
Рейтинг сообщения: 0
Цитата:
Скажу только то, что знаю точно. char rstr[] = "RAM str"; займёт минимум 8 байт флеши
Ну, 8 байт флеши уйдет на одну строку, обсуждение у нас о прочих расходах.
Насколько я понял из анализа дизассемблированного кода, все глобальные переменные и явно инициализированные заполняются сразу после старта программы, до входа в main в едином цикле, так что именно на копирование из flash в ОЗУ память не тратится, только лишних 8 - 10 тактов. Именно при старте на это никто внимания не обратит.
Запись char str[]="AAA"; выделяет в ОЗУ 4 байта памяти, которые будут при старте заполнены из flash. Адрес начала хранится не в переменной, а подставляется компилятором. То есть запись char x = str[1]; эквивалентна char x= *((char*)(0x60+1)), где 0x60 - адрес в ОЗУ, где компилятор разместил массив. То есть расход по ОЗУ - 8 байт, по ПЗУ - 8 байт (не считая само обращение), скорость доступа я уже приводил, 6 тактов. Это немного быстрее, чем работа напрямую с flash и проще для новичков. Но большой расход ОЗУ.
Запись PROGMEM const char str[]="AAA"; выделяет 4 байта ПЗУ, заполненные текстом. Обращение к такой строке идет через специальные команды strcpy_P, memcpy_P, pgm_read_byte и т.д. (если интересно, см. avr-libc). Сама по себе эта запись не занимает в ОЗУ ни одного байта. Запись char x = pgm_read_byte(&str[1]) эквивалентна pgm_read_byte(0x60+1), где 0x60 - адрес в ПЗУ (все-таки, гарвардская архитектура, приходится явно указывать тип памяти), на самом деле он вряд ли будет такой маленький, но для примера это не важно. Скорость доступа около 7 тактов. Обычно именно этот вариант оптимален, но иногда лень подключать pgmspace.h и вспоминать тамошние функции.
Запись char *p = "AAA"; выделяет в ОЗУ 4 байта памяти для строки (также, как для массива) и 2 байта для указателя, записывая туда при старте адрес тех 4 байт. Фактически, она эквивалентна char str[]="AAA"; char *p = str; только адрес str компилятору неизвестен. По скорости около 11 тактов, по объему тоже все плохо, дизассемблерный код я приводил.
Запись char *p = PSTR("AAA"); должна бы создавать массив только в ПЗУ, давая указатель на него, но макрос PSTR работает только в функциях, так что этот вариант неработоспособен и рассматривать его не стоит.
Запись PROGMEM const char *p = "AAA"; компилятором понимается (warning не в счет), но по сути бесполезна - массив создается в ОЗУ, а его адрес записывается в flash. Зачем может понадобиться такое извращение я без понятия. Компилятор, видимо, тоже, поскольку собирается игнорировать модификатор PROGMEM.
Вот как я понимаю распределение памяти и скорости для разных вариантов и на основании чего не рекомендую обхявлять строку как char *p="...";


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Сб дек 12, 2015 12:51:12 
Первый раз сказал Мяу!

Зарегистрирован: Ср сен 01, 2010 07:24:48
Сообщений: 22
Рейтинг сообщения: 0
Народ помогите!!! :o не получается вывести на LCD строку в Протеусе:

sprintf(text,"%s","Hello");
lcd_puts(text);

и так пробовал:
sprintf(text,"%s\n","Hello");
sprintf(text,"%4s\n","Hello");
sprintf(text,"%4s","Hello");
sprintf(text,"%.4s","Hello");
sprintf(text,"%6.4s","Hello");




главное sprintf(text,"%d",123); работает, не могу понять где косячу


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Сб дек 12, 2015 15:51:03 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2119
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18408
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
fatall_error писал(а):
Народ помогите!!! не получается вывести на LCD строку в Протеусе
скорее всего проблема в описании массива text - каков его размер?
Аlex писал(а):
Что бы мы общались "на одной волне"
о чем вы спорите, о каких волнах идет речь? записи char *s и char s[] полностью идентичны по всем формальным критериям! это даже не совсем разные записи одного и того же. а то, что в определенный момент вы инициализируете указатель адресом какой-то строки, это дело третье.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Сб дек 12, 2015 16:48:56 
Первый раз сказал Мяу!

Зарегистрирован: Ср сен 01, 2010 07:24:48
Сообщений: 22
Рейтинг сообщения: 0
unsigned char text[32];


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
СообщениеДобавлено: Сб дек 12, 2015 20:05:25 
Первый раз сказал Мяу!

Зарегистрирован: Ср сен 01, 2010 07:24:48
Сообщений: 22
Рейтинг сообщения: 0
Спасибо всем кто мысленно болел заменя, я разобрался


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 8295 ]     ... , , , 348, , , ...  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 130


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y