реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Closed TopicStart new topic
> tick_10=0; не обнуляет переменную
Dzhesertep
сообщение May 12 2010, 17:58
Сообщение #1





Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222



Прямое обнуление volatile переменных не работает, использую Winavr 20100110, дебаггера в данный момент нет, так что посмотреть что именно происходить с контроллером проблематично.
После операции вида volatile unsigned char Temporary=0; переменной присваивается единица.
Компилятор выдаёт следующее:
tick_10=0;


a00: 10 92 e4 01 sts 0x01E4, r1

volatile unsigned char Temporary=0;
3d2: 19 82 std Y+1, r1 ; 0x01

При этом не нашел ни одной операции, которая бы инкримировала r1, при этом tick_10 обнуляется в прерывании и после сохранения реггистров идет команда
894: 11 24 eor r1, r1
так что в r1 просто обязан быть 0.

Сообщение отредактировал Dzhesertep - May 12 2010, 18:00
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 12 2010, 18:34
Сообщение #2


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Dzhesertep @ May 12 2010, 21:58) *
..переменной присваивается единица.
А как вы это узнали?
Go to the top of the page
 
+Quote Post
Dzhesertep
сообщение May 12 2010, 19:02
Сообщение #3





Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222



Цитата(SysRq @ May 12 2010, 22:34) *
А как вы это узнали?


Каждые 10 секунд идет запись лога, т.е. обнуление происходит внутри
Код
if (tick_10==10)
{
//что-то там ещё
tick_10=0;
}
Замена данной конструкции на
if (tick_10==10)
{
//что-то там ещё
tick_10=tick_10-10;
}

решает проблему.
Во втором месте та же проблема возникает при копировании строки, за счёт того что переменная не обнуляется и копирование идёт не с a[0], а с a[1]. Я пока склоняюсь к тому, что кто-то портит содержимое r1, но прямой инструкции пока не нашел, да и должен же компилятор заботиться о сохранении контекста.

Сообщение отредактировал rezident - May 14 2010, 19:55
Причина редактирования: Оформление цитаты исходника.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение May 12 2010, 19:33
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Dzhesertep @ May 12 2010, 20:58) *
После операции вида volatile unsigned char Temporary=0; переменной присваивается единица.

Смотря конечно где стоит, но вообще-то с чего вы взяли, что это операция? Это объявление переменной с начальной инициализацией.
По этому компилятор где-то в инициализирующей части присвоил 0 и всё. А чего вы от него хотели?
Go to the top of the page
 
+Quote Post
Savrik
сообщение May 12 2010, 19:35
Сообщение #5


наблюдаю..
***

Группа: Свой
Сообщений: 291
Регистрация: 11-12-06
Из: Украина
Пользователь №: 23 369



так-так-так... tick_10 и Temporary глобальные переменные? а ну-ка код полностью в студиюsmile.gif

Сообщение отредактировал Savrik - May 12 2010, 19:36
Go to the top of the page
 
+Quote Post
Dzhesertep
сообщение May 12 2010, 20:20
Сообщение #6





Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222



Цитата(Savrik @ May 12 2010, 23:35) *
так-так-так... tick_10 и Temporary глобальные переменные? а ну-ка код полностью в студиюsmile.gif

tick_10 глобальная, Temporary локальная и volatil'ом обзывал её лишь для проверки предположения(т.е. чтоб ноль из r1 писался напрямую в память).
Содержательная часть кода:
CODE
ISR (TIMER0_OVF_vect)//overflow interrupt vector
{

tick++;
++tick_10;

if (++t.second==60) //keep track of time, date, month, and year
{
t.second=0;
if (++t.minute==60)
{
t.minute=0;
if (++t.hour==24)
{
t.hour=0;
if (++t.date==32)
{
t.month++;
t.date=1;
}
else if (t.date==31)
{
if ((t.month==4) || (t.month==6) || (t.month==9) || (t.month==11))
{
t.month++;
t.date=1;
}
}
else if (t.date==30)
{
if(t.month==2)
{
t.month++;
t.date=1;
}
}
else if (t.date==29)
{
if((t.month==2) && (not_leap()))
{
t.month++;
t.date=1;
}
}
if (t.month==13)
{
t.month=1;
t.year++;
}
}
}
}

if (tick_10==10)
{
unsigned char sreg;
unsigned int i;
/* Save global interrupt flag */
sreg = SREG;
/* Read TCNTn into i */
i = TCNT1;
TCNT1 = 0;
/* Restore global interrupt flag */
SREG = sreg;
pin_events_count_n=pin_events_count_n+i;
pin_events_count=pin_events_count_n;
pin_events_count_n=0;
if (log_on)
{
prepare_string();
USART_SEND();
}
tick_10=tick_10-10;
//tick_10=0;
}
}

