Перейти к содержанию
    

ДЕЙЛ

Свой
  • Постов

    728
  • Зарегистрирован

  • Посещение

  • Победитель дней

    5

Весь контент ДЕЙЛ


  1. По молодости-глупости на днях купил пару вот этих плат. http://www.ebay.com/itm/SIM900A-V4-0-Wirel...=item4adb04cfb7 Терзают смутные сомнения, что в России она не совсем праильно будет работать, но эффективные менеджеры всё равно на других сайтах барыжат их за 3-4 цены. Полагаю, что изучать её нужно начинать с перепрошивки. На плате есть вход RX-TX. К нему и нужно подключать провода для смены прошивки? Есть две перемычки, каково их назначение? Сколько вольт питание? Раньше с этим всем дело не имел. Где можно найти схему? UP1: Можно ли на моей плате заменить SIM900A на SIM900R? Распиновка совпадает за исключением нескольких выводов, которые никуда не заведены.
  2. пока ищу, с какой стороны подойти. Как будет выглядеть в терминале такая команда AT+CGDCONT=1,"IP","internet" ?
  3. Хочу освоить работу с данным модулем. Заказал две демо-платы, на них есть разъём питания и разъём RS232, который можно подключить напрямую к COM-порту без переходников и преобразователей. Т.е. хочу перед подключением к МК погонять данный модуль командами с ПК. Есть ли уже готовая программа для работы с этим модулем? Такая, на которой есть отдельные кнопки для отправки заранее заготовленных символьных строк АТ-команд. UP1: накопал вот это: http://www.seeedstudio.com/wiki/GPRS_Shield_V2.0 и сама программа: http://www.seeedstudio.com/wiki/images/b/b2/Sscom32E.zip есть ли что-то подобное, но на русском языке?
  4. Железно заработало :yeah: дело было ещё и в указателе стека. В этом прикреплённом проекте в тестовой программе для вызова главной нужно написать такой код: unsigned int *VTOR; int main() { VTOR = (unsigned int*)0xE000ED08; //адрес данного регистра из хидера *VTOR = 0x7000; //смещение таблицы векторов - из настроек линкера asm ("mov r13, #0x2448"); //запись в регистр стека младших байтов значения указателя стека основной программы, взятого из ячейки с адресом 0x7000; asm ("movt r13, #0x1000"); //запись в регистр стека старших байтов значения указателя стека основной программы, взятого из ячейки с адресом 0x7000; asm ("B 0x8105"); //Безусловный переход по адресу обработчика прерывания сброса, прочитанного из ячейки 0x7002; } Можно было бы поумнее и правильнее код сделать, но для понимания принципа этого хватит. теперь попробую назад в загрузчик из главной программы зайти :bb-offtopic: Зато оперативка экономится, отключил всё ненужное. Ноуту лет 15, в нём есть привод дискет, два разъёма усб, всамделишный LPT и COM-порты ;) Но зато экран большой и нет отвлекающего выхода в тырнет.
  5. Под отладчиком после ассемблерной инструкции перехода программа работает в реальном режиме времени, но её можно остановить и увидеть, что всё крутится в адресах после 7000. Мошть ещё нужно указатель стека на нужное место поставить, как мне посоветовали на другом форуме?
  6. насчёт перескока на 2кб на какой странице мануала написано? Надо попробовать, а симулирование и реальность не всегда совпадают, как я заметил. пробовал разные варианты - записывал 0x380000 и 0x7000, в отладчике наблюдалось число 0xE0. Имею ввиду, что программа из флеши запускается в следующем шаге после строки B 0x8105 при нажатии кнопки F10 в пошаговом режиме отладки, т.е. переходит в то место и запускает программу, а когда отключаю JTAG и нажимаю на сброс, то никаких переходов нет, контроллер не шевелится.
  7. Согласен с перечисленным и у меня это всё предусмотрено, а на схеме показал принцип переноса синусоиды в положительную область для оцифровки. В расходомере питание прецизионное, имеется двойная гальваническая развязка от питающей сети, в металлоискателе реализован динамический режим, т.е. значение нуля постоянно вычисляется по скользящему среднему в течение нескольких секунд, а фиксируются быстрые изменения сигнала. Проблем пока нет.
  8. Почему-то в пашаговом режиме после перехода по адресу программа в другом конце памяти запускается иногда после команды перехода, а после нажатия кнопки сброса никаких движений.
  9. В хидере 35 прерываний и добавим 16 исключений, как написано в руководстве на ядро, получили 51, ближайшая степень двойки - 64, умножаем на 4 и получим 0x100. Этому числу должен быть кратен адрес таблицы векторов, т.е. 0x7000 подходит. Далее читаю описание полей регистра VTOR: Бит 29 TBLBASE - расположение таблицы в оперативке(1) или во флеш(0) Биты 28:7 TBLOFF - Смещение таблицы относительно начала области кода или области ОЗУ,т.е. к 0x7000 добавляем справа 7 нулевых битов и получаем 0x380000 и записываем это число в регистр VTOR. Пока не трогаю записанные данные по адресу 0x7000, т.е. никуда ничего не перемещаю, а пытаюсь маленькой программой запустить большую, расположеннуюв другом месте памяти. И адрес 8105 не меняется в моём случае.
  10. Написал две строки *VTOR = 0x380000; //смещение таблицы относительно начала области кода (0x0000) 0x7000 передвинуты на 7 бит влево, т.к. смещение записывается в битах 28:7 asm ("B 0x8105"); Нивкакую не работает. Что ещё упустил и как правильно написать для перехода к программе, начинающейся с адреса 0x7000?
  11. Она работает в двух приборах - металлоискатель и расходомер при условии, что сигнал находится в линейной области работы операционника и питание не плавает. Очень интересно почитать комментарии по поводу этой схемы. Какие в ней подводные камни?
  12. В каких пределах меняется напряжение? Будем считать, что плюс-минус 20% Я сильно не мудрил бы с делителями, а поставил бы понижающий трансформатор перед входом АЦП, если он биполярный. Если однополярный, то сигнал со вторичной обмотки просуммировал бы с постоянным напряжением и подал бы на АЦП. Если в реальном времени оцифровывать не нужно, т.е. не нужно следить за формой синуса, то можно применить пиковый детектор. Ну и при применении разделительного понижающего трансформатора безопасность повышается - если где-то на плате коротнёт или пробьёт, то прибор не покалечит пользователя. В прилепленном рисунке схема, которую сам реализовывал для такого дела в случае однополярного АЦП(МК Atmega32). Применял двухполярное питание +6В..-6В, от которого питал повторитель. От этого же источника питал стабилизатор +5В, но включал так, как показано на схеме, т.е. схема стабилизатора и МК не использует и не видит среднюю точку. Подстроечный резистор нужно выставить так, чтобы на входе АЦП была половина опорного напряжения при отсутствии сигнала на входе (в моём случае 2.5В было). Размах сигнала должен вписываться в пределы от 0 до опорного(5В), с этим понятно. Регулируется этот размах коэффициентом трансформации или коэффициентом усиления усилителя. Ещё нужно на вход АЦП поставить обычную защиту из двух диодов.
  13. не работало по причине неправильной программы, это я уже выяснил :) Этот вопрос можно пока закрыть. Лучше посоветуйте в теме про стартовый загрузчик.
  14. Насколько помню, в конце сектора имеется какая-то контрольная сумма, поэтому для надёжности его нужно весь в буфер считывать и проверять правильность данных. Этот момент уточни.
  15. Покопался в настройках линкера, нашёл настройки линкера: Config->Edit->Linker configuration file editor->Vector Table-> .intvec start = 0x7000 Config->Edit->Linker configuration file editor->Memory Regions-> ROM = 0x7000 - 0x7FFFF После компилирования и запуска в пошаговом режиме видно, что программа раположена по адресу, начиная с 0x7000, на этом этапе всё работает нормально - данные бегут из UART0. Получается, что программа уже нормально записана в память и работоспособна. Далее пробую написать маленькую программу, расположенную в обычном месте, т.е. в начальном секторе флеш. Пишу такой текст: main() { asm ("B 0x7000"); } Перебрал несколько возможных адресов, но всегда зависает в Hard Fault. В каком известном векторе прерывания находится адрес обработчика? Как узнать этот адрес? Написал маленькую тестовую программу без подключения библиотек и лишних файлов unsigned int *VTOR int main() { VTOR = (unsigned int*)0xE000ED08; //адрес регистра смещения таблицы *VTOR = 0x7000; //смещение адреса таблицы веторов прерываний asm ("B 0x7000"); //адрес перехода } Т.е. 1. Прерывания не разрешал, близко к ним не подходил в этом коде. 2. Переферию не трогал 3. С этим вопрос - как узнать адрес? 4. По какому адресу переходить? Как его узнать? UP1: в прикреплённом архиве проект основного ПО и второй проект тестовой программы, которая должна запускть основное ПО ______________________________________________.rar
  16. У меня было ошибочное предположение, что адреса таблиц нужно вписывать в регистры вручную перед вызовом IAP, что я и делал: asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц asm ("mov r1, #0x6100"); asm ("movt r1, #0x2000"); Поэтому в моём представлении инкременты ничего не меняли, но в любом случае вариант кода из первого поста не работал.
  17. Спасибо, заработало :-) Выкинул ассемблер, упростил и в итоге получился работающий код: #include "iolpc1778.h" #include "LPC17xx.h" #define IAP_LOCATION 0x1fff1ff1 //точка входа в IAP (страница 896 мануала) unsigned int command[5]; unsigned int result[2]; unsigned int *test; typedef void (*IAP)(unsigned int[], unsigned int[]); void main(void) { { //INIT SCS |= 0x20; //подключение осциллятора 12МГц while(!( SCS & 0x40 )) {} //ожидание запуска PLL0CON |= 0x01; //включение PLL0 PLL0CFG |= 0x09; //умножение частоты тактирования на (1+9) - 120МГц PLL0FEED = 0xAA; // PLL0FEED = 0x55; // CCLKSEL |= 0x100; //тактирование CPU от PLL0 } test = (unsigned int*)0x20001004; *test = 0xAA; IAP iap_entry; iap_entry = (IAP) IAP_LOCATION; //_______ПОДГОТОВИТЬ СЕКТОР К ЗАПИСИ_______// { command[0] = 50; //код команды command[1] = 4; //начальный номер сектора command[2] = 4; //конечный номер сектора iap_entry (command, result); } //_______ПОДГОТОВИЛИ СЕКТОР К ЗАПИСИ______// //_______СТЕРЕТЬ СЕКТОР_______// { command[0] = 52; //код команды command[1] = 4; //начальный номер сектора command[2] = 4; //конечный номер сектора command[3] = 120000; //системная тактовая частота в кГц iap_entry (command, result); } //_______СТЁРЛИ СЕКТОР______// //_______ПОДГОТОВИТЬ СЕКТОР К ЗАПИСИ_______// { command[0] = 50; //код команды command[1] = 4; //начальный номер сектора command[2] = 4; //конечный номер сектора iap_entry (command, result); } //_______ПОДГОТОВИЛИ СЕКТОР К ЗАПИСИ______// //_______КОПИРОВАТЬ ОПЕРАТИВНУЮ ПАМЯТЬ ВО ФЛЕШ_______// { command[0] = 51; //код команды command[1] = 0x4000; //начальный адрес перезаписываемой флеш command[2] = 0x20001000; //начальный адрес оперативной памяти, откуда нужно копировать command[3] = 512; //число байт для копирования command[4] = 120000; //системная тактовая частота в кГц iap_entry (command, result); } //_______СКОПИРОВАЛИ СЕКТОР______// while(1) { test = (unsigned int*)0x4004; } } Интересно узнать, в чём суть подготовки памяти? Со стиранием вроде понятно - наверно FFFFFFFами заполняет всё. И ещё есть не совсем понятная команда заполнения пробелами. Правильно я понимаю, что 0x1fff1ff1 есть адрес начала отдельной программы IAP?
  18. среда IAR В мануале написано, что нужно зарезервировать верхние байты. Что имеется ввиду под верхними байтами, если считать за начало адрес 0x2000000, а за конец 0x2008000? Эти 32 байта распложены в области 0x2000000 - 0x200001F или в другом конце?
  19. С этим тоже вопрос. Как зарезервировать место в памяти?
  20. Решил данный вопрос задать в отдельной теме, ответвив от темы про стартовый загрузчик http://electronix.ru/forum/index.php?showt...15&start=15 Там подсказали насчёт организации записи флеш из пользовательской программы. Сделал по мануалу, т.к. примеров пока не видел. Получилось вот так: #include "iolpc1778.h" #include "LPC17xx.h" #define IAP_LOCATION 0x1fff1ff1 //точка входа в IAP (страница 896 мануала) unsigned long *command; unsigned long *result; unsigned int *test; typedef void (*IAP)(unsigned int*, unsigned int*); void main(void) { { //INIT SCS |= 0x20; //подключение осциллятора 12МГц while(!( SCS & 0x40 )) {} //ожидание запуска PLL0CON |= 0x01; //включение PLL0 PLL0CFG |= 0x09; //умножение частоты тактирования на (1+9) - 120МГц PLL0FEED = 0xAA; // PLL0FEED = 0x55; // CCLKSEL |= 0x100; //тактирование CPU от PLL0 } test = (unsigned int*)0x20001004; //записал контрольный байт в копируемую область RAM *test = 0xAA; IAP iap_entry; //так в мануале написано iap_entry = (IAP) IAP_LOCATION; //---//--- //_______СТЕРЕТЬ СЕКТОР_______// { result = (unsigned long*)0x20006100; //адрес расположения таблицы результатов command = (unsigned long*)0x20006000; //адрес таблицы параметров *command = 52; //код команды *command++; *command = 4; //начальный номер сектора *command++; *command = 4; //конечный номер сектора *command++; *command = 120000; //системная тактовая частота в кГц asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц asm ("mov r1, #0x6100"); asm ("movt r1, #0x2000"); iap_entry (command, result); } //_______СТЁРЛИ СЕКТОР______// //_______ПОДГОТОВИТЬ СЕКТОР К ЗАПИСИ_______// { result = (unsigned long*)0x20006100; //адрес расположения таблицы результатов command = (unsigned long*)0x20006000; //адрес таблицы параметров *command = 50; //код команды *command++; *command = 4; //начальный номер сектора *command++; *command = 4; //конечный номер сектора asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц asm ("mov r1, #0x6100"); asm ("movt r1, #0x2000"); iap_entry (command, result); } //_______ПОДГОТОВИЛИ СЕКТОР К ЗАПИСИ______// //_______КОПИРОВАТЬ ОПЕРАТИВНУЮ ПАМЯТЬ ВО ФЛЕШ_______// { result = (unsigned long*)0x20006100; //адрес расположения таблицы результатов command = (unsigned long*)0x20006000; //адрес таблицы параметров *command = 51; //код команды *command++; *command = 0x4000; //начальный адрес перезаписываемой флеш *command++; *command = 0x20001000; //начальный адрес оперативной памяти, откуда нужно копировать *command++; *command = 512; //число байт для копирования *command++; *command = 120000; //системная тактовая частота в кГц asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц asm ("mov r1, #0x6100"); asm ("movt r1, #0x2000"); iap_entry (command, result); } //_______СКОПИРОВАЛИ СЕКТОР______// while(1) { test = (unsigned int*)0x4004; //для просмотра ячейки в отладчике в пошаговом режиме. } } Работать почему-то не хочет - как было во флеш FFFFFFFFFFFF, так и остались. Ещё в мануале написано, что содержимое регистров r0 и r1 остаётся постоянным во время работы с флеш-памятью, но у меня в пошаговом режиме видно, что после функции iap_entry (command, result); они меняются. Так же там написано, что в регистры r0 и r1 записываются начальные адреса таблиц параметров и результатов. Можно ли в моём коде избавиться от ассемблерных вставок, т.к. каждый раз вручную назначать адреса таблиц в памяти неудобно и нежелательно. Ещё там написано, что верхние 32 байта RAM не должны использоваться пользовательской программой, но как программе запретить пользоваться этими байтами? UP1: добавил файл проекта в IAR 20141001LPC.rar
  21. Но ведь хочется спросить и тут разжёваный ответ получить :rolleyes: Спасибо за направляющий ответ, буду копать. Как в общих чертах происходит запись блока? Какие шаги нужно проделать?
  22. Пока в исходник загрузчика глубоко не влазил. Хочу попробовать что-либо записать во флеш из программы. т.е. если написать вот так: adres = (unsigned int*)0x20000200; //область оперативной памяти *adres = 0x12345678; то всё нормально - в ячейку с указанным адресом записывается число, а если написать вот так adres = (unsigned int*)0x1000; //область флеш-памяти *adres = 0x12345678; то ничего не записывается. Тут нужно предварительно какие-то настройки делать. В мануале что-то написано, но нет примеров. Хотелось бы увидеть самый простой пример включения возможности записи в ячейку флеш. МК LPC1778
  23. Тут надо разделить магнитные помехи и электрические. От магнитных помех спасёт пермаллой, а от высокочастотных электрических обычно экранируют не сплошным металлом, а сеткой с круглыми отверстиями, как Вы наверно видели внутри сотовых телефонов. Если правильно помню из курса технической электродинамики, такие отверстия называются вырожденными волноводами, т.е. такие волноводы, которые физически не могут пропустить электромагнитные волны выше определённой частоты. На 100% правильность совета не претендую ввиду почти полностью забытых мной лекций по СВЧ, но я бы поэкспериментировал бы с дырчатыми экранами.
  24. я бы выложил последовательность действий скринами, понятнее стало бы
  25. А если заменить кварц? Среди них тоже бывают бракованные. И ещё смущает такая частота, для MSP430 это как-то многовато, я разгонял PLL максимум до 20МГц, а кварц ставил до 8-10 МГц. Может МК работает на пределе частоты и повышение температуры его добивает? Остальной код нормально работает?
×
×
  • Создать...