STM32 + SS495A

Nov 20, 2012 17:55

Сегодня с утра нашел немного времени и прикрутил к своей макетке датчик Холла. Так как изменения небольшие, я просто обновил старый архив: исходники.
Я решил было спаять обвязку для контроллера шаговых двигателей (L6208), но, обшарив все склады, так и не нашел резисторов на 1Ом (чтобы набрать ~0.33Ом), а лепить гирлянды из 30 резисторов не хочется. Завтра, наверное, сделаю резисторы из стальной проволоки.

SS495A - аналоговый датчик Холла, однако, он хорошо работает и в цифровых схемах. Спецификации на датчик можно найти в интернете. Скажу лишь, что в нормальном состоянии на его выходной ноге напряжение составляет около 2.5В (логическая единица STM32), в зависимости от полярности и величины внешнего магнитного поля он будет изменять свои показания в пределах 0..5В. Учитывая то, что напряжение на выходе может достигать пяти вольт, надо использовать не обычные, а "пятивольтовые" (обозначены как FR в спецификации) входы контроллера.
Имеющиеся у меня магниты (специально для этого датчика) при помещении их рабочей поверхности в пределах 1мм от "морды" датчика (маркированная сторона) приводили к появлению на его выходе нулевого напряжения. Причем уровень логического нуля появляется в довольно-таки небольшой зоне по координатам в параллельной маркированной стороне датчика плоскости.
Я собираюсь использовать эти датчики для контроля положения турелей нашего ИК-спектрометра. Идея простая: каждая позиция турели кодируется числом от 1 до N (где N - количество позиций в турели) в двоичном коде: есть магнитик - единица, нет магнитика - ноль (точнее, в моем случае - наоборот, т.к. без магнита на ноге будет единица). В результате на турелях фильтров (их две по шесть позиций) надо будет разместить по 9 магнитов и по три датчика Холла на неподвижной панели для считывания кода; на турель щелей (одна, 8 позиций - увы, три бита не хватит) придется ставить 13 магнитов и установить на панели четыре датчика Холла. ИТОГО: 31 магнит + 10 датчиков Холла и 10 занятых ног контроллера (выполнять дальнейшую шифровку не вижу смысла). А по классической схеме (1 датчик + 1 магнит == 1 позиция) мне пришлось бы закрепить меньше магнитов (20 штук), но вдвое больше датчиков (те же 20 штук). Хоть эти датчики и не золотые, но чем меньше проводов будет идти из криостата, тем лучше. Ну, а определять, не переохладились ли эти датчики, я буду при помощи 1-wire термометров (они заодно будут немного подогревать планку с датчиками, если часто включать АЦП).
Пока моделировать поведение на толпе датчиков смысла не имеет - я припаял всего один датчик Холла. Питание его подключил к 5В, а сигнальный выход вывел на порт PC10, который не сгорит, если на него подать 5В.
Для того, чтобы не дергать постоянно порт, я повесил на него прерывание.
Итак, вот конфигурация порта с использованием библиотеки STM32StdPeriphLib:
// enable Hall GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &GPIO_InitStructure); // Configure Hall EXTI GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource10); EXTI_InitStructure.EXTI_Line = EXTI_Line10; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure)
Оставляем вход "болтаться в воздухе"; активируем десятую линию прерываний (для десятых выводов всех цифровых портов); заставляем МКшку генерировать прерывания и на возрастающий, и на спадающий фронты сигнала на PC10; выставляем приоритет и разрешаем прерывание. Прерывание же обрабатываем просто:
// прерывание EXTI от датчика Холла void EXTI15_10_IRQHandler(){ FLAGS |= FLAG_PRINTHALL; EXTI_ClearITPendingBit(EXTI_Line10); } Обработка прерываний выполняется в бесконечном цикле, крутящемся в main():

if(FLAGS & FLAG_PRINTHALL){ if(GPIOC->IDR & GPIO_Pin_10) prnt((uint8_t*)"clear"); else prnt((uint8_t*)"Magnet"); newline(); FLAGS ^= FLAG_PRINTHALL; } если возникло прерывание от PC10 (т.е. магнит либо появился, либо покинул "поле зрения" датчика) проверяем сигнал на десятом бите порта C. Если этот сигнал нулевой (есть МП), пишем в терминал "Magnet", иначе пишем "clear". Еще можно принудительно проверить, есть датчик или нет его, нажав "h" в терминале. Терминал - все тот же com из пакета tunyserial.

В реализации этой схемы я думаю вешать прерывания только на внешние датчики каждой турели (во-первых, чтобы не было частых срабатываний при постепенном "заезде" датчиков; во-вторых, чтобы прерывание срабатывало как можно ближе к реальной позиции). Все датчики надо будет повесить на соседние, наплевательски относящиеся к пятивольтовому входу, биты портов МК. Если все они будут иметь номер ≥10, то одно-единственное прерывание будет их обрабатывать.
Принцип работы будет таким: при необходимости перемещения турели из позиции А в позицию Б МКшка сначала узнает номер текущей позиции, затем определит оптимальный маршрут движения (не обязательно ближайший - если турель будет неполнооборотная из-за того, что на нее что-нибудь придется поналепить. Далее, учитывая количество позиций, МКшка вычислит требуемое количество шагов привода, чтобы доехать до пункта назначения и начнет двигать турель. Как только сработает прерывание на выход магнита из зоны действия крайнего датчика, пользователю будет выдано соответствующее сообщение. По мере прохождения над датчиками магнитиков, будут генерироваться прерывания и пользователю будут посылаться сообщения: "зашел на позицию N", "сошел с позиции N"…
При подходе к нужной позиции возможен один из трех вариантов: датчики сработали, шаги еще есть; шаги кончились, датчик еще не сработал; успешно. Понятно, что эти варианты не предугадаешь: все зависит от механизма и его точности. Но это еще у меня впереди. Главное - работать с датчиками Холла довольно-таки просто.

железяки, stm32

Previous post Next post
Up