Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2148 проблемы с вычислениями
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Zugus
Доброго времени суток.
Проблема вот в чём. Контроллер должен вычислять и задавать температуру, с использованием PID алгоритма.
Обмен между компом, контроллером и платой я наладил. Всё работает адекватно.
А в формулах для вычисления коэффициентов, используются переменные типа float. И вот тут начинаются чудеса.
До этого моделировал работу в Кейловском симуляторе, там всё было корректно.
А как только я начинаю делать расчёты с этими переменными в камне, у меня либо камень после прошивки повисает в стартапе в строчке DAbt_Addr/
Либо всё таки прошивается, но после вычисления получается ответ 0. Причём, если залезть в камень ULINKOм то даже если переменные типа флоат, он вполне адекватно показывает, что в них прописано, но стоит запустить программу в штатном режиме, снова 0.
Перешел от float к int, проблема в основном ушла, но мистика все равно осталась. Доходит до того, что просто добавление переменной, может после прошивки посылать контроллер в DAbt_Addr. Тоесть тупо добавил, и нигде не использую. Какие то танцы с бубном smile3046.gif
Я до этого не имел дело с АРМами. Возможно я не правильно инициирую камень в самом начале? Может у меня смешиваются области данных и области переменных? В стартапе надо что то прописать?
Или это проблемы в кейле самом, он у меня с лекарством. Компиллер RealViev Сам кеил Enterprise-ARM.
У меня состояние уже близко к панике, вторую неделю ересь какая то творится, все сроки уже горят. Поискал на форуме, не нашел никого с такой проблемой. Прикладываю свой startup и кусочек кода из мэин, ту часть где идёт начальная инициализация.
Код
#include <LPC214x.h>
#include <math.h>
#include <float.h>
#include <fenv.h>


void initFiq (void);
void initLPC (void);
void init_PLL(void);

int main (void)
{
init_PLL();
initLPC();
initFiq();


////////////////////////////////////////////////////////////////////////////////////////////////////
__irq void FIQ_Handler(void) ////prerivanie
{
if (state1 ==0x7f)                                                  
{
flajok =flajok+1;
}  
EXTINT      = 0x00000002;                        //Clear the peripheral interrupt flag
}  

////////////////////////////  INTERRUPT  //////////////////////////////////////////////
void initFiq(void)
{
PINSEL0         = 0x20000000;            //Enable the EXTINT1 interruptand p0.16, p0.17-input
VICIntSelect     = 0x00008000;                            //Enable a Vic Channel as FIQ
VICIntEnable    = 0x00008000;        
}
////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// INICIALIZATION  //////////////////////////////////////////////
void initLPC(void)
{
IODIR0            |= 0x00000000; //DATA
IODIR1            |= 0x007F0000; //ADDR
IOSET1             |= 0x00630000; //ADDR =3, WR =1; RD=1;    0x00630000
//IOSET1             |= 0x00230000; //ADDR =3, WR =1; RD=0;    
}
////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////   PLL   ///////////////////////////////////////////////
void init_PLL(void)
{
PLL0CFG         = 0x00000024;                  // Set multiplier and divider of PLL to give 60.00 Mhz
PLL0CON         = 0x00000001;                  // Enable the PLL
PLL0FEED         = 0x000000AA;                // Update PLL registers with feed sequence
PLL0FEED         = 0x00000055;
while (!(PLL0STAT & 0x00000400))             // test Lock bit
{
;
}
PLL0CON         = 0x00000003;                  // Connect the PLL
PLL0FEED        = 0x000000AA;                   //Update PLL registers
PLL0FEED         = 0x00000055;    
VPBDIV             = 0x00000001;                   //Set the VLSI peripheral bus to 30.000Mhz
}
/////////////////////////////////////////////////////////////////////////////////////
sergeeff
У тебя под стек выделено 1024 байта. Нигде не используются большие локальные массивы?
Zugus
Я вообще не использую массивы.
sergeeff
Да, еще раз внимательнее посмотрел startup. Там явная ляпа с назначением объема стека в user - mode:

Написано:

Код
  Enter User Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_USR
                IF      :DEF:__MICROLIB

                EXPORT __initial_sp

                ELSE

                MOV     SP, R0
                SUB     SL, SP, #USR_Stack_Size

                ENDIF

а надо:

Код
  Enter User Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_USR
                IF      :DEF:__MICROLIB

                EXPORT __initial_sp

                ELSE

                MOV     SP, R0
                SUB     SP, SP, #USR_Stack_Size

                ENDIF
Zugus
А можно поподробнее объяснить, чем отличается
SUB SL, SP, #USR_Stack_Size
от
SUB SP, SP, #USR_Stack_Size
?
Хочется немного разобраться, а не просто бездумно менять...

Где вообще можно почитать, что за что отвечает в стартапе?
aaarrr
Цитата(sergeeff @ Feb 9 2009, 11:07) *
Там явная ляпа с назначением объема стека в user - mode:

Не ляпа это ни разу, а установка Stack Limit'а. Менять ничего не нужно.

Библиотека float в RealView может наворачиваться, если стек не выровнен по границе 2-х слов.
Zugus
Вопрос наверно дурацкий.
Но как его выровнять? По границе двух слов?
sergeeff
Цитата(aaarrr @ Feb 9 2009, 13:57) *
Не ляпа это ни разу, а установка Stack Limit'а. Менять ничего не нужно.


Да, действительно - не ляп. Не внимательно весь файл посмотрел. Пардон. А про startup можно почитать у Т.Мартина "Микроконтроллеры АРМ7.Семейство LPC2000" на стр.36.
aaarrr
Цитата(Женёк @ Feb 9 2009, 14:15) *
Но как его выровнять? По границе двух слов?

После стартапа он выровнен правильно (можете проверить в симуляторе, чему он равен при входе в main), следить за выравниванием дальше - забота компилятора. Но если используются какие-либо сторонние библиотеки/asm-модули, то проблемы могут быть в них.
Zugus
Можно подробнее расписать про стэк? Как его посмотреть?
Асм модули и сторонние библиотеки не использую. Только стандартные, которые описаны в шапке.
Может из за лекарств компилятор шалит?
По каким ещё причинам, может не работать флоат?
aaarrr
Цитата(Женёк @ Feb 9 2009, 15:46) *
Можно подробнее расписать про стэк? Как его посмотреть?

Посмотрите состояние SP (R13) непосредственно перед вызовом float-функции.

Цитата(Женёк @ Feb 9 2009, 15:46) *
Может из за лекарств компилятор шалит?

Вряд ли.

Вам нужно посмотреть, откуда процессор влетает в Data Abort - многое может проясниться.
A. Fig Lee
А сколько float места занимает?
Возможно, он поболее инта и процессор не успевает считать его?
Я бы установил минимальную скорость чтения из флеша для начала,
и попробовал как себя программа в RAM ведет.
Zugus
Будем посмотреть.
Кстати, в дата аборт вылетает как правило сразу. Тоесть ещё при инициализации
Zugus
Коллега нашел ошибку...
Всё дело было в плл. Она была инициализирована для умножения на 5. А входная частота у меня 20Мгц. Я так понял частота внутри не должна быть больше 60.
В любом случае, сейчас сделали умножение на 3, всё заработало.
Всем большое спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.