void prepare_string(void)
{
for (int i=0; i<30;i++)
log_string[i]='\0';
if (t.date<10)
{
log_string[0]='0';
my_itoa(t.date, &log_string[1]);
}
else
my_itoa(t.date, &log_string[0]);
log_string[2]='.';

if (t.month<10)
{
log_string[3]='0';
my_itoa(t.month, &log_string[4]);
}
else
my_itoa(t.month, &log_string[3]);
log_string[5]='.';

my_itoa(t.year, &log_string[6]);
log_string[10]=' ';

if (t.hour<10)
{
log_string[11]='0';
my_itoa(t.hour, &log_string[12]);
}
else
my_itoa(t.hour, &log_string[11]);
log_string[13]=':';

if (t.minute<10)
{
log_string[14]='0';
my_itoa(t.minute, &log_string[15]);
}
else
my_itoa(t.minute, &log_string[14]);
log_string[16]=':';

if (t.second<10)
{
log_string[17]='0';
my_itoa(t.second, &log_string[18]);
}
else
my_itoa(t.second, &log_string[17]);
log_string[19]=' ';
volatile unsigned char i=my_ltoa(pin_events_count, &log_string[20]);
log_string[20+i]=log_string[19+i];
log_string[19+i]=',';
log_string[21+i]='\r';
log_string[22+i]='\n';
}

void my_itoa(int i, char *Place)
{
volatile int C[3];
volatile unsigned char Temp=0, NumLen = 0;
do
{
Temp++;
C[Temp] = i % 10;
i = i/10;
}
while (i);
NumLen = Temp;
for (Temp = NumLen; Temp>0; Temp--)
{Place[NumLen-Temp]=C[Temp] + 48;}

}

unsigned char my_ltoa(long int i, char *Place)
{
volatile unsigned char C[10];
volatile unsigned char Temp=0, NumLen = 0;
do
{
Temp++;
C[Temp] = i % 10;
i = i/10;
}
while (i);
NumLen = Temp;
for (Temp = NumLen; Temp>0; Temp--)
{Place[NumLen-Temp]=C[Temp] + 48;}
return NumLen;
}

void USART_SEND(void)
{
unsigned char Temporary=0;
do
{
ch=log_string[Temporary];
SendCharUart1(ch);
Temporary++;
}
while((ch!='\n')&&(Temporary<30));
}

Кстати, ещё баг возникает именно при выполнении prepare_string();из прерывания, если находиться в while(1) в функции отличной от main и в строке volatile unsigned char i=my_ltoa(pin_events_count, &log_string[20]); отсутсвует volatile. Контроллер начинает творить что-то страшное, сначала выводя на экран какой-то непонятный мусор, но с этим разбираться планирую когда раздобуду нормальный дебаггер.
P.S. То что подготовка строки тупая и вообще неизящная я знаю, но суть не в этом.

