|
tick_10=0; не обнуляет переменную |
|
|
|
May 12 2010, 17:58
|
Группа: Участник
Сообщений: 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
|
|
|
|
|
 |
Ответов
|
May 12 2010, 20:20
|
Группа: Участник
Сообщений: 11
Регистрация: 12-05-10
Пользователь №: 57 222

|
Цитата(Savrik @ May 12 2010, 23:35)  так-так-так... tick_10 и Temporary глобальные переменные? а ну-ка код полностью в студию  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
Причина редактирования: Оформление цитаты исходника.
|
|
|
|
|
May 13 2010, 13:22
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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 где непоподя!!!
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
May 13 2010, 16:11
|
Группа: Участник
Сообщений: 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
|
|
|
|
Сообщений в этой теме
Dzhesertep tick_10=0; не обнуляет переменную May 12 2010, 17:58 SysRq Цитата(Dzhesertep @ May 12 2010, 21:58) .... May 12 2010, 18:34 Dzhesertep Цитата(SysRq @ May 12 2010, 22:34) А как ... May 12 2010, 19:02 SasaVitebsk Цитата(Dzhesertep @ May 12 2010, 20:58) П... May 12 2010, 19:33    demiurg_spb Цитата(Dzhesertep @ May 13 2010, 20:11) Н... May 14 2010, 09:19     Dzhesertep Цитата(demiurg_spb @ May 14 2010, 13:19) ... May 14 2010, 13:43      demiurg_spb Цитата(Dzhesertep @ May 14 2010, 17:43) P... May 14 2010, 16:16    xemul Цитата(Dzhesertep @ May 13 2010, 20:11) Н... May 14 2010, 13:02     Dzhesertep Цитата(xemul @ May 14 2010, 17:02) Нелоги... May 14 2010, 19:31      demiurg_spb Цитата(Dzhesertep @ May 14 2010, 23:31) А... May 14 2010, 20:14      rezident Цитата(Dzhesertep @ May 15 2010, 01:31) В... May 14 2010, 20:15       Dzhesertep Цитата(rezident @ May 15 2010, 00:15) dem... May 14 2010, 20:57        rezident Цитата(Dzhesertep @ May 15 2010, 02:50) А... May 14 2010, 21:01         Dzhesertep Цитата(rezident @ May 15 2010, 01:01) Вот... May 14 2010, 21:14          rezident Цитата(Dzhesertep @ May 15 2010, 03:14) З... May 14 2010, 21:29 SysRq Цитата(Dzhesertep @ May 12 2010, 23:02) К... May 13 2010, 16:02 Dzhesertep Ну вот так сложилось, что на уарт строчку надо ото... May 14 2010, 22:20 demiurg_spb Цитата(Dzhesertep @ May 15 2010, 01:14) Н... May 15 2010, 07:59  Dzhesertep Цитата(demiurg_spb @ May 15 2010, 11:59) ... May 15 2010, 09:09   Dzhesertep Всё, тему можно закрывать, нашлась именно ошибка, ... May 15 2010, 14:16
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|