WinAvr в вопросах и ответах
А зачем что-то куда-то девать? Там в finish.mk уже есть готовая цель program для прошивки avrdude, просто ею воспользуйтесь
- Реклама
- Сообщения: 7722
- Зарегистрирован: Вс июл 24, 2011 11:38:09
Еслиб я был программистом, я бы искал проблемы в мелочах, а имея паяльник…
Оказалось всё проще
…в общем я спалил програматор.
Запаял вместо 78lO5 туда 78l|5
От usb прибор отказался работать от 4.5, ну я сунул в него китай бп 15-10.
Яркость росла, контраст плыл, ну при втыкании usb становилось как надо, видимо ПК вместе с програматором сажали на себе до 7в.
Всё нормально было, только прибор брехал, потом то дошло нужную кренку впаять и всё было хорошо пока я дал команду BitClock=115000 на чём програматор повис и я его дёрнул.
Програматор сдох, порт сдох, все порты сдохли.
Перестановкой дров удалось оживить порты которые опять нашлись, но мой програматор уже не определялся в отличии от другой платки.
В итоге выход 3.3в pl2303 коротыш на корпус, пробовал подавать ненужные 3в с прибора, сажает до 2.5 и не определяется.
Вменил микру, вот тут началось извращение.
Непропай убил мне и прошивку в програматоре(точнее я её) и ещё пол дня потрачено.
Из за одной полухалявной кренки видимо поджарил микру по питанию.
Не знаю в этом ли была проблема, но потом корпус подплавился.
А может от выдёргивания провода или както замкнул.
Неверная команда скорости свалила програматор в медленый режим.
Решается 2 способами, стереть eep програматора, что невозможно без полной перешивки.
Или накатить AVR Studio 4 или может 6 и там поднять частоту isp, что тоже хрен найдёшь, они разные.
Вобщем пропаяв usb-uart и убрав сопли, стандардатным(для меня) способом запаяв капельки перешил микру чтоб ожила, а настройку поменял в студии.
Кароче надо eep с неё снять с настройками, чтоб по полчаса не шить и не искать где студию скачать
Оказалось всё проще
Код: Выделить всё
PROGRAMMER=stk500v2
PORT=com7
BitClock=1Спойлер
История долгая, китаец обманул меня прислав не то, я обманул китайца оставив кренки и леды вместо не присланых пофигисторов потомучто они 2.5 раза дороже.Запаял вместо 78lO5 туда 78l|5
От usb прибор отказался работать от 4.5, ну я сунул в него китай бп 15-10.
Яркость росла, контраст плыл, ну при втыкании usb становилось как надо, видимо ПК вместе с програматором сажали на себе до 7в.
Всё нормально было, только прибор брехал, потом то дошло нужную кренку впаять и всё было хорошо пока я дал команду BitClock=115000 на чём програматор повис и я его дёрнул.
Програматор сдох, порт сдох, все порты сдохли.
Перестановкой дров удалось оживить порты которые опять нашлись, но мой програматор уже не определялся в отличии от другой платки.
В итоге выход 3.3в pl2303 коротыш на корпус, пробовал подавать ненужные 3в с прибора, сажает до 2.5 и не определяется.
Вменил микру, вот тут началось извращение.
Непропай убил мне и прошивку в програматоре(точнее я её) и ещё пол дня потрачено.
Из за одной полухалявной кренки видимо поджарил микру по питанию.
Не знаю в этом ли была проблема, но потом корпус подплавился.
А может от выдёргивания провода или както замкнул.
Неверная команда скорости свалила програматор в медленый режим.
Решается 2 способами, стереть eep програматора, что невозможно без полной перешивки.
Или накатить AVR Studio 4 или может 6 и там поднять частоту isp, что тоже хрен найдёшь, они разные.
Вобщем пропаяв usb-uart и убрав сопли, стандардатным(для меня) способом запаяв капельки перешил микру чтоб ожила, а настройку поменял в студии.
Кароче надо eep с неё снять с настройками, чтоб по полчаса не шить и не искать где студию скачать
- Сообщения: 72
- Зарегистрирован: Пн окт 01, 2018 11:33:59
Друзья, такой вопрос! Задача - написать бутлоадер на 128 меге на с++.
Во всех статьях инструкции - менять строки, указывать адрес загрузочной секции в makefile. Но! в atmel studio 7.0 они пишутся автоматически, даже в заголовке стоит метка - не изменять. Изменение фьюзов Bootrst и bootsz результатов не принесло.
Во всех статьях инструкции - менять строки, указывать адрес загрузочной секции в makefile. Но! в atmel studio 7.0 они пишутся автоматически, даже в заголовке стоит метка - не изменять. Изменение фьюзов Bootrst и bootsz результатов не принесло.
[uquote="An-SU",url="/forum/viewtopic.php?p=3530071#p3530071"]указывать адрес загрузочной секции в makefile. Но! в atmel studio 7.0 они пишутся автоматически[/uquote]Они пишуться автоматически из настроек проекта в студии.
Пропишите в настройках проекта соответствующие параметры линковщику. Студия их потом в makefile пропишет.
Пропишите в настройках проекта соответствующие параметры линковщику. Студия их потом в makefile пропишет.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
подскажите, кто знает, почему я не могу получить значение символа, заданного в скрипте линкера?
скрипт (фрагмент):определил два символа __my_tbl_start и __my_tbl_end
в программе делаю так:получаю 0x0000 0x0000
хотя в map-файле эти символы нулю, естественно, не равны:
что я делаю не так? как в программе получить значения этих символов дл доступа к моей таблице?
скрипт (фрагмент):
Код: Выделить всё
.text :
{
*(.vectors)
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
/* PR 13812: Placing the trampolines here gives a better chance
that they will be in range of the code that uses them. */
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* avr-libc expects these data to reside in lower 64K. */
*libprintf_flt.a:*(.progmem.data)
*libc.a:*(.progmem.data)
*(.progmem*)
. = ALIGN(2);
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* Внедрение моих секций для таблиц */
__my_tbl_start = __dtors_end ;
*(.my_table)
__my_tbl_end = . ;
KEEP(SORT(*)(.my_table))
/* Конец моих секций для таблиц */
в программе делаю так:
Код: Выделить всё
extern int __my_tbl_start;
extern int __my_tbl_end;
printf("%04X %04X", __my_tbl_start, __my_tbl_end);хотя в map-файле эти символы нулю, естественно, не равны:
Код: Выделить всё
0x0000069e __my_tbl_start = .
*(.my_table)
.my_table 0x0000069e 0x2 ./alarm-main.o
0x0000069e _A0_DATA28
.my_table 0x000006a0 0x2 ./alarm.o
0x000006a0 _A0_DATA22
.my_table 0x000006a2 0x2 ./timers.o
0x000006a2 _A0_DATA121
0x000006a4 __my_tbl_end = .
SORT(*)(.my_table)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
А сами таблицы (массивы, как я понимаю) объявлены с "__attribute__((__section__(".my_table")))"?
И ещё немного непривычно (хотя не уверен, что неправильно), что по сути, если верить скрипту, эта секция объявлена внутри .text. Я в своё время экспериментировал (правда, с STM32, но не суть важно) - так я отдельно в MEMORY {} добавлял MY_TABLE - нужную область памяти (по адресам - в конце FLASH), а саму область FLASH "обрезал" на это же число. И уже отдельно секцию объявлял, типа
Вполне работало.
И ещё немного непривычно (хотя не уверен, что неправильно), что по сути, если верить скрипту, эта секция объявлена внутри .text. Я в своё время экспериментировал (правда, с STM32, но не суть важно) - так я отдельно в MEMORY {} добавлял MY_TABLE - нужную область памяти (по адресам - в конце FLASH), а саму область FLASH "обрезал" на это же число. И уже отдельно секцию объявлял, типа
Код: Выделить всё
.my_table :
{
. = ALIGN(4);
__my_tbl_start = .;
*(.my_table*)
__my_tbl_end = .;
} > MY_TABLEэлементы таблицы объявлены именно с указанием секции. смысл этих телодвижений - создать некий аналог массива во FLASH, элементы которого разбросаны по отдельным модулям проекта - где нужно объявить, там и объявляется, а в итоге все эти разрозненные объвления оказываются в одном массиве. но надо как-то узнать адрес начала этого массива и его длину, для чего два этих символа и объявляю...
это первый мой опыт со скриптами, плохо понимаю, что делаю... но по образцу найденного в интернете: https://stackoverflow.com/questions/397 ... le-for-avr
это первый мой опыт со скриптами, плохо понимаю, что делаю... но по образцу найденного в интернете: https://stackoverflow.com/questions/397 ... le-for-avr
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
А зачем такие сложности, на самом деле? Объявите массивы const PROGMEM (то есть, самым что ни на есть стандартным образом), и компилятор разберётся сам.
Я в моём случае пытался задействовать лишние 64кБ Flash-памяти на STM32F103C8, которых у него якобы нет. А какова у Вас причина не отдать это на откуп компилятору?
Я в моём случае пытался задействовать лишние 64кБ Flash-памяти на STM32F103C8, которых у него якобы нет. А какова у Вас причина не отдать это на откуп компилятору?
сложности?
задача стоит такая: парсить входную строку, и по её первым нескольким (количество разное) символам вызывать ту или иную функцию.
то есть в начале строки идет текстовая команда и надо её выполнять.
как такие задачи решаются в avr-gcc?
описывается структура типазаметьте, что в конце структуры указатель на сроку во FLASH.
затем описываются все ключевые строки:затем определяются все функции обработки и массив во FLASH из этих структур
ну а уж потом в цикле можно перебирать элементы массива, сравнивать начало строки с полем cmd и при совпадении вызывать соответствующую функцию.
согласны, что так принято делать? удобно ли это? это ужасно неудобно!
во-первых, надо отельно описывать строки, т.к. avr-gcc не может сразу помещать во FLASH строку, указанную в инициализации структуры.
во-вторых, все функции должны быть описаны до массива в том же модуле
в-третьих, если по ходу пьесы приходит на ум изменить количество элементов массива, то надо править сразу в трех местах...
с другой стороны, в avr-gcc имеется возможность в любом месте в любом модуле описать обработчик прерывания, и они все из разных мест будут собраны линкером в одну таблицу! вот аналогичный подход я и хочу реализовать:а затем в любом месте моего проекта(т.е. в любом месте любого исходника!) я напишу таки вуаля! линкер соберет все эти разрозненные "входы" в таблицу, останется лишь узнать адрес её начала и... понимаете?
согласитесь, что это просто очень удобно! и какой простор по применению этого метода при создании меню! красота ведь!
кстати, по моему конкретному вопросу: ночью приснилось - утром проверил. адрес __my_tbl_start как раз правильный! то есть printf("%04X %04X", &__my_tbl_start, &__my_tbl_end); выводит то, что надо. но выглядит это каким-то грязным хаком...
Добавлено after 8 minutes 1 second:
единственное, о чем следует помнить при таком подходе, так это об уникальности всех "команд". нельзя допускать, чтобы существовали команды, совпадающие с первыми символами другой команды, т.е. "CMD" недопустимо, если существует "CMD1". потому как линкер отсортирует элементы таблицы так, что "CMD" всегда будет попадаться при переборе первой, и сравнение начала входной строки с этой командой будет происходить всегда, даже если в строке указана команда "CMD1"...
задача стоит такая: парсить входную строку, и по её первым нескольким (количество разное) символам вызывать ту или иную функцию.
то есть в начале строки идет текстовая команда и надо её выполнять.
как такие задачи решаются в avr-gcc?
описывается структура типа
Код: Выделить всё
typedef struct{
void (*funcptr)(char *);
const __flash char cmd[];
} item_t;затем описываются все ключевые строки:
Код: Выделить всё
const __flash char str1[] = "CMD1";
const __flash char str2[] = "CMD2";
const __flash char str3[] = "CMD3";Код: Выделить всё
static void func1(void){
}
static void func2(void){
}
static void func3(void){
}
const __flash item_t table[] = {
{.funcptr = func1, .cmd = str1},
{.funcptr = func2, .cmd = str2},
{.funcptr = func3, .cmd = str3},
}согласны, что так принято делать? удобно ли это? это ужасно неудобно!
во-первых, надо отельно описывать строки, т.к. avr-gcc не может сразу помещать во FLASH строку, указанную в инициализации структуры.
во-вторых, все функции должны быть описаны до массива в том же модуле
в-третьих, если по ходу пьесы приходит на ум изменить количество элементов массива, то надо править сразу в трех местах...
с другой стороны, в avr-gcc имеется возможность в любом месте в любом модуле описать обработчик прерывания, и они все из разных мест будут собраны линкером в одну таблицу! вот аналогичный подход я и хочу реализовать:
Код: Выделить всё
#define tbl_entry(s) static const __flash char s[] = # s ; \
static void CONCAT(func_, s)(void); \
static const __flash __attribute__((section(".my_table"))) item_t CONCAT(item_, s) = {.funcptr = CONCAT(func_, s), .cmd = s}; \
static void CONCAT(func_, s)(void)Код: Выделить всё
tbl_entry(CMD1){
// обработка команды
}согласитесь, что это просто очень удобно! и какой простор по применению этого метода при создании меню! красота ведь!
кстати, по моему конкретному вопросу: ночью приснилось - утром проверил. адрес __my_tbl_start как раз правильный! то есть printf("%04X %04X", &__my_tbl_start, &__my_tbl_end); выводит то, что надо. но выглядит это каким-то грязным хаком...
Добавлено after 8 minutes 1 second:
единственное, о чем следует помнить при таком подходе, так это об уникальности всех "команд". нельзя допускать, чтобы существовали команды, совпадающие с первыми символами другой команды, т.е. "CMD" недопустимо, если существует "CMD1". потому как линкер отсортирует элементы таблицы так, что "CMD" всегда будет попадаться при переборе первой, и сравнение начала входной строки с этой командой будет происходить всегда, даже если в строке указана команда "CMD1"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Так-то да, но в случае прерываний задача попроще. Всё-таки имена этих функций-прерываний фиксированы. И Вы, да, помещаете их где угодно в коде, но назвать "от балды" их не можете.ARV писал(а):в avr-gcc имеется возможность в любом месте в любом модуле описать обработчик прерывания, и они все из разных мест будут собраны линкером в одну таблицу!
А вот эта задачка, когда сами имена функций отличаются - это уже сложнее. И, ещё, как указатели на эти функции, в каком порядке, будут выстроены в этой таблице? Где гарантия, что он не нарушится при добавлении новой?
Имхо, такое стремление к "красоте" кода, делает его уж слишком непереносимым.
для поиска вхождений подстрок в строке не принципиально, в каком порядке сравнивать, поэтому порядок размещения строк-функций в массиве не важен. конечно, могут быть исключения, и тогда о красоте придется забыть, но, в частном случае моих задумок это не важно на самом деле.
на счет переносимости у меня такое мнение: во-первых, я надеюсь, GCC работает с секциями одинаково для всех платформ, и LD, по идее, тоже. значит, проблема переносимости будет заключаться только и исключительно в правильном выборе секций и корректировке скрипта линкера под конкретную платформу. я так понимаю, это нормально. во-вторых, лично меня прблема переносимости волнует мало, т.к. я не профессионал.
теперь снова о личном.
я моем проекте DIGILIGHT я сделал, как мне казалось на тот момент, гибкую систему сборки прошивки с разными модулями-эффектов. однако, на деле это вылилось в следующее: каждый модуль эффекта сам себя "регистрировал" при помощи специальной функции. регистрация эта заключалась в том, что в массив фиксированной величины, размещенный в ОЗУ, заносились адреса интерфейсных структур модуля. т.е. все недостатки проявились в полной мере: расход ОЗУ, необходимость "регистрировать" модуль вручную... а ведь при помощи секций и линкера все это можно было сделать гибче и проще, и ОЗУ напрасно не тратить. да и в случае необходимости никто не запретит и в ОЗУ массивы делать за счет усилий компоновщика! гибкость получается высочайшая!
на счет переносимости у меня такое мнение: во-первых, я надеюсь, GCC работает с секциями одинаково для всех платформ, и LD, по идее, тоже. значит, проблема переносимости будет заключаться только и исключительно в правильном выборе секций и корректировке скрипта линкера под конкретную платформу. я так понимаю, это нормально. во-вторых, лично меня прблема переносимости волнует мало, т.к. я не профессионал.
теперь снова о личном.
я моем проекте DIGILIGHT я сделал, как мне казалось на тот момент, гибкую систему сборки прошивки с разными модулями-эффектов. однако, на деле это вылилось в следующее: каждый модуль эффекта сам себя "регистрировал" при помощи специальной функции. регистрация эта заключалась в том, что в массив фиксированной величины, размещенный в ОЗУ, заносились адреса интерфейсных структур модуля. т.е. все недостатки проявились в полной мере: расход ОЗУ, необходимость "регистрировать" модуль вручную... а ведь при помощи секций и линкера все это можно было сделать гибче и проще, и ОЗУ напрасно не тратить. да и в случае необходимости никто не запретит и в ОЗУ массивы делать за счет усилий компоновщика! гибкость получается высочайшая!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
[uquote="ARV",url="/forum/viewtopic.php?p=3562362#p3562362"]что я делаю не так? как в программе получить значения этих символов дл доступа к моей таблице?[/uquote]
Думается в программе именно к этим символам доступ не получить никак - это же линковщик.
Надо действовать обычными путями.
Исходя из моего понимания можно:
1) задать фиксированный адрес секции при линковке, а адрес передавать через дефайн в исходники;
2) в основной программе, точнее в первом модуле при общей сборке, объявить в той же секции переменную, она будет там первая - взять её адрес.
3) создать асемблерный (.S) файл, где разместить глобальную метку в нужной секции, в общую линковку ставить этот файл первым, в исходнике через extern.
Добавлено after 2 hours 25 minutes 1 second:
ARV, это ж адрес! Метка сама по себе не резервирует память. Поэтому тип указанный в extern в упомянутом случае смысла не имеет, нужен именно адрес.
printf("%04X %04X", &__my_tbl_start, &__my_tbl_end);
PS: Да, сначала разобрался, а потом прочитал ваше сообщение, где уже проверили этот вариант...
Думается в программе именно к этим символам доступ не получить никак - это же линковщик.
Надо действовать обычными путями.
Исходя из моего понимания можно:
1) задать фиксированный адрес секции при линковке, а адрес передавать через дефайн в исходники;
2) в основной программе, точнее в первом модуле при общей сборке, объявить в той же секции переменную, она будет там первая - взять её адрес.
3) создать асемблерный (.S) файл, где разместить глобальную метку в нужной секции, в общую линковку ставить этот файл первым, в исходнике через extern.
Добавлено after 2 hours 25 minutes 1 second:
Мои представления были не точны.Kavka писал(а):Думается в программе именно к этим символам доступ не получить никак
ARV, это ж адрес! Метка сама по себе не резервирует память. Поэтому тип указанный в extern в упомянутом случае смысла не имеет, нужен именно адрес.
printf("%04X %04X", &__my_tbl_start, &__my_tbl_end);
PS: Да, сначала разобрался, а потом прочитал ваше сообщение, где уже проверили этот вариант...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
благодарю за желание помочь
я уже вовсю пользуюсь этим методом - мне нравится.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
[uquote="ARV",url="/forum/viewtopic.php?p=3562455#p3562455"]линкер отсортирует элементы таблицы так, что "CMD" всегда будет попадаться при переборе первой, и сравнение начала входной строки с этой командой будет происходить всегда, даже если в строке указана команда "CMD1"...[/uquote]Хм... Если я правильно понимаю, то строки объявлены как ASCIIZ, а сравнение строк осуществляется в написанной программе. И если это так, то частичное совпадение в начале имени команды может быть проблемой только при определённом способе сравнения. Если проверять строку полностью (с учётом их длины), то это не должно быть проблемой.
Или тут опять какие-то подводные грабли?