Сообщение отредактировал rezident - May 14 2010, 19:57
Причина редактирования: Оформление цитаты исходника.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 13 2010, 13:22
Сообщение #7


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Dzhesertep @ May 13 2010, 00:20) *
Контроллер начинает творить что-то страшное, сначала выводя на экран какой-то непонятный мусор
Логично...
Первое, что бросилось в глаза это my_ltoa...
Попробуйте так (не претендую на оптимальность):
Код
uint8_t my_ultoa(uint32_t x, char *dst)
{
    #define STR_SIZE  10   // 2^32 - 1 = 4294967295

    char    str[STR_SIZE];   // str w/o null terminator
    uint8_t len = 0;

    do
    {
        str[len++] = '0' + x % 10;
    }
    while ( (x/=10) );

    for (uint8_t i=0; i<len; i++)
    {
        *dst++ = str[len-i];
    }

    dst[0] = '\n'; // null
    
    return len; // str len w/o null terminator
}
А зачем Вам нужно знать длину строки и чем не устраивает стандартная ultoa из stdlib.h?
Никогда не изобретайте велосипед и регулярно читайте букварь по СИ до полного прояснения в голове!
ЗЫЖ Не надо лепить volatile где непоподя!!!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 13 2010, 16:02
Сообщение #8


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Dzhesertep @ May 12 2010, 23:02) *
Каждые 10 секунд идет запись лога, т.е. обнуление происходит внутри if (tick_10==10)
Запись лога происходит не через 10 секунд? Откуда вывод, что вместо 0 пишется 1? Не понятно...
Go to the top of the page
 
+Quote Post
Dzhesertep
сообщение May 13 2010, 16:11
Сообщение #9





Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222



Цитата(demiurg_spb @ May 13 2010, 17:22) *
Логично...
Первое, что бросилось в глаза это my_ltoa...

Ну вот ни разу не логично.
Во первых не увидел принципиальных отличий между моей функцией и вашей (ну кроме терминального \n, который мне вообще не нужен) , и в чём же может быть ошибка именно моей функции?
Во вторых проблему библиотечные функции не решили.
В третьих страшное твориться при отсутвии volatile именно в volatile unsigned char i=my_ltoa(pin_events_count, &log_string[20]); (с библиотечной ultoa та же ситуация) (но вообще здесь всё более или менее понятно)
В четвертых volatil'ы в такие функции ставятся не от хорошей жизни, а как последняя мера, когда совсем уже ничего не понятно, и единственный вред который они могут принести-только снижение производительности и лишний объем занимаемой памяти.
И в пятых, но на самом деле во первых, из любого "букваря по Си" следует, что после tick_10=0; tick_10 будет НОЛЬ!

Цитата(SysRq @ May 13 2010, 20:02) *
Запись лога происходит не через 10 секунд? Откуда вывод, что вместо 0 пишется 1? Не понятно...

Согласен, сказал неудачно
Запись лога ДОЛЖНА идти каждые 10 секунд, но из-за того что tick_10 не обнуляется лог стабильно ИДЕТ каждые 9 секунд.
При этом в самом начале переменная ноль и первый лог приходит как положено, через 10 секунд после запуска, т.е. получается последовательность времени записи: 10, 19, 28, 37 и т.д.
Если конструкция tick_10=0; меняется на tick_10=tick_10-10 всё становится нормально и получается последовательность времени записи:10, 20, 30, 40 и т.д.
принципиальным тут считаю именно способ обнуления переменных, используемый компилятором т.е. sts <адрес>, r1.


Сразу добавлю: Сейчас перепроверил предположение о испорченном r1 и оно оказалось верным.
Вынеся tick_10=0; перед функциями подготовки строки и её отправки всё заработало как и должно, сейчас буду искать кто же именно может менять значение регистра.

Сообщение отредактировал Dzhesertep - May 13 2010, 16:18
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 14 2010, 09:19
Сообщение #10


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Dzhesertep @ May 13 2010, 20:11) *
Ну вот ни разу не логично.
Блажен кто верует...
Как минимум, у Вас инкремент индекса массива Temp++; происходит до того как поместить данные в этот массив, что может вызвать выход за диапазон массива...
Процедура у Вас как называется? Зачем путать и себя и остальных? Если она работает с беззнаковым числом, так и называйте её по образу и подобию stdlib.h. Повторюсь - не изобретайте велосипед и воспринимайте критику адекватно. Учитесь пока можете. Ваш код пока просто ужасен.
Есть одно хорошее высказывание, которое звучит примерно так: "Если есть возможность испивать совершённую ошибку - то это была не ошибка."

