WinAvr в вопросах и ответах
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
пока писал - опередили
и предложили "решение в лоб" - третий способ
в сущности, мой первый вариант мало отличается от этого...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- krolaka
- Нашел транзистор. Понюхал.
- Сообщения: 169
- Зарегистрирован: Пн мар 02, 2009 12:23:37
- Контактная информация:
обясните почему себя так ведет sprintf вот привожу пример програмы
char yf[];
.....
char year,year_10, year_1
.....
year_10=(bq32000_addr[6]&0b11110000)>>4;
year_1=bq32000_addr[6]&0b00001111;
sprintf(yf,"%2i%2i",year_10,year_1);
lcd_puts(yf);
выводит мне 5853 вместо 2010 да и вобще любое схожое число там пишет не пойму почему
в переменуюю специально записал bq32000_addr[6]=0b00101010;
char yf[];
.....
char year,year_10, year_1
.....
year_10=(bq32000_addr[6]&0b11110000)>>4;
year_1=bq32000_addr[6]&0b00001111;
sprintf(yf,"%2i%2i",year_10,year_1);
lcd_puts(yf);
выводит мне 5853 вместо 2010 да и вобще любое схожое число там пишет не пойму почему
в переменуюю специально записал bq32000_addr[6]=0b00101010;

krolaka писал(а):обясните почему себя так ведет sprintf вот привожу пример програмы
В первую очередь рекоммендую явно задать размер массива yf - пять символов, ибо sprintf ввыводит в память строку с завершающим символом '\0'.
А вообще что-то не пойму логики, зачем какие-то операции над year_10 и year_1 и зачем вообще эти переменные? Не проще так:
Код: Выделить всё
char yf[5]
uint16 year;
year=2010;
sprintf(yf, "%.4i", year)В качестве полезного совета предлагаю сначала отладить sprintf на строке из чисел, а потом переходить к преобразованиям.
Как врубить поддержку c++ в проектах ??
Хотел перейти с IAR на WINAVR а тут такой касяк =((
Помогите плизз!! =)
Хотел перейти с IAR на WINAVR а тут такой касяк =((
Код: Выделить всё
#include <avr>
#include <avr>
#include <avr>
class Test
{
public:Test();
};
Test::Test(){}
int main()
{char *a=new char [2];}Код: Выделить всё
avr-gcc -mmcu=atmega2560 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d -c ../main.c
../main.c:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'
../main.c:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
../main.c: In function 'main':
../main.c:12: error: 'new' undeclared (first use in this function)
../main.c:12: error: (Each undeclared identifier is reported only once
../main.c:12: error: for each function it appears in.)
../main.c:12: error: expected ',' or ';' before 'char'
../main.c:12: warning: unused variable 'a'
make: *** [main.o] Error 1
Build failed with 6 errors and 1 warnings...
Помогите плизз!! =)
пробовал
класс прошёл, но дин массив нет =(( .
Код: Выделить всё
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
../main.cpp: In function 'int main()':
../main.cpp:9: warning: unused variable 'a'
avr-g++ -mmcu=atmega2560 -Wl,-Map=AVRWIN001.map main.o -o AVRWIN001.elf
main.o: In function `main':
S:\AVRWIN001\default/../main.cpp:9: undefined reference to `operator new[](unsigned int)'
make: *** [AVRWIN001.elf] Error 1
Build failed with 1 errors and 2 warnings...
класс прошёл, но дин массив нет =(( .
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
"Вы будете смеяться", но нужно дать файлу расширение .cpp
Можно, конечно, дать ключ
но логичнее просто дать расширение, соответствующее языку.
Пример использования С++ для avr-gcc можно посмотреть тут
Правда, там new не используется.
Ещё полезное место - тема о С++ в avr-gcc на avrfreaks
Можно, конечно, дать ключ
Код: Выделить всё
avr-gcc -x c++ -c main.cПример использования С++ для avr-gcc можно посмотреть тут
Правда, там new не используется.
Ещё полезное место - тема о С++ в avr-gcc на avrfreaks
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
хех флаг
надо было добавить =)), но ошибка все равно есть
вот мой Makefile
Использую связку AVR studio + WinAVR-20100110.
Код: Выделить всё
-x c++надо было добавить =)), но ошибка все равно есть
Код: Выделить всё
S:\AVRWIN001\default/../main.c:18: undefined reference to `operator new[](unsigned int)'
вот мой Makefile
Использую связку AVR studio + WinAVR-20100110.
- Вложения
-
- Makefile.zip
- Makefile
- (1004 байт) 303 скачивания
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Я всё же рекомендую использовать не этот флаг, а правльное расширение - если файл будет main.cpp, то єтот флаг не нужен. В проекте по разным соображениям может возникнуть желане применить и С-шные файлы (свои или чужие) и по расширению "драйвер" avr-gcc разберётся и применит нужный компилятор, а ключ смешивает всё в одну кучу.
операторов new и delete нет в библиотеке, их проблематично сделать полностью соответствующими стандарту (кто и куда будет выбрасывать исключение по нехватке памяти std::bad_alloc ? исключения для AVR пока вообще не предусмотрены и я себе плохо представляю их необходимоть) и они отданы на откуп пользователю.xVekx писал(а):но ошибка все равно есть
Код: Выделить всё
S:\AVRWIN001\default/../main.c:18: undefined reference to `operator new[](unsigned int)'
В простейшем варианте new/delete предлгается сделать через malloc/free.
Посмотрите ту тему на avrfreaks.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
А есть какие-нибудь рекомендации по уменьшению размера сгенерированного кода? Компилирую с оптимизацией по размеру (-Os), extern перед функциями я расставил, -fno-inline в опции компиляции добавил, но всё равно код еле-еле в 2к умещается. Если надо будет добавить дополнительную функциональность, то это будет затруднительно.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
рекомендаций много
extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает). вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...
если вы программируете не очень аккуратно и у вас имеются функции, которые просто "для запаса" содержатся в тексте - они будут включены в код, хотя по сути лишние. так вот, убрать их можно опцией компилятора -ffunction-sections и опцией линкера -Wl,-gc-sections - для "мусорного кода" очень большой эффект!
вчера из проекта с кодом в 2038 байт сумел сделать 1930 байт путем замены некоторых статических глобальных переменных на регистровые.
WinAVR не может похвастаться сверхоптимальным кодом для работы с битовыми полями, особенно когда эти поля знаковые или многобитные. но если структура с битовыми полями умещается в регистре или паре регистров, то сделав ее регистровой переменной вы получите заметный выигрыш. часто можно отказаться от однобитовых полей, заменив их отдельными байтовыми переменными или полями в структуре - если ОЗУ хватает, то скорее всего получите выигрыш в размере кода.
используйте для функции main() атрибут OS_main. помните о том, что если вы описываете статическую или глобальную переменную и сразу инициализируете ее ненулевым значением, то это самое значение приплюсуется к коду. подумайте, действительно необходимо это делать или можно обойтись нулевым значением по умолчанию.
посмотрите, реально ли необходимо иметь в функциях более одного параметра? действительно ли необходимы типы int и long? можно ли обойтись uint8_t или нет? не используйте float и double - для проектов на tiny ничего хорошего не выйдет скорее всего из этой попытки...
есть и еще тонкости, которые все я не помню, хотя дома записано многое
extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает). вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...
если вы программируете не очень аккуратно и у вас имеются функции, которые просто "для запаса" содержатся в тексте - они будут включены в код, хотя по сути лишние. так вот, убрать их можно опцией компилятора -ffunction-sections и опцией линкера -Wl,-gc-sections - для "мусорного кода" очень большой эффект!
вчера из проекта с кодом в 2038 байт сумел сделать 1930 байт путем замены некоторых статических глобальных переменных на регистровые.
WinAVR не может похвастаться сверхоптимальным кодом для работы с битовыми полями, особенно когда эти поля знаковые или многобитные. но если структура с битовыми полями умещается в регистре или паре регистров, то сделав ее регистровой переменной вы получите заметный выигрыш. часто можно отказаться от однобитовых полей, заменив их отдельными байтовыми переменными или полями в структуре - если ОЗУ хватает, то скорее всего получите выигрыш в размере кода.
используйте для функции main() атрибут OS_main. помните о том, что если вы описываете статическую или глобальную переменную и сразу инициализируете ее ненулевым значением, то это самое значение приплюсуется к коду. подумайте, действительно необходимо это делать или можно обойтись нулевым значением по умолчанию.
посмотрите, реально ли необходимо иметь в функциях более одного параметра? действительно ли необходимы типы int и long? можно ли обойтись uint8_t или нет? не используйте float и double - для проектов на tiny ничего хорошего не выйдет скорее всего из этой попытки...
есть и еще тонкости, которые все я не помню, хотя дома записано многое
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Извиняюсь. Конечно же static. ОписАлся.ARV писал(а):рекомендаций много
extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает).
Да просто код короче в этом случае получился.ARV писал(а):вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...
За рекомендацию о глобальных переменных в регистрах спасибо. Буду пробовать
Что с новыми версиями WinAVR?
Здравствуйте, уважаемые!
Возникла небольшая проблемка с новыми версиями WinAVR.
Сидел на старой WinAVR-20060125, поскольку не требовалось пока ничего большего. Программатор ponyser. При разработке устройства перешел с Attiny26 на 461, avrdude старой версии ее не знает. Поэтому поставил свежий WinAVR-20100110...... без проблем откомпилировал, зашил программу и...ничего не работает...
Перепробовал разные версии WinAVR, перебрав с 20100110 по 20071221 - все то же! В итоге снова установил старую версию 20060125 и в avrdude.conf описал attiny461.
Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел
Возникла небольшая проблемка с новыми версиями WinAVR.
Сидел на старой WinAVR-20060125, поскольку не требовалось пока ничего большего. Программатор ponyser. При разработке устройства перешел с Attiny26 на 461, avrdude старой версии ее не знает. Поэтому поставил свежий WinAVR-20100110...... без проблем откомпилировал, зашил программу и...ничего не работает...
Перепробовал разные версии WinAVR, перебрав с 20100110 по 20071221 - все то же! В итоге снова установил старую версию 20060125 и в avrdude.conf описал attiny461.
Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел
Re: Что с новыми версиями WinAVR?
Оптимизация скорее всего. Нужно код смотреть. Сравни ассемблерный код по результату компиляции.Alex_Jet писал(а):Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
в новых версиях был такой грех: несколько раз менялись форматы функций для работы с EEPROM, причем менялись кардинально: аргументы функция переставлялись местами. в итоге вполне может оказаться, что исходник уже абсолютно не так собирается. последние три или четыре версии WinAVR уже одинаково все делают, но по сравнению с более древними факт может иметь место. возможно, есть и другие моменты, о которых я не знаю - сам-то я пользуюсь более-менее свежими версиями 2009 и 2010 годов.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Что с новыми версиями WinAVR?
Большего или не большего, но из старых (gcc 3.x.x) всё же 20060424 поприличнее.Alex_Jet писал(а):Возникла небольшая проблемка с новыми версиями WinAVR.
Сидел на старой WinAVR-20060125, поскольку не требовалось пока ничего большего.
А вот эти (gcc 4.x.x) несколько "агрессивнее" (но, тем не менее, в полном соответствии со стандартом С) оптимизируют код в том, что управляется ключевым словом volatile. В смысле чаще находят что выбросить, так как без volatile оно выглядит ненужным или переставить местами код.Alex_Jet писал(а):Поэтому поставил свежий WinAVR-20100110...... без проблем откомпилировал, зашил программу и...ничего не работает...
Перепробовал разные версии WinAVR, перебрав с 20100110 по 20071221 - все то же!
Для справки (в даном конкретном случае лучше ипользовать макросы из util/atomic.h - и писать меньше, и оибки такой из-за барьеров "memory" не будет, но на этом примере хорошо видно):
Код: Выделить всё
uint16_t vvar; /* надо бы volatile, но старые версии это прощали */
uint16_t foo()
{
uint16_t temp;
uint8_t sreg_copy = SREG;
cli();
temp = vvar;
SREG = sreg_copy;
}компилятор имеет право сделать где-то так
Код: Выделить всё
in r24, SREG
cli
out SREG, r24
lds r24, vvar
lds r25, vvar+1
retНе обязательно проблема в этом, но стоит обратить внимание.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Мужики, подскажите ПЛС по WinAVR(GCC). есть некий массив:
Вопрос: как мне обратиться к любому элменту массива по индексу а не по содержимому? Через "CASE" сопоставлять содержимое индексу?
Код: Выделить всё
volatile unsigned char vol_tda[] = {0x1C,0x1E,0x20,0x22,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F }; Вопрос: как мне обратиться к любому элменту массива по индексу а не по содержимому? Через "CASE" сопоставлять содержимое индексу?