Или тут опять какие-то подводные грабли?
Для этого, ведь, тут и тусуемсяARV писал(а):благодарю за желание помочья уже вовсю пользуюсь этим методом - мне нравится.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
я тут дальше продолжаю думать в направлении секций памяти... по-моему, отличные перспективы автоматизации рутины открываются!Kavka писал(а):Для этого, ведь, тут и тусуемся
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 567
- Зарегистрирован: Ср дек 19, 2012 12:16:22
А есть какие то ньюансы по использованию _delay_ms()? воткнул в начало прошивки - и прошивка не стартует в мк, хотя далее по тексту в самой прошивке процедура задержки используется и используется успешно. Удаляешь строку с паузой и все норм.
никаких нюансов нет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 567
- Зарегистрирован: Ср дек 19, 2012 12:16:22
Есть плата. Долго рассказывать, но смысл в том что мне надо что бы она "стартовала" с небольшой задержкой, иначе происходит ложное срабатывание датчика. После ряда инициализаций втыкаю паузу _delay_ms() и прошивка умирает. В протеусе в симуляторе все работает, то есть пауза и понеслось. Куда смотреть то? В чем может быть дело? Пробовал по разному, в разных местах....
Код в начале вот такой:
PS тинька2313, sut=10 пробовал - мало
Код в начале вот такой:
Код: Выделить всё
unsigned char butt_on_state=WAVE_ALW_ON_LOW,
butt_off_state=WAVE_ALW_OFF_LOW,
st_t=0;
int tmrLo=0, //счетчик таймера понижения яркости
tmrOff=0, //счетчик таймера включения/отключения света
tmrTun=0; //счетчик таймера настройки света
unsigned char is_tune=0, //признак того что регулируют яркость и не надо выключать свет
state_butt; //Состояние главного конечного автомата кнопки (общий для двух)
DDRA=0x00;
DDRB=0x07;
DDRD=0x01;
PORTD=0x00;
for (unsigned char i=0;i<SP_COUNT;i++) arSteps[i]=0;
TCNT0=0;
TCCR0B = (0<<CS02)|(0<<CS01)|(1<<CS00);
TIMSK |= (1<<TOIE0); // разрешаем прерывание по переполнению таймера (ШИМ)
sei();
TCNT1=0;
TCCR1B = (0<<CS12)|(0<<CS11)|(1<<CS10);
TIMSK |= (1<<TOIE1); // разрешаем прерывание по переполнению таймера
/*задержка в одну секунду что бы датчики в себя пришли*/
_delay_ms(1000);
MCUCR = (1<<ISC00)|(0<<ISC01)|(1<<ISC10)|(0<<ISC11); // прерывания по изменению уровня INT0 или INT1
GIMSK = (1<<INT0)|(1<<INT1);
state=IDLE;
state_butt=BUTTON_NOT_PRESS;А значение F_CPU определено в программе?
- Сообщения: 43
- Зарегистрирован: Ср мар 15, 2017 18:52:10
Доброго времени суток. Есть такая проблема: есть ли в WinAvr (и avr-gcc, соответственно) возможность по умолчанию разместить некий массив данных в EEPROM контроллера, причём начиная с определённого адреса? Нужно вывести на HD44780 пользовательские символы, и я хочу немного сэкономить ресурсы за счёт помещения символов в энергонезависимую память. Однако строка типа
как я понимаю, будет перезаписывать массив при каждом выполнении программы, да ещё и начиная с нулевого адреса. В PIC-ах, например, можно заранее указать данные EEPROM, которые будут записаны туда единожды при прошивке контроллера и размещены по указанным адресам, минуя основную память. Как сделать то же самое в AVR (в моём случае - AtMega8), я так и не нашёл.
Код: Выделить всё
uint8_t EEMEM some_array[64];