Цитата(Dzhesertep @ May 13 2010, 20:11) *
...терминального \n, который мне вообще не нужен)
Повторюсь и в 3 раз - не изобретайте велосипед. Если стандартные функции с именами *toa возвращают строку, то и Ваша с таким же именем обязана делать также. В противном случае назовите её иначе например *toa_wo_null!
И почитайте наконец что такое volatile и с чем его едят, а то
Цитата
volatile unsigned char C[10];
volatile unsigned char Temp=0, NumLen = 0;
просто удручает, а Вы говорите нет разницы
Цитата
кроме терминального \n
И это ещё я не начинал придираться.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
xemul
сообщение May 14 2010, 13:02
Сообщение #11



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Dzhesertep @ May 13 2010, 20:11) *
Ну вот ни разу не логично.
...

Нелогичен весь Ваш обработчик прерывания. Не пробовали оценить/измерить время его выполнения?
имхо, в нём ничего кроме
Код
volatile bit tick_flag;
volatile uint tick_time;

ISR (TIMER0_OVF_vect)//overflow interrupt vector
{
   tick_flag = 1;
   tick_time = TCNT1;
}

быть не должно.

Чтобы немножко ускорить процесс своими, но более разумными Xtoa(), на контроллере без аппаратного деления, воспользуйтесь чем-нить вроде
Код
Деление на 10:
8 bit: Y = (X * 0xCD) >> 11;
16 bit: Y = (X * 0xCCCD) >> 19;
32 bit: Y = (X * 0xCCCCCCCD) >> 35;

(поиск по конфе Вам в помощь - обсуждалось не раз)

ЗЫЖ оформляйте, плз, сорцы тэгами {code} {/code} (в [], а не в {}, естесно)
ручками или пользуйтесь [attachment=44040:000_140510.JPG]
Go to the top of the page
 
+Quote Post
Dzhesertep
сообщение May 14 2010, 13:43
Сообщение #12





Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222



Цитата(demiurg_spb @ May 14 2010, 13:19) *
Если стандартные функции с именами *toa возвращают строку, то и Ваша с таким же именем обязана делать также.


1.Это кому же она что обязана?
2.Специально для чистоплюев она называется my_ltoa (sic!)
3. Баг в ней на данный момент только один-неиспользуемый c[0], выход за пределы массива исключен так как больше 10^8 значения функции не передаются. А то что значение 2^32-1 она не обработает-да мне этого от неё и не надо.

Опять же повторюсь, что мы уходим от темы. Если кто что-то и обязан, так это tick_10=0; обязан обнулять tick_10.

P.S. Я отлично понимаю что делает volatile. В данном случае volatile привязывает переменную к конкретному адресу памяти, не давая ей болтаться по регистрам и стэку как попало. И опять же повторюсь-volatile ставится не от хорошей жизни.(И вообще мотивы заставившие меня "изобретать велосипед" касаются только меня)
P.P.S. Я сюда пришел, дабы получить помощь лишь в вопросе чётко обозначенном в теме, уж с преобразованиями чисел сам как-нибудь разберусь. Если кого-то коробит кривость подготовки строки(а здесь, признаюсь, я принимаю критику), то извините, нужно было сделать быстро и чтобы работало.
P.P.P.S. Специально для demiurg_spb. Я тоже могу начать придираться и сразу скажу, что строка по стандартам завершается ну никак уж не '\n'. Если кто забыл основы - то терминатор строки всю жизнь был '\0'
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 14 2010, 16:16
Сообщение #13


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Dzhesertep @ May 14 2010, 17:43) *
P.S. Я отлично понимаю что делает volatile. В данном случае volatile привязывает переменную к конкретному адресу памяти, не давая ей болтаться по регистрам и стэку как попало.
Чушь и бред. Как собственно почти всё остальное вами сказанное.
volatile ничего никуда не "привязывает", а для случая "привязывает переменную к конкретному адресу" вменяемые люди используют static.
Последний раз советую вам начать читать букварь!!!

