|
|
  |
Ошибка IAR или чтото еще? |
|
|
|
Dec 20 2006, 19:29
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(prottoss @ Dec 20 2006, 18:05)  Я смотрел, и не раз, пожалуйста, c чуйством глубокохо удовлетворения привожу листинг, смотрите: Код \ ??PULSE_SENS_CorrectTime_0: \ 00000028 01A8 MOVW R21:R20, R17:R16 \ 0000002A 9556 LSR R21 \ 0000002C 9547 ROR R20 \ 0000002E E060 LDI R22, 0 \ 00000030 0189 MOVW R17:R16, R19:R18 \ 00000032 01C8 MOVW R25:R24, R17:R16 \ 00000034 EE08 LDI R16, 232 \ 00000036 E013 LDI R17, 3 \ 00000038 E020 LDI R18, 0 \ 0000003A E030 LDI R19, 0 \ 0000003C 9F19 MUL R17, R25 \ 0000003E 0D20 ADD R18, R0 \ 00000040 1D31 ADC R19, R1 \ 00000042 9F18 MUL R17, R24 \ 00000044 2D10 MOV R17, R0 \ 00000046 0D21 ADD R18, R1 \ 00000048 1F36 ADC R19, R22 \ 0000004A 9F09 MUL R16, R25 \ 0000004C 0D10 ADD R17, R0 \ 0000004E 1D21 ADC R18, R1 \ 00000050 1F36 ADC R19, R22 \ 00000052 9F08 MUL R16, R24 \ 00000054 2D00 MOV R16, R0 \ 00000056 0D11 ADD R17, R1 \ 00000058 1F26 ADC R18, R22 \ 0000005A 1F36 ADC R19, R22 \ 0000005C 0F04 ADD R16, R20 \ 0000005E 1F15 ADC R17, R21 \ 00000060 1F26 ADC R18, R22 \ 00000062 1F36 ADC R19, R22 ProttossНе поленился, проверил Ваш код сначала в голове, затем на симуляторе Так вот: Компилятор сделал РОВНО ТО, ЧТО ВЫ У НЕГО ПОПРОСИЛИ !!! Так что исчите апщибку в логике работы программы. Да, кстати, присоединяюсь к Цитата И, кстати, это так ведь задумано - при каждом вызове функции портить Pulse->Time? скорее всего именно здесь собака порылась
|
|
|
|
|
Dec 20 2006, 20:04
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(singlskv @ Dec 20 2006, 23:29)  ProttossНе поленился, проверил Ваш код сначала в голове, затем на симуляторе Так вот: Компилятор сделал РОВНО ТО, ЧТО ВЫ У НЕГО ПОПРОСИЛИ !!! Так что исчите апщибку в логике работы программы. Да, кстати, присоединяюсь к Цитата И, кстати, это так ведь задумано - при каждом вызове функции портить Pulse->Time?
скорее всего именно здесь собака порылась Какая все же ошибка? Объясните не разумному? 2 Oldring - функция вызывается после того, как прерывания запрещены. После всех вычислений прерывания разрешаются. В первом случае я возвращаю результат из функции и он правильный, во втором случае я возвращаю результат в указатель и результат, в итоге, не правильный
--------------------
|
|
|
|
|
Dec 20 2006, 20:23
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Oldring @ Dec 21 2006, 00:09)  Ключевое слово - "в итоге". Так найдите то место, в котором результат в конце концов портится. Судя по тому, что, как Вы пишете, код вычисления выражения одинаковый - и результат сразу после вычисления выражения одинаковый. Так что ищите глюк где-то в другом месте. А в итоге вызывающая функция вот такая (закомментированная строчка не работает для функции, которая возвращает результат вычислений с структуру): Код
UINT16 PULSE_SENS_GetState(Pulse_Time_t *Pulse) { /* корректируем время и преобразуем период в герцы*/ return (UINT16)(1000000 / /* stop_time - start_time */ (PULSE_SENS_CorrectTime(&Pulse[1]) -PULSE_SENS_CorrectTime(&Pulse[0]))); //(Pulse[1].Time - Pulse[0].Time)); -----ЭТО НЕ РАБОТАЕТ } Pulse - массив двух структур Pulse_Time_t, которые изменяет внешнее прерывание INT. Перед вызовом данной функции прерывание запрещается, после - разрешается.
--------------------
|
|
|
|
|
Dec 20 2006, 20:43
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Oldring @ Dec 21 2006, 00:28)  Пожалуйста, приведите два варианта кода отдельно - когда работает и когда не работает. Сейчас сложно понять, какой именно вариант не работает. ОК Вот рабочий вариант: Код
/***************************************************************************** ******************************************************************************/ UINT16 PULSE_SENS_GetState(Pulse_Time_t *Pulse) { /* корректируем время и преобразуем период в герцы*/ return (UINT16)(1000000 / /* stop_time - start_time */ (PULSE_SENS_CorrectTime(&Pulse[1]) - PULSE_SENS_CorrectTime(&Pulse[0]))); }
............................................................................
/***************************************************************************** ******************************************************************************/ UINT32 PULSE_SENS_CorrectTime(Pulse_Time_t *Pulse) { UINT32 time = Pulse->Time; /* корректируем результат по состоянию флага OCF1A на момент считывания значений времени */ if(Pulse->TIFR_reg & (1 << OCF1A)) { time += 0x00010000; /* если флаг установлен, инкрементируем значение милисекунд */ if(SYSTIMER_COMPARE_VAL == LOWORD(time)) /* если значение счетчика равно константе в регистре сравнения, то мы это значение должны обнулить */ time &= 0xffff0000; }
/* преобразуем в мкс */ return ((UINT32)(LOWORD(time) >> 1) + (UINT32)(HIWORD(time)) * 1000); } Вот НЕ рабочий вариант Код /***************************************************************************** ******************************************************************************/ UINT16 PULSE_SENS_GetState(Pulse_Time_t *Pulse) { /* корректируем время и преобразуем период в герцы*/
PULSE_SENS_CorrectTime(&Pulse[1]) PULSE_SENS_CorrectTime(&Pulse[0]) return (UINT16)(1000000 / /* stop_time - start_time */ (Pulse[1].Time - Pulse[0].Time));
}
/***************************************************************************** Коррекция значения времени Корректирует время в зависимости от значения TIFR и младшего слова (ТС1) ******************************************************************************/ void PULSE_SENS_CorrectTime(Pulse_Time_t *Pulse) { UINT32 time = Pulse->Time; /* корректируем результат по состоянию флага OCF1A на момент считывания значений времени */ if(Pulse->TIFR_reg & (1 << OCF1A)) { time += 0x00010000; /* если флаг установлен, инкрементируем значение милисекунд */ if(SYSTIMER_COMPARE_VAL == LOWORD(time)) /* если значение счетчика равно константе в регистре сравнения, то мы это значение должны обнулить */ time &= 0xffff0000; }
/* преобразуем в мкс */ Pulse->Time = ((UINT32)(LOWORD(time) >> 1) + (UINT32)(HIWORD(time)) * 1000);
} А теперь найдите отличия в смысле первого и второго, я вот что то не могу....
--------------------
|
|
|
|
|
Dec 21 2006, 17:09
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Oldring @ Dec 21 2006, 01:02)  Только этот вариант все равно не должен компилироваться. Теперь компилируйте, проверяйте, что он все еще не работает - и вываливайте дизассемблер. Все, заработало!!! Ошибка была не "компиляторовская". Просто, из-за относительной сложности вычислений для 8-и битника в "главной" процедуре, вызывающей CorrectTime использовался стек данных, а так как его глубина у меня по умолчанию была определена как 0х20 то стек данных затирался... Странным образом программа хромала дальше. Мало того, данные с ADC и GPIO, работающие тоже, кстати, по прерываниям не портились и выдавались хосту нормально, портились только частотомеры... Увеличил стек до 0х40 - все ОК! Я так понимаю по умолчанию глубина стоит 0х20 - это именно для прерываний? То бишь, что бы можно было, при случае, сохранить все 32 регистра? Вот я его еще в два раза и увеличил...Хотя со всеми вычислениями в программе я уже справился, но мало ли. Тем не менее, всем огромное спасибо, особо отмечу идейную помощь singlskv, (кстати, не впервой)особый респект Вам!
--------------------
|
|
|
|
|
Dec 21 2006, 17:39
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(prottoss @ Dec 21 2006, 17:09)  Все, заработало!!! Увеличил стек до 0х40 - все ОК! Я так понимаю по умолчанию глубина стоит 0х20 - это именно для прерываний? То бишь, что бы можно было, при случае, сохранить все 32 регистра? Поздравляю. А глубина стека по умолчанию ничего не значит, так как кроме прерываний существуют вложенные функции, printfы и прочие мелкие радости ЯВУ. Как вообще можно оставлять 0x20, не представляю.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Dec 21 2006, 18:04
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Dog Pawlowa @ Dec 21 2006, 21:39)  Цитата(prottoss @ Dec 21 2006, 17:09)  Все, заработало!!! Увеличил стек до 0х40 - все ОК! Я так понимаю по умолчанию глубина стоит 0х20 - это именно для прерываний? То бишь, что бы можно было, при случае, сохранить все 32 регистра?
Поздравляю. А глубина стека по умолчанию ничего не значит, так как кроме прерываний существуют вложенные функции, printfы и прочие мелкие радости ЯВУ. Как вообще можно оставлять 0x20, не представляю. А вот представьте, мил человек, никада в своей работе с АВРами не пользовался printf и прочими радостями ЯВУ (честно говря, я даже не знаю как это расшифровывается). Пользуюсь, обычно парой светодиодов, USART, ну и, естественно, отладчиком.
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|