WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Re: WinAvr в вопросах и ответах

Сообщение viiv »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3202314#p3202314"]Просто может есть еще какое-то решение, не использовать MOSI.[/uquote]
Так я же дал еще один способ :-) не подходит?
Спойлер/* Функция выдачи байта со значением 0x00 */
out_00:
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
RET
/* Функция выдачи байта со значением 0x01 */
out_01:
SBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
RET
/* Функция выдачи байта со значением 0x02 */
out_02:
CBI $0B, 7
SBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
RET

/* Функция выдачи байта со значением 0x02 */
out_02:
CBI $0B, 7
SBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
CBI $0B, 7
RET

....
/* Функция выдачи байта со значением 0xfe */
out_fe:
CBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
RET

/* Функция выдачи байта со значением 0xff */
out_ff:
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
SBI $0B, 7
RET
Данные функции имеют одиноковый размер, т.е. если они идут подряд, вычислить адрес нужной функции - не проблема.
Реклама
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: WinAvr в вопросах и ответах

Сообщение Dimon456 »

[uquote="viiv",url="/forum/viewtopic.php?p=3202331#p3202331"]Так я же дал еще один способ :-) не подходит?
Данные функции имеют одиноковый размер, т.е. если они идут подряд, вычислить адрес нужной функции - не проблема.[/uquote]Подходит, объем кода только будет шикарный. Надо попробовать.

Добавлено after 7 minutes 31 second:
Отлично, быстрее не сделаешь, разве что кварц менять.
СпойлерИзображение
Реклама
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Re: WinAvr в вопросах и ответах

Сообщение viiv »

Dimon456, в твоем примере, время выдачи байта зависит от значения байта. По крайней мере видно, что компилятор так нагенерил (может оптимизация не включена). Если ты допишешь все 256 case-ов, увидишь что значение 255 сдвигается долго. Надо именно вычислить смещение, а не перебирать все варианты.

посмотри как написать свою функцию эффективно на ассемблере, пока приходит идея использовать SBRC, SBRS команды. А так надо смотреть, количество тактов для выполнения всех комманд есть в документации. Когда был студентом, у нас была игра - написать небольшую (типа твоей) функцию, чтобы она выполнялась максимально быстро. Вот тебе и надо поигать в эту игру. :-)
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: WinAvr в вопросах и ответах

Сообщение Dimon456 »

Да, действительно, не хилая задачка, да и код шикарный будет.
СпойлерИзображение
Реклама
Эиком - электронные компоненты и радиодетали
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Re: WinAvr в вопросах и ответах

Сообщение viiv »

Навскидку 4608байт займут 256 функций вывода (я не внимательно считал). Но это самый быстрый вариант при выдаче байта - нет ветвлений. Можно уйти от 256 функций, съэкономив флеш, но будет медленней.
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

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

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Структуры в PROGMEM

Сообщение afz »

Нет, конечно, потрепаться о CVAVR в теме про WinAVR - это, несомненно, круто! А вот как с моим вопросом?

Ладно, структуры в PROGMEM, действительно, нереальны. А может выйдет как-нибудь запихнуть два байта двоичного кода внутрь текстовой строки, преобразовав эти коды макросом? Типа, пишу My_Macro(10560,"какой-то текст"); и получаю "\0x40\0x29\какой-то текст", где 0х40 - остаток от деления 10560 на 256, а 0х29 - целая часть результата этого деления, т е. частного? Или что-то подобное?

Блин, ну какой убогий макроязык в этих Сях!.. На макроязыке любого ассемблера от "больших" компьютеров такое сделать - как два байта переслать, а тут!.. :kill:
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

afz писал(а):структуры в PROGMEM, действительно, нереальны
еще как реальны! но инициализировать их СТРОКАМИ не очень удобно. можно, но чуть-чуть геморно. всё дело в том, что AVR-GCC не может одновременно присваивать строковое значение полю структуры и объявлять строковую константу. делать это придётся отдельно... то есть как-то так:

Код: Выделить всё

