Jump to content

    

ДЕЙЛ

Участник
  • Content Count

    258
  • Joined

  • Last visited

Everything posted by ДЕЙЛ


  1. Провал это и есть резонанс - на первой гармонике ток минимальный, поэтому она и вырезается. Эти остатки меандра можно пустить через RC-цепь и на вход АЦП. По минимальному напряжению можно ловить резонанс. Ну или программным способом складывать отсчёты за период.
  2. в описании ядра сказано, что при многоуровневой вложенности нужно думать о размере стека, вот и интересуюсь. Какая функция задаёт этот размер? ПЫСЫ Имел ввиду не даташит, а user manual, т.е. руководство пользователя
  3. С уровнями приоритетов разобрался. Ошибка была в том, что я заблуждался относительно предустановки уровней приоритетов. По умолчанию все программируемые прерывания имеют приоритет 0, т.е. самый высокий. Выше только немаскируемые с приоритетами -1 -2 и -3. А у меня получилось, что прерывание от UART0 и от системного таймера имели одинаковый приоритет и поэтому не было вложенности. Добавил две строки в коде при инициализации: AIRCR = 0x05FA0200; //приоритет группы - поле [7:3], субприоритеты отключены, т.к. [2:0] не задействованы IP1 = 0x800; //уровень приоритета - 1, биты [2-0] не задействованы. Остался открытым вопрос по настройке приоритета прерывания системного таймера. Он программируемый, судя по описанию ядра CORTEX-M3, но в даташите пока не откопал ничего по этому поводу. Ещё в описании рекомендуют указывать размер стека. Как он указывается?
  4. В цепь затвора нужно поставить резистор 20-30 Ом для ограничения тока заряда-разряда ёмкости затвора и для устранения теоретической возможности появления "звона" фронтов. Погугли "резистор в цепи затвора". Сам когда-то столкнулся с непонятной причиной вылета транзисторов в схеме ШИМ-управления двигателем, хотя допустимые пределы по току и напряжению не превышал, но у меня не было ограничительных резисторов затвора. После их установки ни один транзистор не вылетел. Случай в моей практике единичный, поэтому на правило не претендует. Возможно, просто совпадение. В любом случае на разведённой плате вместо резистора всегда можно легко поставить перемычку.
  5. На другом форуме сказали посмотреть регистры уровней приоритетов PRI_x. Думаю, что у меня было заблуждение насчёт приоритетов прерываний от системного таймера, входящего в состав ядра и от переферийного модуля. Вполне возможно, что по умолчанию у всех прерываний с программируемым уровнем приоритета он одинаковый и равен нулю. Вечером отпишусь насчёт этой версии после проверки.
  6. Приоритеты прерываний не менял - они по умолчанию уже установлены. Пробовал менять местами обработчики, т.е. зацикливание делал в обработчике системного таймера, а отправка байта в UART0 вызывала соответствующее прерывание, которое по идее должно было бы вытеснить IRQ_SysTick, если бы у него был бы более низкий приоритет. Равенство приоритетов этих двух прерываний слишком маловероятно, поэтому руководствовался документацией, в которой IRQ_SysTick имеет приоритет 15, а UART0 - 21. В LPC17XX.h указан аналогичное соотношение приоритетов SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt .......... UART0_IRQn = 5, /*!< UART0 Interrupt Может быть нужно перевести главную программу в режим потока установкой бита CONTROL[0]? Сейчас главная программа работает в режиме обработчика, как и должно быть по умолчанию после сброса. Просто в данный момент нет платы под рукой, чтобы проверить.
  7. Схем на эту тему и в инете полно, гугл их тысячи знает ;) тут не стоит тратить особо много времени на велосипед http://el-shema.ru/publ/pitanie/indikator_...atora/5-1-0-285 К твоему случаю подходит.
  8. Данная функция нужна для разрешения исключений с номером 16 и выше, как я понял. К системному таймеру относится исключение №15. Чуть выше была картинка из даташита - http://electronix.ru/forum/index.php?act=a...st&id=85886 Судя по этому, аналогичное разрешение прерывания системного таймера не требуется в виде такой функции - его приоритет выше строжевого таймера. Пробовал вставлять такую же функцию для SysTick - cрабатывает прерывание Hard Fault. NVIC_ClearPendingIRQ(UART0_IRQn) - можно и в начало поставить, но насколько это принципиально? Это просто сброс бита прерывания, в данном случае прерывания от UART0, чтобы после завершения текущего обработчика он не вызвался снова. Прерывания работают и вызываются в данном случае, чуть выше в этой теме была такая проблема. Если в низкоприоритетном обработчике IRQ_UART0 не ставить while(1){}, то всё нормально - таймер тикает, принятый байт тоже вызывает прерывание. Бесконечный пустой цикл поставил в обработчике IRQ_UART0 намеренно, чтобы посмотреть, как будет вести себя более высокоприоритетный обработчик IRQ_SysTick во время работы зависшего в бесконечном цикле while(1) обработчика IRQ_UART0.
  9. в самой первой схеме последовательно с выводом затвора нужно поставить резистор 10-20 Ом для защиты от колебательных выбросов на затворе, который с каналом образует конденсатор. Суть в том, что цепь можно представить RLC эквивалентом и при неудачном сочетании параметров переходная функция может иметь выброс в 2 раза больше уровня подаваемого напряжения - т.н. звон фронтов с возможными неприятными последствиями в виде пробоя затвора от вроде бы 5 вольт и лишеного нагрева транзистора. Так вот резистор в несколько Ом гарантированно защищает от такого дребезга при реальном соотношении L и С порядка наногенри и пикофарадов. Моделировал в MathCAD на досуге.
  10. Продолжаю начинать осваивать LPC. Читаю про вложенные прерывания. Логику работы я понимаю так: если во время выполнения прерывания появляется запрос от источника с более высоким приоритетом, то текущая процедура обработчика приостанавливается на время выполнения обработчика более высокоприоритетного прерывания и после этого продолжается выполнение. Более высокоприоритетное прерывание приостанавливает работу низкоприоритетного так же, как обычное прерывание приостанавливает главную программу в 8битных МК? написал вот такой код: #include "C:\10062014LPC\iolpc1778.h" #include "C:\10062014LPC\src\inc\LPC17xx.h" void main(void) { { //INIT //Инициализация ножек IOCON_P1_25 = 0; //PIO FIO1DIR = 0x2200000; //Выходы PIN1_25, PIN1_11 PCONP |= 0x8; IOCON_P0_02 = 0x1; IOCON_P0_03 = 0x1; FIO0DIR = 0x4+0x8; //Настройка тактирования SCS |= 0x20; //подключение осциллятора while(!(SCS&0x40)){} //ожидание запуска PLL0CON |= 0x01; PLL0CFG |= 0x09; PLL0FEED = 0xAA; PLL0FEED = 0x55; CCLKSEL |= 0x100; PCLKSEL = 1; CLKSRCSEL |= 1; //Настройка UART0 U0LCR |= 0x83; //razrecchenie dostupa k delitely U0DLL = 0xC8; //0xF0;//0xA0; //0x14; //0x4E; //nastrojka delitelya U0LCR &=~0x80; //zapret dostupa k delitely U0IER |= 0x1+0x4;//Разрешение прерываний UART0 NVIC_EnableIRQ(UART0_IRQn); //Enable IRQ UART0 (ISER0=32) //Настройка системного таймера SYSTICKCSR = 0; SYSTICKRVR = 0xF423F; SYSTICKCVR = 2; SYSTICKCSR |= 7; } //Пустой бесконечный цикл while(1){ } } ///////////////////////////// IRQ ///////////////////////////////////// //IRQ_UART0 void UART0_IRQHandler(void) { for (int i=0; i<2; i++) //2 импульса (канал_2 осциллографа) { FIO1CLR = 0x2200000; //pin; //0 FIO1SET = 0x2000000; //pin; //1 FIO1CLR = 0x2200000; //pin; //0 } while(1) {} //здесь должна висеть процедура обработчика IRQ_UART0 NVIC_ClearPendingIRQ(UART0_IRQn); return; } //IRQ_SYSTICK void SysTick_Handler(void) { //1 импульс (канал_1 осциллографа) FIO1CLR = 0x2200000; //pin; //0 FIO1SET = 0x200000; //pin; //1 FIO1CLR = 0x2200000; //pin; //0 return; } Логика задумана такая: имеются два прерывания - UART0 и от системного таймера. После запуска и инициализации в первом канале осциллографа вижу работу обработчика прерываний системного таймера - короткие импульсы с частотой 120Гц. Тут всё нормально. Далее отправляю байт на вход UART0, во втором канале появляются два импульса, т.е. в прерывание вошли и после этого в обработчике стоит бесконечный цикл while(1) {}. Это для того, чтобы МК не выходил из обработчика IRQ_UART0. Но почему-то данный бесконечный цикл не прерывается для выполнения прерывания от системного таймера. В чём тут может быть проблема? Неправильная настройка или я неправильно понял смысл вложенности прерываний? 10062014LPC.rar
  11. Можно и одним резистором обойтись, не вопрос. А схему сами угадайте. Это к тому, что свою мысль очень желательно проиллюстрировать для повышения образованности читателей ;)
  12. Можно совсем закоротить R2 и если эффект не устранится, то конденсатор будет бесполезен. Так тут гистерезис по напряжению, а я имел ввиду временнУю задержку. После запуска в МК счётчик будет считать с нуля до времени T, по достижении которого запускается алгоритм контроля напряжения с помощью АЦП. Если питание у МК будет нестабильным, то пройдёт несколько RESETов до стабилизации питания, но это никак не повлияет на ключ, т.к. между кратковременными интервалами времени между сбросами счётчик не будет успевать досчитать до Т, а когда сможет досчитать, то это будет признаком стабилизации напряжения и тут уже можно запускать алгоритм сравнения или оцифровки. Это аналогия с алгоритмом работы детектора провалов напряжения питания в МК MSP430.
  13. В данном случае от статики пробоя не должно быть - затвор и исток под одним потенциалом при выключенной схеме или разность потенциалов не больше 12-15В при включенной.
  14. Заработало :08: Спасибо большое!
  15. Так понимаю, что схему нужна для того, чтобы подавать питание в нагрузку после того, как питающее напряжение превысит какой-то заданный порог, который и отслеживает компаратор. Если все элементы на одной плате и питаются от одного источника напряжения, включая компаратор, то может иметь место переходной процесс в схеме компаратора в тот момент, когда подаётся напряжение питания. Попробуй плавно и медленно поднимать напряжение на входе платы, может что-то и прояснится. Если компаратор и ключ питаются от одного источника, то я разделил бы питание на две ветви: 1. Цепь питания схемы сравнения. 2. Цепь питания ключа. Получилось бы, что схема управления вошла бы в режим раньше, чем появится напряжение на ключе. Можно и дальше усовершенствовать схему, добавив диод после конденсатора и тогда можно добиться того, что на конденсаторе время нарастания напряжения до 0.6 вольт окажется болше времени нарастания напряжения компаратора до рабочего значения. А так да, нужно видеть схему полностью. Если есть возможность изменить схему, то управляющую часть проще сделать на МК в корпусе DIP8, если у него есть АЦП. В программе организовать алгоритм, который включает нагрузку через несколько секунд после превышения порога - это будет гарантией от ложных срабатываний.
  16. Вечером попробую. Интересно узнать ещё мнение насчёт моего байта 0xAA в регистре U0DLL, который по логике должен находиться в U0RBR.
  17. Прогнал в отладчике через JTAG пошагово. Запустил, отправил байт и сделал Break. Программа зависла в указанном на рисунке месте и никуда не сдвигается. В чём тут может быть причина? В обработчик программа не входит, т.к. переменная pin не изменилась. Каким образом мой байт 0xAA всегда попадает в регистр U0DLL? Это же не приёмный буфер, а делитель. mempfis_, можно увидеть Ваш код программы, к которой относится показанный обработчик?
  18. Дело видимо не столько в наводках, сколько в токах утечки. На высоких частотах конденсаторы шунтируют полезный сигнал, при низких частотах потенциал экрана будет равен среднему потенциалу между входами при любых внешних условиях. Ток утечки определяется разностью потенциалов, которая в данном случае не выше определённого предела порядка максимальной амплитуды полезного сигнала. На практике встречался с такой проблемой - был усилитель с гигаомным входным сопротивлением и сигнал размахом несколько микровольт. Никакие витые пары не помогали - утечки и выходной сигнал жили своей жизнью. Помогла схема из Хоровица и Хилла. Здесь что-то похожее. Хотя и самоподавление синфазных помех тоже происходит, соглашусь. Только в этом случае разумнее было бы применить инструментальный усилитель вроде AD820 или AD620.
  19. Хоровиц и Хилл - хорошая книга, для изучения азов самое то. Далее посоветовал бы купить два тома "1000 и одна микроконтроллерная схема" http://rutracker.org/forum/viewtopic.php?t=3822998 - стиль написания примерно такой же с годными и негодными схемами, но уже с применением микроконтроллеров. И вот ещё хорошая книга на уровне Хоровица, но с более современной элементной базой "Схемотехника аналоговых и аналого-цифровых электронных устройств" http://mirknig.com/knigi/apparatura/118111...ustrojjstv.html
  20. Для меня это уже следующий этап, сейчас нужно как-то зайти в этот обработчик. Насчёт источников прерывания тоже понятно - аналогия с MSP430, где двум портам соответствуют два вектора, а в обработчике уже разбор битов ножек. Упростил свою программу до такоо вида, оставив саму суть вопроса: #include "C:\10062014LPC\iolpc1778.h" #include "C:\10062014LPC\src\inc\LPC17xx.h" int N, pin; void main(void) { //INIT //Настройка ножек IOCON_P1_25=0; //PIO FIO1DIR=0x2200000; //Выходы PIN1_25, PIN1_11 PCONP|=0x8; //Питание модуля UART0 IOCON_P0_02=0x1; //На ножках переферийный модуль (TX, RX) IOCON_P0_03=0x1; FIO0DIR=0x4+0x8; //Настройка тактирования SCS|=0x20; //подключение осциллятора while(!(SCS&0x40)){} //ожидание запуска PCLKSEL=1; CLKSRCSEL|=1; U0LCR|=0x83; //разрешение доступа к делителю U0DLL=0x14; //настройка делителя U0LCR&=~0x80; //запрет доступа к делителю U0IER|=0x1+0x4; //Разрешение прерываний UART0 __set_PRIMASK(0); //Разрешение __set_FAULTMASK(0); //всех прерываний __set_BASEPRI(0); //Отключение маскирования NVIC_EnableIRQ(UART0_IRQn); //Enable IRQ UART0 (ISER0=32) pin=0x200000; //изначально импульсы на ножке P1.11 while(1) { FIO1CLR=pin; //0 FIO1SET=pin; //1 FIO1CLR=pin; //0 } } void UART0_IRQHandler(void) { N=U0RBR; //прочитаем на всякий случай принятое pin=0x200000+0x2000000; //после выхода из прерывания //точно такие же импульсы появляются на P1.25 NVIC_ClearPendingIRQ(UART0_IRQn); return; } По моей задумке при выполнении этой программы на одной ножке кристалла (P1.11) в бесконечном цикле генерируются прямоугольные импульсы. Эта часть работает, что наблюдаю на осциллографе. При отправке одного байта с ПК в прерывании выполняется операция, после которой в основной программе в бесконечном цикле точно такие же импульсы формируются на второй ножке(P1.25), т.е. на осциллографе второй канал станет рисовать копию первого сигнала. Это будет оворить о том, что был выполнен вход в прерывание, выполнились соответствующие действия и нормально вышли в главную программу. Но пока не работает - при отправке байта процессор зависает и бесконечный цикл главной программы останавливается, импульсы не формируются. Байт отправляется правильно, т.к. его визуально наблюдал при приёме данных, но эту процедуру в коде убрал, настройки тактирования оставил без изменений. Что я не досмотрел в коде? вот это не глянул, утром почитаю и вечером попробую, рабочий ноут на проверку диска поставил, но всё же хотелось бы почитать критику моего кода со стороны более опытных коллег :) 10062014LPC.rar
  21. как тогда указать компилятору, что эта функция выполняется по прерыванию? в startup откопал вот эту функцию: UART0_IRQHandler Только в модуле UART0 несколько источников прерываний, скрин описаний в прикреплённом файле. Как программе указать, что прерывание нужно именно после приёма байта? по этому вопросу откопал в даташите:
  22. В данном случае усложнение схемы таким способом неоправдано. Исходя из своего опыта, я сделал бы так: 1. Сократил бы до минимума расстояние между ЧЭ и усилителем. Если это невозможно, то после чувствительного элемента поставил бы повторитель на операционнике (буфер). Буфер будет актуален в том случае, если у источника сигнала высокое выходное сопротивление. Питание данного буфера тоже нужно отфильтровать - RC-цепь по каждой линии питания (резистор несколько ом+электролит микрофарад на 50+керамику порядка нанофарада). 2. Провод до усилителя провёл бы витай парой для избавления от магнитных наводок. 3. Для устранения электрических помех нужно поверх витой пары надеть экран из оплётки, оплётку припаять к среднему проводу схемы при двухполярном питании или к минусу при однополярном. Для примера можно посмотреть схемы подключения магнитной головки в кассетном магнитофоне и раскорячить его с этой же целью.
  23. Сегодня утром вчитался получше в описание регистра BASEPRI Похоже, что вместо __set_BASEPRI(0xFFFFFFFF); надо было написать __set_BASEPRI(0); или не трогать его, оставив по умолчанию 0.
  24. Листинг в общих чертах такой: Инициализация и настройка тактирования 1: U0IER|=0x4; //Разрешение прерывания по приёму байта в RX 2: __enable_irq(); //Разрешаем прерывания (CMSIS) 3: __set_BASEPRI(0xFFFFFFFF); //Разрешаем все прерывания (CMSIS) 4: NVIC_EnableIRQ(UART0_IRQn); //Разрешение прерывания UART0 (CMSIS) while(1) { Циклическая отправка данных на ПК } 5: __irq void UART0_IRQ1(void) { for (k=0; k<200; k++) { FIO1SET=0x2000000; //Подёргаем ножкой 200 раз FIO1CLR=0x2000000; } } Хочу сделать так, чтобы при появлении байта в буфере приёма UART вызывалось прерывание. Вот с этим вызовом прерывания проблема и пока не знаю, с какой стороны к ней подходить. Вопросы такие: 1. Правильно ли я выполнил настройки? (строки 1-4) в строке 4 в качестве параметра функции передаётся UART0_IRQn. Что значит эта n? Её так и нужно оставлять или вместо n нужно какое-то число стаить? Хотя компилятор ругается. 2. Правильно ли я оформил обработчик прерывания? (строка 5). В этой строке пробовал писать название функции от UART0_IRQ1 ло UART0_IRQ10. Компилятор не ругался, но и толку никакого не было, на осциллографе не видел дёрганий ножки после отправки байта с ПК. На что влияет выделенное число? Данные в буфер приёма однозначно приходят правильные с ПК. На скрине моя программа в сыром виде. При нажатии кнопки "ТЕСТОВАЯ" с COM-порта отправляется 1 байт 0xAA, который я вижу принятым программой от МК (выделено). Т.е. с приёмом нормально всё, но не совсем удобно каждый раз смотреть на буфер, куда удобнее считывать из него байт по прерыванию. Ну и с настройкой прерываний разобраться нужно. И ещё имеется такой регистр //SETENA0=0xFFFFFFFF; В описании написано, что каждый бит этого регистра разрешает или запрещает соответствующее прерывание. Как понять, к какому прерыванию относится конкретный бит?
  25. Думается мне, что в функции SystemInit изначально заложен пример инициализации и ошибки здесь нет. Просто образец или шаблон, но эту функцию под каждый проект нужно переписывать - настроивать тактирование и конфигурацию кристалла под себя.