CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

Сообщение Amstron »

Как узнать хватает ли оперативки в моем контроллере для вычислений?
Стоит добавить немного код программы , тогда начинает глючить.
После компиляции объем глобальных переменных равен 278 байт. Контроллер мега 168.
Объем программы 91 процент .
Реклама
Встал на лапы
Сообщения: 107
Зарегистрирован: Сб июл 27, 2013 10:52:37
Откуда: Украина

Сообщение Aмstroн »

Amstron писал(а):Стоит добавить немного код программы , тогда начинает глючить.
По всей видимости добавляете некорректный код, вот и глюк.
Реклама
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

Сообщение Amstron »

Aмstroн писал(а):
Amstron писал(а):Стоит добавить немного код программы , тогда начинает глючить.
По всей видимости добавляете некорректный код, вот и глюк.
Код нормальный. Взят из программы этойже. Не в нем дело.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2296
Зарегистрирован: Пн июл 14, 2008 18:12:37

Сообщение LINKS_234 »

здравствуйте. столкнулся с магией непонятной. после 4-ой студии магии стало ещё больше.
есть такой кусок кода :

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

unsigned flash char duty_cycle[32]={0,3,6,9,12,15,18,21,25,28,31,34,37,40,43,46,50,53,56,59,62,65,68,71,75,78,81,84,87,90,93,100};

void meas_duty(unsigned char m_duty)
{
unsigned char i=0;
unsigned char tmp_meas[3]={0,0,0};

    lcd_command(0x86);
    itoa(duty_cycle[m_duty],tmp_meas);

... 
   
    for (i=0;i<3;i++)
        {
        lcd_data(tmp_meas[i]);
        }
собственно проблема в том, что после itoa переменная m_duty обнуляется (и вроде как только при значении 31. меньшие значения отрабатываются нормально).

PS: версия вижна 2.05.0 Pro крякнутая NeVaDa
PPS: проверил со значением 30 - всё в норме. косяк только с 31. просьба решения в виде временных переменных не предлагать - набыдлокодить всегда успею. это у меня нормально получается. тем более если это баг или "фича", то хотелось бы в дальнейшем не повторять такие косяки.
СпойлерИзображение-------------Изображение
есть вопросы ? чего-то не знаешь ? [url=http://s61.radikal.ru/i174/1006/79/bc6a635c1451.jpg][color=blue][b]прежде всего смотри это[/b][/color][/url]
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

Размер tmp_meas должен быть 3 знака (для 100) + завершающий ноль = 4.
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Только хотел написать, что функции itoa то пофиг что буфер всего три символа вот она и начинает писать при duty_cycle[31] -->itoa(100) :
цифра,цифра,цифра,ноль начиная с адреса нулевого элемента вот и случайно при выходе за пределы выделенной памяти затирает вашу переменную, так как она создана при передаче параметра в функцию совсем рядом с только что созданным массивом( он ведь тоже локальный)
Вроде все правильно написал :roll:
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2296
Зарегистрирован: Пн июл 14, 2008 18:12:37

Сообщение LINKS_234 »

т.е. itoa пишет на один символ больше чем число ? т.е. при двухзначном числе получится 3 символа, при 3 - 4 и т.д. ? первый раз с таким сталкиваюсь и искренне не понимаю нахрена это сделано. а переменная действительно имеет адрес следующий за массивом.

спасибо за помощь. может есть какой-нибудь способ нормально конвертировать трёхзначное число в три символа, пользуясь стандартным itoa ?
есть вопросы ? чего-то не знаешь ? [url=http://s61.radikal.ru/i174/1006/79/bc6a635c1451.jpg][color=blue][b]прежде всего смотри это[/b][/color][/url]
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

тут можно почитать:
http://ru.wikipedia.org/wiki/Itoa_%28%D0%A1%D0%B8%29
на самом деле itoa - разложить число int на /1000, /100, /10 , /1 и добавить получившимся цифрам hex 0x30
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

LINKS_234 писал(а): и искренне не понимаю нахрена это сделано.
Если непонятно, то можно так сказать: строка это массив не нулевых значений, так как все буквы и цифры таблицы символов имеют не нулевое обозначение.Поэтому используют нулевой символ для обозначения конца строки.
Зачем это нужно?
Далее, чтобы вывести эту строку используют функции вывода строки такие как void lcd_puts(char *str) и другие.
Они чтобы не передавать параметр для числа выводимых символов просто выводят все символы массива, начиная с нулевого, пока они не равны нулю.
Если вам так важно, чтобы данный символ окончания строки не использовался, то необходимо всегда перед выводом заполнять ваш буфер пробелами, а потом с помощью самописной функции itoa просто помещать в данный буфер строку.

Проще принять как данное, и просто пожертвовать одним байтом RAM на пару секунд:))) Так как после выхода из вашей функции все равно буфер освободит данные.
oleg110592 писал(а):добавить получившимся цифрам hex 0x30
И развернуть строку :solder:
А можно в самой функции itoa предусмотреть отсчет назад :wink: Только опять же удобно при небольшой строке. Можно как при динамическом выводе считать просто и все.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2296
Зарегистрирован: Пн июл 14, 2008 18:12:37

