Открытый проект универсального зарядника
Облазил все файлы не могу найти где посмотреть в какой вид памяти указатели на строки разместились.
И вообще где смотреть размер и расчет стэка, кучи и т.д.
Должна же быть там какаянибудь подбивка итогов?
Использую только
#incl*ude <avr/io.h>
#incl*ude <avr/fuse.h>
#incl*ude <avr/interrupt.h>
#incl*ude <avr/pgmspace.h>
#incl*ude <avr/eeprom.h>
#incl*ude <avr/wdt.h>
Написал свое определение битов ног проца по совету старших товарищей.
Теперь можно в ноги писать и читать по названию как в IAR
Пока не проверял, но компилятор пропускает.
Идею содрал из другого форума
Мог напортачить только с номером(адресом) порта их бывает 2, но кажись не напортачил.
typedef struct _bit_struct {unsigned char Bit0:1, Bit1:1, Bit2:1, Bit3:1, Bit4:1, Bit5:1, Bit6:1, Bit7:1; }bit_field;
#ifdef PORTA
#define PORTA_Bit0 (*((volatile bit_field*) (PORTA))).Bit0
#define PORTA_Bit1 (*((volatile bit_field*) (PORTA))).Bit1
#define PORTA_Bit2 (*((volatile bit_field*) (PORTA))).Bit2
#define PORTA_Bit3 (*((volatile bit_field*) (PORTA))).Bit3
#define PORTA_Bit4 (*((volatile bit_field*) (PORTA))).Bit4
#define PORTA_Bit5 (*((volatile bit_field*) (PORTA))).Bit5
#define PORTA_Bit6 (*((volatile bit_field*) (PORTA))).Bit6
#define PORTA_Bit7 (*((volatile bit_field*) (PORTA))).Bit7
#endif
#ifdef DDRA
#define DDRA_Bit0 (*((volatile bit_field*) (DDRA))).Bit0
#define DDRA_Bit1 (*((volatile bit_field*) (DDRA))).Bit1
#define DDRA_Bit2 (*((volatile bit_field*) (DDRA))).Bit2
#define DDRA_Bit3 (*((volatile bit_field*) (DDRA))).Bit3
#define DDRA_Bit4 (*((volatile bit_field*) (DDRA))).Bit4
#define DDRA_Bit5 (*((volatile bit_field*) (DDRA))).Bit5
#define DDRA_Bit6 (*((volatile bit_field*) (DDRA))).Bit6
#define DDRA_Bit7 (*((volatile bit_field*) (DDRA))).Bit7
#endif
#ifdef PINA
#define PINA_Bit0 (*((volatile bit_field*) (PINA))).Bit0
#define PINA_Bit1 (*((volatile bit_field*) (PINA))).Bit1
#define PINA_Bit2 (*((volatile bit_field*) (PINA))).Bit2
#define PINA_Bit3 (*((volatile bit_field*) (PINA))).Bit3
#define PINA_Bit4 (*((volatile bit_field*) (PINA))).Bit4
#define PINA_Bit5 (*((volatile bit_field*) (PINA))).Bit5
#define PINA_Bit6 (*((volatile bit_field*) (PINA))).Bit6
#define PINA_Bit7 (*((volatile bit_field*) (PINA))).Bit7
#endif
и т.д.
синусы косинусы степени и тд тоже нет у меня только умножение и деление флоат
по этому поводу думаю вообще от флоат отказаться и перейти на long=float*1000Но здесь есть подводный камень. Например суммирование интегрального полученного/отданного заряда. Точность уплывет.
Всвязи с этим решил переписывать все так как вижу много кривых мест в старой проге.
И по мере переписи контролировать память.
при компиляции смотреть на окно вывода, там видно сколько кода\данных (ну можно еще начало *.lss посмотреь)
описали переменную\константу, запомнили сколько было - скомпилировали, посмотрели сколько стало.
если просто написать строка=‘АБВГ’, то компилятор сосздаст ее в озу, и стартапом скопирует в нее это АБВГ, что весьма криво.
код получается весьма плотный, глядя по листингу видно. иногда на входе в функцию пара команд бывает, которые мне несовсем понятно зачем нужны, но все смотреть просто смысла нет.
мелкий совет - если совсем с памятью кода туго, строки в еепром можно засунуть частично. или внешнюю и2ц на 64кб прицепить под текст меню 😃
Как в WinIar сделать над переменной то, что в ассемблере делает “swap”
Пришлось сделать так:
/* Swap BYTE*/
#define __swap_nibbles(_x) ({BYTE _y=_x; asm volatile(“swap %0” : “=&r” (_y) : “0” (_y)); _y;})
И еще для перехода c IAR на WinAvr
/* Set BIT in ADDRESS */
#define SETBIT(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT)))
/* Clear BIT in ADDRESS */
#define CLEARBIT(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT)))
/* Test BIT in ADDRESS */
#define TESTBIT(ADDRESS,BIT) ((ADDRESS) & (1<<(BIT)))
Как в WinAvr работать с фузами
Стандартный пример не компелится
#incl*ude <avr/io.h>
#incl*ude <avr/fuse.h>
FUSES =
{
.low= // Запрограммированные фузы
(
CKOPT& // рекомендуется для зашумленных приборов и для частот больше 8 МГц
BODEN& // разрешить реагирование на уровень напряжения. Для стабильного запуска и защиты от порчи EEPROM.
BODLEVEL // минимальный уровень напряжения 2.7в. Для стабильного запуска и защиты от порчи EEPROM.
),
.high= // Незапрограммированные фузы
(
CKSEL3&CKSEL2&CKSEL1&CKSEL0& // Частота определяется внешним кварцевым резонатором
SUT0&SUT1& // 65мс медленный старт процессора
BOOTRST& // Стартовать из обычного вектора, а не из BOOT-а
BOOTSZ0&BOOTSZ1& // размер бутовой программы безразличен
EESAVE& // EEPROM не защищен
SPIEN& // SPI не важно разрешен или нет
OCDEN& // встроенный отладчик запрещен
JTAGEN // JTAG запрещен
),
};
main.cpp:31: error: expected primary-expression before ‘.’ token
main.cpp:37: error: expected primary-expression before ‘.’ token
make.exe: *** [main.o] Error 1
Как в WinAvr работать с фузами
даже никогда не думал, что в проекте можно фьюзы описывать…
делаю так:
использую AVREAL (просто замечательный программатор Александра Редчука)
в директории с проектов держу несколько bat файлов - для программирования с прошивкой фьюзов, просто для программирования, и для ресета.
вызов бат-афйлов для программирования и ресета прописаны в иде, чуть ниже маке-алл строчки в меню
программирование фьюзов делаю один раз, при начале работы с новым кристаллом\платой, при отладке только флеш переписываю
под тиражирование бат-файл программирования с прошивкой фьюзов применяется.
вот пример содержимого этих 3-х файлов (1 строка в каждом)
avreal32 -p1 -as -o1000 +mega32 -ew eth_sr.hex -fCKSEL=F,JTAGEN=1,CKOPT=0
avreal32 -p1 -as -o8000 +mega32 -ew eth_sr.hex
avreal32 -p1 -as -o8000 +mega32
Почти ничего не получается:
- Побитовое обращение не работает PORTD_Bit3=PORTC_Bit7.
- AVRstudio elf глючит как хочет меняет содержимое переменных и т.д.
- Работа с флэш памятью требует извратов несовместимых со здравым смыслом
const char FlashString[] PROGMEM = “This is a string in flash”; - обявление переменной во флаш
SendSTR_P(FlashString); - макрос который ее туда суёт - ФУЗЫ описать не удается компилятор обругивает.
Что удалось:
- Удалось написать мааленькую прогу на которую компилятор не ругался.
- Удалось через аврдуду и понипрог ее залить в проц.
В иаре все сделано красиво и логично. Одно слово __flash решает все возможные проблемы с работой флаш памяти.
НО
Данный продукт поставляется только под заказ, т.к. везется из-за границы (срок поставки примерно 6-8 недель)
(27-14-19-IAR-SL) Atmel AVR Stand Alone License Baseline - 1437$ на 1 рабочее место.
(В стоимость лицензии входит доставка из-за рубежа)
Вопрос: Имеет ли право с этой лицензией разработчик распространять разработанные им на указанном ПО программы(прошивки)?
Ответ: Да, имеет.
Устовия оплаты:
Оплата производится по безналичному расчету в рублях по курсу ЦБ+3%
ООО “Ваш Софт”
тел/факс: (495) 153-64-91, 153-94-41 www.yoursoft.ru
ICQ: 404-454-431
На ихнем сайте оптовая цена 1179$
Теперь представим себе как за 6-8 недель можно доставить коробочку за 250$ ?
Ответ на велосипеде!!!
Заработало таки.
- Побитовое обращение не работает PORTD_Bit3=PORTC_Bit7.
- AVRstudio elf глючит как хочет меняет содержимое переменных и т.д.
- Работа с флэш памятью требует извратов несовместимых со здравым смыслом
const char FlashString[] PROGMEM = “This is a string in flash”; - обявление переменной во флаш
SendSTR_P(FlashString); - макрос который ее туда суёт- ФУЗЫ описать не удается компилятор обругивает.
В иаре все сделано красиво и логично. Одно слово __flash решает все возможные проблемы с работой флаш памяти.
побитовое обращение: PORTD_Bit3=PORTC_Bit7 подразумевается из выходного регистраЦ берем бит, и пишем в выходной регистрД ? читать желательно из PINC…
большинство “НЕРАБОТАЕТ!!!” решаются так - смотрим в asm-листинг выхода компилятора, и понимаем где накосячили…
а по работе с флеш, изврат скорей в иаре (с точки зрения программирования на С) - мы для микроконтроллера пишем, и от его архитектуры нам не уйти, просто уровень, до которого она прячется от программиста разный. в любом случае, а=байт_из_флеш(адрес) транслируется в инструкцию LPM, иар это делает сам, видя модификатор, а в gcc надо один раз описать макрос, и объявление из пары строчек. один раз на проект! как - было показано.
про аврстудию ничего подсказать не смогу, ниразу не пользовался.
зачем компилятору фьюзы? например, зачем компилятору знать, кварц или керамический резонатор у вас стоит, от этого кодогенерация поменяется?
мой способ работы с винавр:
работаю в штатном ИДЕ (программернотепад) - вполне устраивает, и заморачиваться с настройкой не надо.
маке-файлы правлю в ручную, на один проект исправить пару-тройку строк не напрягает (имя исходников и проц)
программирую с помощью AVREAL (привычка, и гарантированный результат и скорость работы)
отладка - шнурок в ком и терминал или модбас-читалка\писалка, симуляторы меня не устраивают, надо с реальным железом взаимодействовать.
Нашел таки их документацию и прочитал все более менее понятно, но не все.
Все заработало! Хотя и с извратами.
Вот что удалось нарыть по обращению к FLASH флаш на WinAvr
Вот как объявляются символ знаковый во флаш памяти:
char c PROGMEM=‘a’; // Оба варианта одинаковые по смысловой нагрузке
prog_char c=‘a’; // Этот вариант предпочтительнее из-за глюков компилятора
Вот как объявляются символ беззнаковый флаш памяти:
unsigned char c PROGMEM=‘a’; // Оба варианта одинаковые по смысловой нагрузке
prog_uchar c=‘a’; // Этот вариант предпочтительнее из-за глюков компилятора
В теле самой программы содержимое читается так:
pgm_read_byte(&c);
Объявление массива:
char c[] PROGMEM=“adfgseged”; // Оба варианта одинаковые по смысловой нагрузке
prog_char c[]=“dddhfhf”; // Этот вариант предпочтительнее из-за глюков компилятора
В теле самой программы содержимое читается так:
pgm_read_byte(&c[3]);
или блоком всю строку strcpy_P(buffer_RAM, с);
Объявление массива указателей на строки только так и ни как иначе:
prog_char c1[]=“dddhfhf”; // Именно в этом месте компилятор глючит
prog_char c2[]=“dddhfhf”; // Если объявить char c[] PROGMEM=“rgererger”;
prog_char c3[]=“dddhfhf”; // То компилятор ругается что строка не инициализирована
prog_char c4[]=“dddhfhf”;
prog_char c5[]=“dddhfhf”;
prog_char c6[]=“dddhfhf”;
PGM_P PROGMEM cc[]={c1,с2,с3,с4,c5,c6}; // Если убрать слово PROGMEM или переставить его в начало указатели разместятся в RAM
В теле самой программы содержимое читается так:
Пятая буква из третьей строки pgm_read_byte(&cc[3][5]);
или блоком всю 3 строку strcpy_P(buffer_RAM, (PGM_P)pgm_read_word(&(cc[3])));
Что касается обращения к битам по названию тоже победил.
Я предлагал НЕПРАВИЛЬНО делать так:
typedef struct _bit_struct {unsigned char Bit0:1, Bit1:1, Bit2:1, Bit3:1, Bit4:1, Bit5:1, Bit6:1, Bit7:1; }bit_field;
#ifdef PORTA
#define PORTA_Bit0 (*((volatile bit_field*) (PORTA))).Bit0
#define PORTA_Bit1 (*((volatile bit_field*) (PORTA))).Bit1
#define PORTA_Bit2 (*((volatile bit_field*) (PORTA))).Bit2
#define PORTA_Bit3 (*((volatile bit_field*) (PORTA))).Bit3
#define PORTA_Bit4 (*((volatile bit_field*) (PORTA))).Bit4
#define PORTA_Bit5 (*((volatile bit_field*) (PORTA))).Bit5
#define PORTA_Bit6 (*((volatile bit_field*) (PORTA))).Bit6
#define PORTA_Bit7 (*((volatile bit_field*) (PORTA))).Bit7
#endif
А надо было делать так:
#ifdef PORTA
#define PORTA_Bit0 (*((volatile bit_field*) (0x3b))).Bit0
#define PORTA_Bit1 (*((volatile bit_field*) (0x3b))).Bit1
#define PORTA_Bit2 (*((volatile bit_field*) (0x3b))).Bit2
#define PORTA_Bit3 (*((volatile bit_field*) (0x3b))).Bit3
#define PORTA_Bit4 (*((volatile bit_field*) (0x3b))).Bit4
#define PORTA_Bit5 (*((volatile bit_field*) (0x3b))).Bit5
#define PORTA_Bit6 (*((volatile bit_field*) (0x3b))).Bit6
#define PORTA_Bit7 (*((volatile bit_field*) (0x3b))).Bit7
#endif
Такое определение битов-ног проца очень удобно.
Добавив в тело проги эти строки можно легко перейти с IAR на WinAVR “касательно ног”
В комплект winavr входит avrdude - как оказалось удобная штука.
Т.к. в моей плате разведен понипрог, программирование происходит зашибись прямо из оболочки PN.
Оч удобно: исправил, скомпилил, прошил, проверил.
Тока вот еепром и фузы еще не смог пока приладить.
Процесс планомерно приближается к завершению программы.
НО есть трудности:
В WinAvr есть 5 уровней оптимизации 0,1,2,3,s
При оптимизации “0” работает.
При оптимизации “1” или “s” не работает.
Кто нибудь сталкивался???
Победил!
Отвечаю на свой вопрос:
При оптимизации WinAvr выбрасывает из подпрограммы все присвоения (в том числе и глобальным переменным), если эта переменная не читается в данной подпрограмме.
Проблема решается описанием глобальной переменной словом VOLATILE
Победил!
Отвечаю на свой вопрос:
При оптимизации WinAvr выбрасывает из подпрограммы все присвоения (в том числе и глобальным переменным), если эта переменная не читается в данной подпрограмме.Проблема решается описанием глобальной переменной словом VOLATILE
ну так это и есть оптимизация с точки зрения компилятора, убрать все лишнее(и присвоения тоже), ему же не извесно где в последствии будут нужны эти присвоения, об этом ему нужно сообщать, что такая переменная в оптимизации не участвует, примочка С.
Если переменная объявлена вне всех программ и подпрограмм, значит ее юзают все подпрограммы.
Глупо все присвоения на нее выбрасывать из подпрограмм где ее не читают.
В ИАРе этот вопрос решен правильно.
С другой стороны в смысле оптимизации дурацких программ где программеры присваивают глобальным переменным че попало и непользуют их???
В данном случае WinAvr-овцы решили заделать по своему. Но это не “здравый смысл”.
И вместо исправления ошибки описали ее решение в факе.
И что теперь все глобальные переменные мне надо описывать volatile.
Вроди бы проблема решена, но на ней спотыкаются все новички и если они не читают по аглицки факи и надо додуматься еще в фак залезть.
Мнемоника чужая бысстро допереть не получается.
Если охватить всю проблему на более высоком уровне: “Юзера-WinAvr-Переход с другого компилятора-Гимор”, то данное решение не оптимально для людей.
Сколько народу тра…сь с отладчиками и убивали драгоценное время на спотыкание на ровном месте? А сколько свихнулось?
Ну а если еще шире смотреть “Люди и Плоды их рук и мозгов”, то может и правильно что кругом бардак, воспитывающий и натаскивающий людей на внимательность и трезвость.
Сегодня собрал на макетке очередную версию сепика…
в этот раз с одним ключем и одним дроселем работает, из 11.5 производит 23v 4.5А дальше развивать успех отказывается, при запирании возбуждается затвор… пока затвор не возбуждается производит только электричество тепла почти не производит… много думал…
пришел к выводам…
1 макетка себя пережила надо делать пробную плату.
2 надо как-то изголиться и заказать в чипедипе правильных шимок.
3 надо запирать ключ минусом, как учили в школе.
4 где купить НОРМАЛЬНЫЕ драйвера, непонятно.
Ключ - это полевик что-ли? так ему для запирания никакой минус не нужен. Вот совсем-совсем не нужен.
А в чем проблема с покупкой нормальных драйверов? 😉
Ключ - это полевик что-ли? так ему для запирания никакой минус не нужен. Вот совсем-совсем не нужен.
А в чем проблема с покупкой нормальных драйверов? 😉
ну если Вы не вкурсе, то полевики при 0v затвор-исток могут при определенных обстоятельствах самопроизвольно открываться, самое распространееное условие это отрицательная температура кристала. для этого в “нормальных” драйверах предусмотрено запирание “минусом”. по тойже причине микросхеммуделятся на текоторые можно использовать до 0 и на те которые работают при минусе забортом. пример очень распространенная UC3842 стоит во всей бытовой технике, а вот в сварочный аппарат ставится 2842 😃 расчитанная для работы при “минусе”. в нашем случае девайс портативный зимние полетушки/покатушки никто не отменял вот и приходится думать о том чтоб этот девайс в руках у народа не взрывался 😃
проблема в том что 1А на заряд затвора ну никак в данной конструкции не устраивает… надо зарядить емкость в 3-4нф да потом перезарядить его вминус 1-2в по причинам указанным выше.
сегодня товарищь все митино облазил, на прошлой неделе искал нетути “правильных” драйверов лежит один IR у всех, а поведение с таким драйвером я уже описывал + к сказанному выше видно ступеньку при прохождении плато миллера надо постараться уложиться в 60-100 наносекунд иначе утюг, а не зарядник получится… в чипе дипе одни H/L лежат на 600в да еще и тормозные , а из нижних полный хлам… надо что нить типа EL7154
в принципе на 2х ключах 50n06 я эту штуку до 170W раскочегарил с драйверами ir2121 но это не езда, а скорее ерзанье.
вот такие вот грусные мысли… топать мне сними в интернет магазины…и ждать потом 2-3 недели. 😦
Про рабочие диапазоны температур компонентов мне можно не рассказывать - сам разрабатываю электронику.
Раз Вы уверены, что нужен минус (самому вникать - времени нет), попробую дать совет 😃
Если переменная объявлена вне всех программ и подпрограмм, значит ее юзают все подпрограммы.
Глупо все присвоения на нее выбрасывать из подпрограмм где ее не читают.
В ИАРе этот вопрос решен правильно.В данном случае WinAvr-овцы решили заделать по своему. Но это не “здравый смысл”.
И вместо исправления ошибки описали ее решение в факе.
И что теперь все глобальные переменные мне надо описывать volatile.
Уважаемый R2D2! “WinAvr-овцы” сам компилятор не писали, а сделали сборку GCC - комплекта для _ПРОСТОЙ_ работы под виндами. соответствие компилятор стандартам очень жесткое, куча “маньяков” свободного софта по всему миру мечтает найти несоответсвие или баг, и прославить этим свое имя на вечные времена…
по поводу volatile - типичный пример: в прерывании если переменная не ноль, уменьшаем ее на единицу, а в другом месте программы присваиваем ей значение, а далее выполняем цикл до ее обнуления (проще говоря задержку делаем, попутно делая что-нибудь полезное). при любой оптимизации, компилятор (если ему не сказать volatile) логично сообразит, что в теле цикла переменная не меняется, и просто проигнорирует ее.
еще раз советую просматривать asm-листиг после компиляции, очень помогает в повышении качества кода. например, помогает понять, когда надо явно указывать преобразование типов, код в 2-3 раза можно ужать.
Про рабочие диапазоны температур компонентов мне можно не рассказывать - сам разрабатываю электронику.
Раз Вы уверены, что нужен минус (самому вникать - времени нет), попробую дать совет 😃
1 +1 😃
2, я вкурсе все равно большое спасибо
3 спасибо буду посмотреть 😃
Не хотел наезжать на WinAvr. Молодцы что сделали бесплатный и тем не менее замечательный компилятор.
Наверное просто был под впечатлением очередног гимора, связанного с переходом, и невозможностью двигаться дальше из-за какойто непонятной фигни.
На Borlande C++, Pacal, … и все прочие языи на большом компе не покушаются на глобальны перемнные. И затем ИАР тоже не проявил таких тендений. Вот я грешным делом и подумал.
А зачем их выкидывать? Таким образом можно выкидывать не только переменные но и целые куски кода для оптимизации и при этом обязать прогаммера следить за его кусками в асм-листинге
и особым способом помечать все куски кода “Я написал эти куски шоб они работали” и потом подтвердить “я действительно хочу шоб оптимизатор не выкидывал эти куски”.
И всетаки мне кажется что это нелогично. Я допускаю, что чегото не понимаю. И могу найти оправдание для токого пведения следующее:
- GCC был адаптирован под АВР и просто не получилось по человечески это сделать (без всяких там дполнительных типов) из-за особенностей GCC. Собственно пчему они этот вопрос в факе и бъясняют первым, потому как их наверно задолбали с этим.
- Сущестуют такие примеры подпрограмм, где программер осущесвяет присвоение глобальной переменной значение, а компилятор не включает это присвоение в конечный код и при этом программа работает как хотел программер. ??? 😂
😃 Сегодня нашел таки комплектуху вот здесь www.elbase.ru не выпендриваются, что типа заказ уних от 1000р и тд и тп. цены помоему вполне демократичные. заказал. едет. тем временем в программе, не скажу какой, рисовал схему и патерны. пока пробную, сплошные непонятки с ОС.
как замешивать то, что идет с шунта и с проца пока в карандаше не придумал. похоже нарисую площадок и дырок(пардон отверстий), и буду сооружать… поместу. блин, а туда ведь еще по напряжению защиту надо подмешать…
спецы по ОУ могут предлагать варианты решения. шим будет такой: LM3488MM . шунт 0.02ОМ с него есть пропорционально усиленный сигнал от 0 до 5 в.
с проца напраяжение 0-5в. защита по максимальному напряжению с резисторного делителя.
да R2D2, сигнал вгключения преобразователя - логический 1. там в мануале на шимку есть типовое включение.