Хинт: программно определяем, подключено ли что-то к пину

Мне захотелось определять — подключена к устройсву пищалка или нет. Цель столь странного желания не важна, просто в зависимости от этого меняется логика работы программы.



Пищалка подключается через транзистор и резистор в 10к. Как-то так:

Если на ножке высокий уровень, то ток начнет стекать через R1 -> Q1 на землю. Но это нам ничего не даст (кроме открытого транзистора). А если мы настроим ножку как вход с pull-up? Тогда у нас получится такая схема:

Вышло что-то вроде делителя. Напряжение на ножке будет = Vcc (ну может чуть меньше), если она висит в воздухе. А если к пину подключен транзистор с пищалкой — напряжение будет меньше (К примеру у меня было 1.4V, при Vcc=3.14).

Осталось только подключить к делу АЦП, который выдаст нам значение напряжения на ножке. Вуаля:
bool IsBuzzerConnected()
{
 bool tmp_result; 
  
 GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_In_PU_No_IT); 
 
 delay_ms_tmr(2);
 
 ADC_ChannelCmd(ADC1, ADC_Channel_17, ENABLE);
 ADC_SoftwareStartConv(ADC1);
 while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
 ADC_ChannelCmd(ADC1, ADC_Channel_17, DISABLE);
 
 tmp_result = FALSE;
 
 if (ADC_GetConversionValue(ADC1)<4000)
  if (ADC_GetConversionValue(ADC1)>500) tmp_result = TRUE;
    
 GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_Out_PP_Low_Fast);   
 return tmp_result;
};

Тут я работаю с пином B1 — это 17й канал АЦП (да, ацп у нас очень многоканальный :)
Перед вызовом функции надо настроить АЦП. Примерно так:
CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE); 
ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit,ADC_Prescaler_2);
ADC_VrefintCmd(ENABLE);
ADC_Cmd(ADC1, ENABLE);

Теперь о самом коде.
Сначала я переключаю пин на вход с подтяжкой,
Затем жду пару миллисекунд (функция delay_ms_tmr — моя самописная, а не из стандартного набора)
Потом идет замер напряжения.
Решение о том, что к пину что-то подключено, принимаю если результат находится в рамках 500-4000. Если меньше, то пин видимо просто замкнул на землю, а больше — болтается в воздухе.
В конце пин переводится на выход, и далее используется для пищания пищалкой (если она есть)

Таким нехитрым образом можно, например, устроить простенькую самодиагностику устройства. Определять разрывы и замыкания линий.

Кстати, у MSP430 и STM32 пины умеют подтягиваться и к земле, и к питанию, что дает нам больше возможностей по такой-вот диагностике :)
  • +4
  • 01 августа 2012, 00:07
  • dcoder

Комментарии (20)

RSS свернуть / развернуть
А разве у AVR не подтягивается и туда, и сюда?
0
  • avatar
  • Trjam
  • 01 августа 2012, 01:05
Не, у них только вверх
+1
Ну AVR понятно, а у STM8 разве нельзя подтянуть вниз? Они же аналогичны STM32 по периферии.
0
У STM8L такое есть для аналогового режима (регистр RI_RCR).
+1
Точно, а я и не знал. Там вообще куча интересного в этом RI прячется :)
0
Надо же, с xMega попутал, там и вниз, и вверх.
0
только пуллап — к питанию.
0
Если нужно, ничего не стоит и снаружи резистор поставить. Необходимость подтягивать вниз встречается крайне редко.
0
У резистора снаружи есть недостаток: его отключить нельзя. Точнее, можно… только это половину выходного каскада по сути надо самому допаивать и 1 GPIO потратить. Так что те кто сделал логичные функции подтяжки и так и сяк — получает честно заработанные 5 очков форы в ряде ситуаций.
0
Я как-то раздумывал над одним извращенским способом мультиплексирования кнопок без возможности фантомных нажатий. Не то чтоб отключаемая подтяжка вниз была необходима, но позволяла упростить схему и повысить плотность мультиплексирования.
0
А можно подробней о данном варианте?
0
Я его уже забыл, честно говоря)
0
А зачем АЦП? Если несколько уменьшить базовый резистор, то он вполне справится с утягиванием напряжения ниже порога переключения обычного цифрового входа (1.4В вроде где-то на грани).
Стоит правда заметить, что подтяжка несколько приоткрывает транзистор и нагрузка может сработать.
0
  • avatar
  • Vga
  • 01 августа 2012, 08:40
а при достаточно большой нагрузке транзистор еще и греться будет…
0
Ну просто вся эта конструкция тестировалась на пинборде, поэтому резистор решил не трогать. Да и каналов АЦП у меня там чуть меньше чем пинов, так-что почему-бы не применить? :)
0
почему до сих пор нет коммента «КАТ!!!111»?
0
  • avatar
  • xar
  • 01 августа 2012, 10:05
Вы меня опередили ;)
0
а вот и то, чего я ждал))))
0
Это росто я не зашел ещё.
0
Готово, щеф :)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.