Цитата(Dzhesertep @ May 14 2010, 17:43) *
Если кто забыл основы - то терминатор строки всю жизнь был '\0'
Это очень даже хорошо, когда есть что забывать...

Ну никак не понимаете вы намёков и не хотите учиться.
Даже скучно становится...

"Тщеславие - мой любимый грех" (с) AL PACINO - "The Devil's Advocate"

Цитата(Dzhesertep @ May 14 2010, 17:43) *
P.P.S. Я сюда пришел, дабы получить помощь лишь в вопросе чётко обозначенном в теме, уж с преобразованиями чисел сам как-нибудь разберусь. Если кого-то коробит кривость подготовки строки(а здесь, признаюсь, я принимаю критику), то извините, нужно было сделать быстро и чтобы работало.
Это всегда так начинается, а потом все удивляются почему так много говнокодеров.
Приучайтесь к дисциплине, решайте и по возможности отлаживайте каждую задачку отдельно - это даст вам хороший результат в целом.
Невозможно отладить всё разом - примите это как данность. Из кусков говна янтарной комнаты не слепишь. Удачи Вам!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Dzhesertep
сообщение May 14 2010, 19:31
Сообщение #14





Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222



Цитата(xemul @ May 14 2010, 17:02) *
Нелогичен весь Ваш обработчик прерывания. Не пробовали оценить/измерить время его выполнения?
имхо, в нём ничего кроме
Код
volatile bit tick_flag;
volatile uint tick_time;
ISR (TIMER0_OVF_vect)//overflow interrupt vector
{
   tick_flag = 1;
   tick_time = TCNT1;
}

Согласен, что, в идеале, больше ничего он не должен делать, но специфика железки преполагает именно такой вариант.
Времена оценивал: 0,75 с занимает подготовка строки и около 0,01 секунды отправка, так что до следующего прерывания всё должно успевать отрабатывать, а с "подвисанием" на это время раз в 10 секунд можно мириться. Опять же непонятно, что портит регистр r1, а именно в нём явная загвоздка, судя по дизассемблеру.

Цитата(demiurg_spb @ May 14 2010, 20:16) *
Чушь и бред. Как собственно почти всё остальное вами сказанное.
volatile ничего никуда не "привязывает", а для случая "привязывает переменную к конкретному адресу" вменяемые люди используют static.
Последний раз советую вам начать читать букварь!!!


Хы. Вот от вас не было ещё ни одного совета по существу. В "букварях" обычно пишут что-то вроде "запрещает оптимизацию доступа". А на деле открываем дизассемблер и видим, что любая запись в переменную представляет собой просто прямое обращение к памяти посредством sts или st.

Опять же уклоняемся от темы. Чувствую что вообще зря её создал, ибо на следующей недели появится дебаггер, а толку от него, как показывают ответы, намного больше.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 14 2010, 20:14
Сообщение #15


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Dzhesertep @ May 14 2010, 23:31) *
А на деле открываем дизассемблер и видим
так можно многое понять совершенно превратно...
Цитата
Опять же уклоняемся от темы.
Ничуть. Вы выкиньте всё лишнее из вашей программы и "откройте дизассемблер" - 10 минут делов на поиски пустяковой ошибки.
А тут уже целый день народ вам даёт дельные советы, а в ответ слышим что так и задумано, так и хорошо, мне так надо.
Цитата
Чувствую что вообще зря её создал...
С таким умением слушать точно зря.
Цитата
ибо на следующей недели появится дебаггер, а толку от него, как показывают ответы, намного больше.
Ни разу в жизни не испытывал надобности во внутрисхемной отладке программ для AVR.
Этак лет около 10 назад дебажил асмовые проекты в эмуляторе на avr-студи, сейчас вообще об этом и не вспоминаю...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Closed TopicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 17:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01503 секунд с 7
ELECTRONIX ©2004-2016