typedef struct{
   int a;
   char b;
   char *str;
} my_struct;

PROGMEM char my_str1[] = "string 1";
PROGMEM char my_str2[] = "string 2";
PROGMEM char my_str3[] = "string 3";
PROGMEM char my_str4[] = "string 4";

#define str_init(x,y,z) {.a=x, .b=y, .str=z}

PROGMEM my_struct array[4] = {
   str_init(1,2,my_str1),
   str_init(3,4,my_str2),
   str_init(5,6,my_str3),
   str_init(7,8,my_str4)
}
Добавлено after 1 minute 50 seconds:
Очень рекомендую применять не WinAVR, а сборку AVR-GCC версии свежее 4 (лично я пользуюсь 6.2.2) - там уже определено пространство __flash, что позволяет работать с массивами, строками и структурами во flash практически так же просто, как и с ОЗУ - никаких pgm_read_xxx более не требуется!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение WiseLord »

Как вариант, для более простого кода можно попробовать инициализировать не строками, а массивами char-ов определённой длины. Правда, при этом часть памяти будет потрачена впустую.

Код: Выделить всё

typedef struct{
   uint16_t freq;
   char name[16];
} my_struct;

const my_struct array[] PROGMEM = {
    {9890, "Russian"},
    {9950, "Unistar"},
};
Не уверен в корректности кода (в смысле, не проверял), но компилируется он вроде как без ошибок.
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Re: Структуры в PROGMEM

Сообщение viiv »

afz, чуть подправил пример от ARV, чтобы все определения (радиостанций) поместить в одно место. Почти как ты хотел :-) (предполагается, что "freq" структуры _radio_t является уникальным):
Спойлер

Код: Выделить всё

#define RADIO_LIST                 \
	RADIO_ITEM(10450, "string 1")   \
	RADIO_ITEM(10520, "string 2")   \
	RADIO_ITEM(10640, "string 3")   \
	RADIO_ITEM(10680, "string 4")

typedef struct _radio_t {
   int freq;
   const char *name;
} radio_t;

/* Объявляем строки */
#define RADIO_ITEM(f,s) PROGMEM char radio_name_##f [] = s;
	RADIO_LIST
#undef RADIO_ITEM

/* Объявляем массив, в котором указатели на объявленные ранее строки */
#define RADIO_ITEM(f,s) { .freq=f, .name=radio_name_##f },
PROGMEM radio_t radio_array [] = {
	RADIO_LIST
};

#define RADIO_LIST_SZ (sizeof (radio_array)/sizeof(radio_t))
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

viiv писал(а):чуть подправил пример
вот это здорово! сам мучился всегда с разбросанными в разных местах строками и связанными с ними логически остальными вещами - беру на вооружение ваш подход! :beer:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Re: WinAvr в вопросах и ответах

Сообщение viiv »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3202756#p3202756"]Не уверен в корректности кода (в смысле, не проверял), но компилируется он вроде как без ошибок.[/uquote]
Раз скомпилировал, то легко посмотреть во что это скомпилировалось :-) Например, если задать ключик "-S", то в выходном ассемблерном файле можно посмотреть все ли было сделано так, как задумывалось. У меня не WinAVR, а классический кросс gcc под линукс: Ваш код поместил массив структур в секцию ".progmem.data", - все как и было задумано
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение WiseLord »

Да, что-то я и забыл про .lss файл, который у меня Makefile делает
Изображение
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: WinAvr в вопросах и ответах

Сообщение Dimon456 »

[uquote="viiv",url="/forum/viewtopic.php?p=3202481#p3202481"][/uquote]В общем так:
Спойлер

Код: Выделить всё

// Создаем функции с одинаковым количеством параметров
// и соответствующими типами, а так же возвращаемым типом

void m0 (void) {
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0; 
     PORT_VID.VID_PIN = 0;
}

void m1 (void) {
     PORT_VID.VID_PIN = 1;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0; 
     PORT_VID.VID_PIN = 0;
}

void m2 (void) {
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 1;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0;
     PORT_VID.VID_PIN = 0; 
     PORT_VID.VID_PIN = 0;
}

