Jump to content

    

Alechin

Свой
  • Content Count

    158
  • Joined

  • Last visited

Community Reputation

0 Обычный

About Alechin

  • Rank
    Частый гость
  • Birthday 10/27/1973

Контакты

  • Сайт
    Array
  • ICQ
    Array

Информация

  • Город
    Array

Recent Profile Visitors

1590 profile views
  1. я разрабатываю кардиостимуляторы. Могу отвечать только за производимые нами. Мы проходим полный комплекс проверок на электромагнитные воздействия. Самому стимулятору ничего не будет. Проблема в другом: стимулятор непрерывно "слушает" сердце. если сердце работает само - стимулятор не выдает стимул на него. Сигналы сердца имеют уровень 0.3 мВ. Поэтому внешнюю наведенную помеху стимулятор может воспринять за "работу сердца" и прекратит его стимулировать. Что может негативно сказаться на пациенте. При пропадании опмехи штатная работа воостановится. Поэтому на 100% зависимого от стимулятора человека возможны негативные последствия. для остальных - маловероятны.
  2. Отбой - нашел ошибку: есть одна короткая фраза в мануале, которую я не увидел сразу: For write and erase operations on the Flash memory (write/erase), the internal RC oscillator (HSI) must be ON Вопрос такой: теперь не удается работать (стирать/писать) во внутреннюю флеш. При записи улетаю в BusFault, при стирании - вообще проц. умирает: отладчик IAR (с ST-LINK) зависает. Вот пример кода записи слова: static void Write(WORD32 Flash_Addr, WORD16 val) { FLASH_KEYR = UNLOCK_KEY1; // Разблокируем контроллер. FLASH_KEYR = UNLOCK_KEY2; if((FLASH_CR & (1 << LOCK)) == 0) { FLASH_CR() |= (1 << PG); *(WORD16 *)Flash_Addr = val; // Пишем - вот здесь возникает BusFault while((FLASH_SR & (1 << BSY)) != 0); // Ждем готовности. FLASH_CR() &= ~(1 << PG); FLASH_CR |= (1 << LOCK); } }
  3. Да вроде все в норме: UARTовский загрузчик запускается при правильной комбинации. При комбинации "все нули" UARTовский загрузчик не запускается. Записанная через него (или ST-Link) программа нет. Проц - 103VG
  4. Не могу заставить процессор запускаться с программой из флеши. Писал-писал, отлаживался в IARе через ST-Link. А тут решил включить плату отдельно - не хочет запускать программу! ST-Link Utility показывает, что файл прошит. Но стартует программу только если нажать "Core Reset" В чем может быть причина?
  5. А как-нибудь сделать обработчик членом класса можно? Имя то будет уже другим. "В лоб" не получилось. Например самый простой вариант - SysTick таймер.
  6. ну то, что нет деструктора это понятно. А вот конструктор должен быть - надо ведь проинициализировать и "запустить" таймер. Иначе в начале программы придется все делать руками (типа методы Init() вызывать). Моя задача полность оградить программиста от работы с какой-либо аппаратурой. Т.е. он должен знать, что есть класс "таймер" с известным тиком, экземпляры корого он создает и пользует, есть класс "цифровой потенциометр" в котором он устанавливает значения. А уж какие-там ножки, прерывания задействованы, программный или аппаратный SPI там - это его не должно касаться. Все это прописано в моем хидере, который он просто подключает к проекту. Что-либо править в данном хидере ему нельзя. где на это посмотреть? В принципе я сейчас создал класс таймера (программного), при создании которого конструктору передаю адрес класса аппаратных таймеров. Компилятор молодец - никакого оверхеда! Ну в принципе адреса классов аппаратных таймеров известны на этапе компиляции, так наверное он так и должен был поступить (просто подставить адреса, а не использовать указатель). Плохо то, что неизвестно, можно ли это гарантировать при других уровнях оптимизации например, или смене версии компилятора.
  7. Хорошо, допустми каким-либо образом мне удалось создать экземпляры класса таймеров. Теперь хотелось бы создать класс индивидуального таймера. Если создать наследника каласса таймеров - получим вызов конструктора базового класса (класса таймеров) при создании каждого экземпляра таймера. Что не нужно (и не правильно). Убрать вызов конструктора базового класса невозможно? Хорошо, создаем самостоятельный класс. Тогда будем передавать в конструктор класса таймера ссылки/адреса на базовый класс. При этом подстановки компилятор уже не будет делать и получим овехед? Как тут "выкрутиться"?
  8. Делал - говорю-ж - криво выходит. Во первых обработчики всегда будут существовать - т.е. при попытке задействовать другой обработчик линковщик ругается на два определения обработчика. Во вторых - изначально собирался ввести еще один аргумент шаблона: "функцию" таймера - выставление флага (SIGNAL_TIMER) или вызов процедуры (PROC_TIMER). А это уже другие действия в обработчике. Т.е. уже четыре обработчика. А тут уже никак. Через один универсальный шаблон все очень компактно и красиво получилось. Кроме того, что обработчиков прерываний в коде нет :( А, я несколько не так понял. Так, должно получиться. И наверное даже компилятор подставновку сделает (т.е. не будет лишнего вызова). Проблема тогда только в том, что бы как-нибудь "красиво" задать обработчик - т.е. как бы дистанцируясь от аппаратуры (не могу объяснить :( в общем есть файл hardware.h, в котором определена вся аппаратура, и далее в программе никаких прямых упоминаний аппаратуры нет. Тут так не выйдет - надо будет где-то задать конкретный обработчик конкретного прерывания, что сразу свяжет программу с аппаратурой, чего хочется избежать. А почему? Компилироваться долго будет?
  9. вот и не понимаю как. Для начала - как задать компилятору вектор прерывания? В нутри класса есть аргумент, определяющий A или B таймер. Вне класса - как определить, с каким таймером работаем? Вернее понимаю как на этапе создания класса, когда уже известно какой таймер будем использовать. Я же хочу сделать универсальный класс (ну вернее шаблон) - что бы подключил h файл и вообще не открывать его (для правки). Пишу для того, что бы она была доступна из обработчика прерывания. Ясно что в данном случае весь класс статический - т.е. более одного экземпляра существовать не может. насчет одной переменной на оба класса: я все-таки недопонимаю тогда шаблоны: ведь компилятор создает ДВА никак не связанных между собой класса, и поэтому как может получиться одна переменная на оба класса.
  10. а если я хочу созать шаблон класса с обработчиком внутри - компилятор не вставляет код обработчика. Мелькало где-то в обсуждениях, что для шаблонов именно так. Я обойти эту ситуацию не смог. Вот пример: хочу создать шаблон класса таймеров. Аргумент шаблона - используемый таймер А или B (это MSP430, но принцип должен быть один) #define MODULES_IN_TIMER_A 2 #define MODULES_IN_TIMER_B 6 #define TIMER_A 'A' #define TIMER_B 'B' template <char Timer> class TTimers { protected: static const BYTE nModules = (Timer == TIMER_A) ? (MODULES_IN_TIMER_A) : (MODULES_IN_TIMER_B); // Флаги состояния модулей захвата/сравнения. static volatile bool run[nModules]; // Старший байт счетчика времени работы таймера. static volatile WORD hi_Word_of_Tick_Cntr; public: // Конструктор класса. inline TTimers() { // Обнулим счетчик времени работы таймера. hi_Word_of_Tick_Cntr = 0; // Выключим все модули захвата/сравнения. for(register IDX i = 0; i < nModules; i++) { Dis(i); Reset(i); } // Программируем таймер: // синхронизация от ACLK, счетчик 16 бит, режим непрерывного счета, // прерывание по переполнению запрещено, все таймеры независимы. (Timer == TIMER_A) ? (TACTL = TASSEL0 + MC1 + TACLR) : (TBCTL = TBSSEL0 + MC1 + TBCLR); } // Методы управления прерываниями от модулей захвата/сравнения. static inline void Ena(IDX i) { *(&((Timer == TIMER_A) ? (TACCTL1) : (TBCCTL1)) + i) = CCIE; } static inline void Dis(IDX i) { *(&((Timer == TIMER_A) ? (TACCTL1) : (TBCCTL1)) + i) = 0x00; } // Методы загрузки значения в регистр сравнения. static inline WORD Remained(IDX i) { return *(&((Timer == TIMER_A) ? (TACCR1) : (TBCCR1)) + i) - ((Timer == TIMER_A) ? (TAR) : (TBR)); } static inline void Load(IDX i, WORD val) { *(&((Timer == TIMER_A) ? (TACCR1) : (TBCCR1)) + i) = ((Timer == TIMER_A) ? (TAR) : (TBR)) + val; } // Методы проверки/сброса/установки флага срабатывания таймера. static inline bool is_Setting(IDX i) { return run[i] == true; } static inline void Reset(IDX i) { run[i] = false; } static inline void Set(IDX i) { run[i] = true; } // Обработчик прерывания. #pragma vector = (Timer == TIMER_A) ? (TIMERA1_VECTOR) : (TIMERB1_VECTOR) static __interrupt void Timer_IRQ(void) { IDX i = (Timer == TIMER_A) ? (TAIV) : (TBIV); if(i == ((Timer == TIMER_A) ? (0x0a) : (0x0e))) { // Прерывание по переполнению. // Инкрементируем старший байт счетчика работы таймера. hi_Word_of_Tick_Cntr++; } else { // Прерывание от модулей захвата/сравнения. i = (i >> 2) - 1; Dis(i); // Запрещаем прерывания от модуля захвата/сравнения. Set(i); // Выставляем признак завершения счета. __low_power_mode_off_on_exit(); // Выходим из режима пониженного потребления. } } }; в итоге в коде нет обработчиков. Как в этой ситуации поступить? и еще: если создать два экземпляра класса (ну конечно для А и B таймеров) - переменные run у каждого экземпляра свои, а hi_Word_of_Tick_Cntr одна на оба экземпляра! В чем тут причина я так-же не смог понять.
  11. На самом деле там не совсем провода - там спирали, намотанные на что-то типа лески. Или штыри разных диаметров, но в узком диапазоне - от пол миллиметра до одного с небольшим. Заказчик уже использовал десяток разных приборов от разных производителей (причем в основном импортных). Только в одном были цанги. И по опыту эксплуатации этих приборов он (заказчик) однозначно выбрал цанги. Зато это самый надежный вариант: еще раз повторю: провод из терминального рычажного блока можно "случайно" вытащить нажав на рычаг, если рычажки тугие или мелкие, или клеммник нажимной (ну нажимать ответкой) - то врач на операции заниматься такой работой не будет - просто выбросит прибор (я бывал на операциях, они такие, "эмоциональные", еще и матом могут очень жестко прокомментировать :) Ладно, это уже не по теме пошло. Да, кстати, на первое место по удобству инсталляции, они поставили обыкновенные "крокодилы". И часто на буржуйских приборах есть дополнительные кабели-переходники с разъема/клеммника на "крокодилы". Но это, конечно, для использования только во время операций. Когда пациент ходит с данным прибором - это не приемлимо.
  12. На самом деле заказчик показал нам "буржуйский" прибор с цангами и сказал - что "нужно так-же, все остальное мы уже проходили и оно нам нафиг не надо". Так что с рычажками может и "круто", жаль только заказчика не устраивает :( Что-ж, жаль, что нет такого. Придется скорее всего самопалом заниматься, благо наше производство позволяет в небольших количествах делать "чуднЫе" вещи :)
  13. Не знаю о каком мире Вы говорите..... Используют обычно то, что нужно, а не то, что есть в наличии в большом количестве. А мне нужно именно то, картинку чего я привел. Более подробно что, зачем и почему я расписал там http://caxapa.ru/170594.html
  14. Надо иметь возможность быстро и надежно подключать проводники от 0.4 до 3-ех мм. На буржуйском приборе видел чудненький цанговый зажим. поиски по всяким каталогам ни к чему не привели. Не уж то в природе таких нет и придется самим городить из цанговых зажимов (от микродрелей :)? Типа такого:
  15. В 218x возможно только два варианта загрузки - по параллельной шине (8-ми разрядной - как раз из внешнего ПЗУ как EZ-Lite) и по шине прямого доступа в память IDMA. Из ПЗУ процессор загружается сам, по IDMA его грузят извне (например внешний микроконтроллер). Никакого загрузчика, как 219x в нем нет. То, что программу в EZ_Lite можно грузить по RS232 - заслуга зашитой в ПЗУ программы-монитора.