Сообщение LINKS_234 »

спасибо за помощь. код на вики рассказал что в конце массива пихается null чтобы потом можно было юзать определение размера массива и переворачивать его. ошибочно полагал что там должен пихаться символ перевода каретки и он не может быть нулём. оказалось что не так казалось и всё встало на свои места.

vitalik_1984, спасибо и вам. сказывается незнание мелочей. касательно размерности массива - впихнуть-то можно, но я через неделю-две буду смотреть в свой же код и тупить по поводу что откуда там берётся и зачем оно. хотелось отделаться малой кровью, но и так нормально. можно, кстати, вообще переписать с вики код и не морочиться с либой stdlib, т.к. из неё я только itoa использую.
Последний раз редактировалось LINKS_234 Ср ноя 27, 2013 00:10:13, всего редактировалось 2 раза.
есть вопросы ? чего-то не знаешь ? [url=http://s61.radikal.ru/i174/1006/79/bc6a635c1451.jpg][color=blue][b]прежде всего смотри это[/b][/color][/url]
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Это если текстовый файл, то для окончания строки пихается символ каретки, а так - просто ноль.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

имхо лучше по взрослому использовать sprintf, громоздко но универсально, например для микроконтроллеров stm32 с sprintf голая программа занимает 2648 байт, без sprintf занимает 1848 байт - для таких микроконтроллеров это капля в море. Для AVR, опять имхо, лучше использовать самописные функции - типа как Чан: http://elm-chan.org/fsw/strf/xprintf.html.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2296
Зарегистрирован: Пн июл 14, 2008 18:12:37

Сообщение LINKS_234 »

с памятью проблем пока нету, но забивать её просто так не хочется. а sprintf вообще будет избыточна в моём случае.
есть вопросы ? чего-то не знаешь ? [url=http://s61.radikal.ru/i174/1006/79/bc6a635c1451.jpg][color=blue][b]прежде всего смотри это[/b][/color][/url]
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

LINKS_234 писал(а):касательно размерности массива - впихнуть-то можно, но я через неделю-две буду смотреть в свой же код и тупить по поводу что откуда там берётся и зачем оно.
А Вы напишите проще:

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

unsigned char tmp_meas[]="999";
Размер автоматически станет равным 4. Зато сразу видно, что на 3 цифры рассчитан.
PS.

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

for (i=0;i<strlen(tmp_meas);i++)
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 351
Зарегистрирован: Пн сен 12, 2011 12:13:46

Сообщение Garin »

Проблема , переношу один проект (который работает норм.) в другой, применяется переменная unsigned long int
выдает сообщение
Изображение
Это что в свойствах проекта нужно делать какие то настройки?
P.S. проект был CodeVisionAVRV2.04.4a теперь в CodeVisionAVRV2.05.3
Вложения
3.png
(9.68 КБ) 721 скачивание
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2296
Зарегистрирован: Пн июл 14, 2008 18:12:37

Сообщение LINKS_234 »

на варнинги можно не обращать внимания, если чётко знать что не будет переполнения переменных. все эти мессаги говорят о том, что при работе с 16-тибитной переменной возможно её переполнение при умножении и сложении. ну и компилятор говорит что возможно требуется переход к типу "long".
я ещё что-то не помню в cvavr типа long int. сам по себе int уже является 16-тибитным типом, а long - уже 32-битным. unsigned - беззнаковый. т.е. unsigned int - от 0 до 65535, а unsigned long - от 0 до 4 294 967 295.
есть вопросы ? чего-то не знаешь ? [url=http://s61.radikal.ru/i174/1006/79/bc6a635c1451.jpg][color=blue][b]прежде всего смотри это[/b][/color][/url]
Прорезались зубы
Аватара пользователя
Сообщения: 236
Зарегистрирован: Чт июн 25, 2009 16:00:25
Откуда: нижний новгород

Сообщение pashaumnov »

Помогите выйти из сна , тинька 13
Спойлер#include <tiny13.h>
#include <sleep.h>
unsigned int counter;
// Timer 0 overflow interrupt service routine
interrupt [PC_INT0] void pin_change_isr(void)
{
// Place your code here

}
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(PINB.1)
#asm("cli");

}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{if(++counter >552) PORTB.4= 0; // если истекли 20 сек
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=Out Func3=In Func2=Out Func1=Out Func0=Out
// State5=T State4=0 State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x14;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 9,375 kHz
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
SREG|= (1<<7); //разрешаем общие прерывания
GICR|=(1<<0); //разрешаем прерывание по INT0
MCUCR=0x00;
GIMSK=0x54;





// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x02;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// Global enable interrupts
#asm("sei")


while (1)
{
if(PINB.3==1) // если вход == 1 или можно записать так if(PORTB.3)

{
counter= 0; // сбрасываем счетчик
PORTB.4= 1; // устанавливаем порт в "1"
}
{ if(PORTB.4==0) // если вход == 0 или можно записать так if(!PORTB.4)
{
MCUCR|=(1<<5)|(1<<4)|(0<<3)|(0<<0)|(1<<0); // настройка 1 в бите SE,
#asm ("sleep")

}
};
} ;
}
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

MCUCR|=(1<<5)|(1<<4)|(0<<3)|(0<<0)|(1<<0);
Сомневаюсь, что эта строчка работает так как бы вы хотели...
Уж тогда так:
MCUCR=(1<<5)|(1<<4)|(0<<3)|(0<<1)|(1<<0);
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2296
Зарегистрирован: Пн июл 14, 2008 18:12:37

Сообщение LINKS_234 »

а я-то думал что хуже своего кода уже не увижу ... :)
неужели конструкция вида MCUCR|=(1<<5)|(1<<4)|(0<<3)|(0<<0)|(1<<0);
нагляднее чем MCUCR|=0b0011001 или дефайнов ?
смысла писать | (логическое "или"), а потом туда пихать нули - совершенно нету. логическим "или" присваивают необходимому биту(битам) значение 1. обнуляют логическим "и" - &
ну и осталось определиться со сдвигами и форматированием кода - без отступов чем больше строк кода - тем хреновее код читается.
есть вопросы ? чего-то не знаешь ? [url=http://s61.radikal.ru/i174/1006/79/bc6a635c1451.jpg][color=blue][b]прежде всего смотри это[/b][/color][/url]
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Это (частично) позаимствовано из асма. В оригинале от Атмела в (.h - .inc)-файлах символические имена имеют не значения битов регистров, а их номера. Например, в регистре управления SPI, который называется SPICR, бит разрешения работы SPI - шестой. Так вот, во всех материалах от Атмел, SPE (SPi Enable) имеет значение 6, а не 0x40. Если тебе надо его взвести, то это очень удобно делается одной командой SBI SPICR,SPE. Однако уже для того, чтобы собрать байт из нескольких отдельных битов для передачи его одной командой OUT, приходится писать те самые конструкции, только вместо конкретных цифр, на сколько сдвигать единичку, пишут имена битов. Например, если для инициализации того же SPI тебе нужно взвести в SPICR биты SPIE (SPi Interrupt Enable) и MSTR (мастер), приходится писать (1<<SPIE)|(1<<MSTR), а верхом идиотизма является случай, когда несколько смежных битов образуют поле, в которое нужно поместить число или код. Как в том самом MCUCR, где (не факт, что правильно, не вникал) устанавливается Sleep Mode. Вместо нормального-понятного SleEna+SleADCNR (ADC Noise Reduction) плюс два кода для ISC0/1, приходится городить ерунду (1<<SE)|(0<<SM2)|(0<<SM1)|(1<<SM0), из которой хрен что поймешь.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Ответить

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