// Я три создал, для проверки что это будет работать

 // создаем новый прототип (в данном случае указатель на функцию)
  typedef  void (*fptr)(void);
   
  fptr arr[3]; // объявляем массив функций в данном случае из трех элементов
  // помещаем в массив функции указывая их имена (имя функции это и есть указатель на нее)
    arr[0] = m0;
    arr[1] = m1;
    arr[2] = m2; 

//Ну и волшебный
#define COLUMN(r) arr[font[r][fontline]]();          // Результат 3.7500us

//Надпомню #define COLUMN(r) SPDR=font[r][fontline];                 // Выполнялся за 1.5625us
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: WinAvr в вопросах и ответах

Сообщение Пока_без_кота »

Доброго времени суток. Раздела по AVR Toolchain не нашел, поэтому спрошу здесь. Вчера стоял AVR Toolchain 3.3, сегодня снес и поставил 3.4 (новее, значит лучше, ага...). Вчера прога компилировалась без ошибок, сегодня на строке

Код: Выделить всё

char OK[] PROGMEM = "OK";
Выдает error: variable 'OK' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
Как изменить запись, чтобы ошибка пропала ? Студия 4.19.
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение watchmaker »

Добавить const перед типом. Странно, что пропускало без этого атрибута, эти данные должны обязательно объявляться константами.
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

Пока_без_кота писал(а):новее, значит лучше, ага...
мне показалось, что avr-gcc 4.9.2 и 5.2.1 выдают более компактный результат компиляции. ну а вообще максимально новая версия, которой я пользуюсь, имеет номер 6.1.1
Пока_без_кота писал(а):Как изменить запись, чтобы ошибка пропала ?
попробуйте так

Код: Выделить всё

const __flash char OK[] = "OK";
если скомпилируется, то для доступа к байтам строки уже не потребуется применять pgm_read_byte, можно будет сразу работать, как с обычной переменной. разумеется, это относится не только к строкам, но и к любым другим "переменным" во flash

только с указателями будьте осторожнее, потому что "указатель на данные во flash" и "указатель во flash на данные" - две большие разницы
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: WinAvr в вопросах и ответах

Сообщение Пока_без_кота »

Нет, скомпилировалось только, если просто добавить const

Код: Выделить всё

const char OK[] PROGMEM = "OK";
И теперь выдает warning: passing argument 1 of 'SendStr_P' discards 'const' qualifier from pointer target type [enabled by default] на функции

Код: Выделить всё

// Отправка строки из флеша в UART =================
void SendStr_P(char *string)							// На входе указатель на символ строки
{
	while (pgm_read_byte(string) != '\0')				// Пока байт строки не 0 (конец строки)
	{
		SendByte(pgm_read_byte(string));				// Мы продолжаем слать строку
		string++;										// Не забывая увеличивать указатель, выбирая следующий символ строки
	}
}
Смысл варнинга мне понятен, но вот как подправить, я не знаю.
Насчет не самой последней версии. Это последняя версия с сайта Атмел, которая идет одним екзешником и ее легко может проинсталить любой новичек. Все что позже, поставляеться каким-то набором файлов, и я незнаю, как его установить.
Последний раз редактировалось Пока_без_кота Ср окт 18, 2017 07:55:56, всего редактировалось 2 раза.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

Пока_без_кота писал(а):но вот как подправить, я не знаю
да точно так же: раз указатель "на константу", то и писать его тип надо аналогично

Код: Выделить всё

void SendStr_P(const char *string)
Добавлено after 51 second:
P.S. __flash, наверное, в более поздних версиях компилятора добавилось - рекомендую перейти на посвежее версию.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: WinAvr в вопросах и ответах

Сообщение Пока_без_кота »

Ха... Я думал точно так, как Вы сказали, но если я так делал, мне вместо варнинга выдавался уже error: conflicting types for 'SendStr_P'. Посчитав, что варнинг лучше чем еррор, я оставил как было...
Ответить

Вернуться в «AVR»