Сенсорные кнопки

02/02/2011 - 20:32 Pashgan, Petrov
     Управление с помощью компьютера  исполнительным механизмом или иным устройством не всегда удобно. Первые два дня это, конечно, интересно, но потом начинает напрягать, потому что приходится совершать много лишних действий – включать компьютер, запускать программу и т.д. Возникает вопрос, а  не изготовить ли для этих целей автономный управляющий модуль с клавиатурой и дисплеем?
   Так как делается это для себя, то требуется дешевое, но в то же время красивое решение. С выбором дисплея особо не помудришь, дешевле и удобнее символьных LCD с контроллером еще не придумали, а вот при выборе клавиатуры можно хорошенько сэкономить.
 Рассмотрим варианты. За готовую матричную клавиатуру придется выложить 100-200 рублей. Клавиатура из кнопок обойдется рублей в 36 (3р * 12 кнопок), не считая колпачков.   Сенсорную клавиатуру можно изготовить почти задаром из куска фольгированного текстолита, при этом в корпусе устройства не придется сверлить отверстия под кнопки. 
   По-моему выбор очевиден, осталось только понять, как с такой клавиатурой  работать. Но для начала нужно хотя бы разобраться с одиночной сенсорной кнопкой. 
   
  Одиночная сенсорная кнопка представляет собой металлическую площадку,  подключенную к выводу  микроконтроллера. Поскольку любое проводящее тело обладает емкостью, величина которой зависит от геометрии тела и окружающего его диэлектрика, такое подключение равносильно подключению к выводу конденсатора.    
   Человеческое тело тоже обладает емкостью (~100..300 pF), поэтому при поднесении пальца к сенсору суммарная емкость на входе микроконтроллера увеличится (ведь при параллельном соединении конденсаторов их емкости складываются). По именениям этой емкости и можно делать вывод о прикосновении к сенсору. 

Сенсорная кнопка, подключенная к микроконтроллеру

С1 — паразитная емкость вывода мк, С2 — емкость сенсора, С3 и С4 – емкости, вносимые прикосновением.  
  
   Поскольку все КМОП микросхемы болезненно переносят воздействие статического электричества, а человеческое тело ,обладая вышеуказанной емкостью, может заряжаться до нескольких тысяч вольт, схему следует дополнить небольшой защитной цепью. 
    Защита микроконтроллера от статического электричества
  
  При прикосновении к сенсору, накопленный телом заряд благополучно разрядится через один из диодов. В принципе такая защитная схема (не считая резистора) спрятана внутри микроконтроллера, но полагаться на нее не стоит, так как встроенные диоды выдерживают ток лишь в 1 ма.
   Кстати, внешние диоды добавят к входной емкости еще пару тройку пикофарад.

  Ну ладно, принцип понятен, а каким образом измерить емкость? Величину емкости можно оценить по времени ее заряда. Подключим к выводу микроконтроллера высокоомный подтягивающий резистор (смотри схему) и получим RC цепь. Манипулируя выводом микроконтроллера можно вызвать заряд и разряд нашего виртуального конденсатора, а контролирую потенциал вывода в процессе заряда емкости - оценивать ее величину. Чем больше емкость, тем медленнее она будет заряжаться.   

Вырисовывется следующий алгоритм работы:
 
1. Переключаем вывод микроконтроллера в режим выхода и сбрасываем в ноль. Паразитная емкость разрядится на внутренние цепи микроконтроллера.

2. Переключаем вывод микроконтроллера в режим входа в состоянии Hi-Z. Емкость начнет заряжаться через внешний подтягивающий резистор.

3. Контролируем состояние вывода и отсчитываем время. Как только емкость зарядится до напряжения логической единицы, снимаем показания счетчика.

4. Сравниваем полученное значение счетчика с заданной эталонной величиной и определяем, увеличилась ли емкость или нет. 
 
  Ничего сложного и можно перейти к делу.  Представляю сделанную на скорую руку, но, тем не менее, рабочую схему и исходники устройства.

Микроконтроллер и две сенсорные кнопки
 
Исходник не большой и, я думаю, main.c можно выложить полностью, он у меня хорошо прокомментирован.

//***************************************************************************
//
//  Author(s)...: Pashgan    http://ChipEnable.Ru, Petrov http://svyaz.blogspot.com/
//
//  Target(s)...: ATtiny2313
//
//  Compiler....: IAR EWA 5.11
//
//  Description.: ATtiny sensor
//
//  Data........: 19.01.11
//
//***************************************************************************
#include <ioavr.h>
#include <intrinsics.h>
#include "usart.h"
 
//макросы для работы с битами
#define InvBit(reg, bit)  reg ^= (1<<(bit))
#define ClearBit(reg, bit)       reg &= (~(1<<(bit)))
#define SetBit(reg, bit)          reg |= (1<<(bit))
#define BitIsSet(reg, bit)       ((reg & (1<<bit)) != 0)
 
//сколько циклов опроса кнопка должна удерживаться
#define THRESHOLD 20
// величина которую, возможно придется подстраивать
#define TOUCH_COUNT 1 
//переменные для подсчета количества переполнений Т0
volatile unsigned char sub_time_pin0 = 0;
volatile unsigned char sub_time_pin1 = 0;
//переменная для защиты от дребезга
unsigned char comp = 0;
 
int main( void )
  USART_Init();
 
  // Инициализация таймера T0 для Tiny2313
  TIMSK = (1<<OCIE0A);    //разрешаем прерывание таймера T0 при событии совпадение
  TCCR0A = (1<<WGM01)|(0<<WGM00);
  TCCR0B = (0<<CS02)|(1<<CS01)|(0<<CS00);  //режим СТС, прескалер - 8
  TCNT0 = 0;              //обнуляем счетный регистр
  OCR0A = 0x32;            //прерывания каждые ~ 50мкс
 
  // Инициализация таймера T1 для Tiny2313
  TIMSK |= (1<<OCIE1A);                 //разрешаем прерывание таймера т1 при событии совпадение
  TCCR1A = (0<<WGM11)|(0<<WGM10);
  TCCR1B = (0<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);  //режим работы СТС, прескалер - 8
  TCNT1 = 0; //обнуляем счетный регистр
  OCR1A = 0x2710; //прерывания  каждые 10мс
 
  //разрешаем прерывания  
  __enable_interrupt();
  USART_SendStr("Button: "); 
  DDRD |=(1<<PD2)|(1<<PD3)|(1<<PD4); //устанавливаем  PD2, PD3 и PD4 на выход
  PORTD = 0;
 
//++++++++++++++++++++++++++++++++++++++++++++++++++
  while(1){
  /*если на выводе PB0 единица и таймер переполнился 
  несколько раз -> увеличить антидребезговую переменную
  затем, если значение переменной comp превысило порог ->
  инвертировать пин PD2, послать по УАРТУ номер кнопки,
  обнулить антидребезговую переменную  */
  if (BitIsSet(PINB, PB0)) { 
     if (sub_time_pin0 > TOUCH_COUNT) { 
        comp++;   
        if (comp >= THRESHOLD){ 
           InvBit(PORTD,PD2); 
           USART_SendStr("1 "); 
           comp = 0;
        }
     }
     sub_time_pin0 = 0;
   }
  /* то же самое */
  if (BitIsSet(PINB, PB1)) {
     if (sub_time_pin1 > TOUCH_COUNT) {
       comp++;
       if (comp >= THRESHOLD){
          InvBit(PORTD, PD3);
          USART_SendStr("2 "); 
          comp=0;
       }
     }
     sub_time_pin1 = 0;
  }
//++++++++++++++++++++++++++++++++++++++++++++++++++    
  }
  return 0;
}
 
// Прерывание Таймера 0 используемого для сканирования пина
#pragma vector = TIMER0_COMPA_vect
__interrupt void Timer0Comp(void)
{
// Увеличиваем на 1 счетчики переполнений таймера  
  sub_time_pin0++;
  sub_time_pin1++;
  
//это для мониторинга в Протеусе
  InvBit(PORTD,PD4);
}
 
// Прерывание Т1
//Инициализация порта, к которому подключены сенсорные кнопки согласно алгоритму
#pragma vector = TIMER1_COMPA_vect
__interrupt void Timer1CompA(void)
{
  //переключаем порт в режим выхода и устанавливаем 0
  //разряжая паразитную емкость на внутренние цепи AVR
  DDRB = 0xFF;
  PORTB = 0x00;
  
  //переключаем порт в режим входа в состоянии Hi-Z
  DDRB = 0x00;
 
  //обнуляем количество срабатываний для нулевого и первого выводов PORTB
  sub_time_pin0 = 0; 
  sub_time_pin1 = 0; 
  
  TCNT0 = 0; // Обнуляем счетный регистр T0

Комментарии   

# TERMIN 02.02.2011 22:41
Отличный проектик, как макетная плата придет, сразу попробую на ней
Ответить | Ответить с цитатой | Цитировать
# Petrov 03.02.2011 03:03
Страрамся :-) Скоро будет про ИК управление и, в перспективе, обмен данными между МК по инфракрасному каналу.
Ответить | Ответить с цитатой | Цитировать
# ANN 03.02.2011 03:31
Интересно всё изложено....хот елось бы увидеть фото данной модели. Наверняка будет красивенько :)
Ответить | Ответить с цитатой | Цитировать
# Pashgan 03.02.2011 11:49
Petrov!! Где фотографии?
Ответить | Ответить с цитатой | Цитировать
# CrazySynergetic 03.02.2011 10:02
Не хилая такая кнопочка, которая таймер у тебя отжирает... Зато модно...
Ответить | Ответить с цитатой | Цитировать
# Pashgan 03.02.2011 12:07
Да ладно, при грамотном программировани и эти таймеры можно задействовать и для остальных нужд.
Ответить | Ответить с цитатой | Цитировать
# CatMurr 03.02.2011 11:45
На Хабре недавно была подобная статья, немного схемотехника другая, а принцип тот же. Хорошо б такую клавиатуру делать на кмоп логике, чтоб ресурсы не отжирала!
Ответить | Ответить с цитатой | Цитировать
# Petrov 03.02.2011 13:29
:-) Та какие там фотографии, не делал еще само устройство. Вообще задумывалось как выключатель света в ванной и туалете. Малышка не дотягивается, а жена запретила стену сверлить и выключатель ниже ставить. Был вариант висюльку повесить, ну знаете дернешь включилось, еще раз выключилось, также было зарезано на корню. Вот и пришла идея наклеить прозрачным скотчем тонкие проводники, опустив до нужного уровня(где детка достанет) Идея реализована на макетке, а до "внедрения на производстве" пока руки не дошли :lol: Обещаю как сделаю - выложу.
Ответить | Ответить с цитатой | Цитировать
# Leo 20.11.2012 10:40
Может лучше датчик движения поставить? Я тут для туалета делаю схему. Два датчика движения, управление яркостью и задержкой освещения, управление вытяжкой.
Ответить | Ответить с цитатой | Цитировать
# Витек. 03.02.2011 14:49
Обалдеть. Вы про статику не слыхали что ли? Может оказаться что вход проживет до первого нажатия, потом ноге AVRки каюк. Про электрошокер молчу.
Ответить | Ответить с цитатой | Цитировать
# Pashgan 03.02.2011 15:28
1. Между сенсором и пальцем находится изолятор.
2. Входы защищены двумя диодами.
3. Можно добавить между выводом и подтягивающим резистором низкоомный резистор для ограничения входного тока.
4. И наконец кто мешает поставить стабилитроны или супрессоры (TVS-диоды).
Ответить | Ответить с цитатой | Цитировать
# Витек. 03.02.2011 15:59
Входы защищены диодами - супер! Без резисторов, но диоды стоят. И много они простоят при 500 вольтовых скачках "через изолятор"? :) Ну так что мешало нарисовать защиту-то, чтобы начинающие не набивали себе шишек?
Ответить | Ответить с цитатой | Цитировать
# Pashgan 03.02.2011 19:36
Цитата:
Ну так что мешало нарисовать защиту-то, чтобы начинающие не набивали себе шишек?
Ничего страшного, от шишек еще никто не умирал. Наоборот, они как правило идут на пользу.
Ответить | Ответить с цитатой | Цитировать
# Petrov 04.02.2011 02:51
Цитирую Витек.:
...Ну так что мешало нарисовать защиту-то, чтобы начинающие не набивали себе шишек?

Дык кто вам мешает, окажите услугу покажите как надо! Мы вам спасибо скажем. А критиковать то проще всего, не иначе. 8)
Предрекая все дальнейшие размышления и вопросы предлагаю ознакомится с AppNote от Atmel
(http://www.atmel.com/dyn/resources/prod_documents/doc10620.pdf)
Документ многим будет интересен, как в части защиты от статики, так и в части юзабилити.
Ответить | Ответить с цитатой | Цитировать
# GurovIlya 04.02.2011 05:05
Опасения правильные. Посмотрите по ссылке, там есть Описание эффективности типовых методик защиты от статического электричества при разработке сенсорных клавиатур (Effects of ESD Protection Devices on Capacitive Sensing Performance) an376. http://www.efo.ru/doc/Silabs/Silabs.pl?2050
Ответить | Ответить с цитатой | Цитировать
# CatMurr 04.02.2011 06:12
А при разработке платы для сенсора, когда площадки расположены на одном слое, что делать со вторым? Оставить металлизацию, оставить и присоединить к земле или удалить? Atmel, насколько я понял при беглом просмотре, рекомендует к земле...
Ответить | Ответить с цитатой | Цитировать
# Владимир 16.02.2011 08:30
Полагаю, теория изложена не верно,
наводки окружающих электрических полей,которые вокруг нас наведённые на тело человека 50 гц,передаёт при прикосновении к сенсору.а никакое не изменение ёмкости.
Представьте,что ваше устройство надо будет эксплуатировать в чистом поле, где нет ЛЭП и прочих коммуникаций и электрических полей,
Ваше устройство там работать не будет,
нечему там наводиться на тело человека.
Ответить | Ответить с цитатой | Цитировать
# Pashgan 16.02.2011 21:59
Теория подробно изложена на страницах интернета. Проект не мой. Повторю конструкцию и сообщу о результатах.
Ответить | Ответить с цитатой | Цитировать
# Владимир 23.02.2011 11:35
Цитата:
Повторю конструкцию и сообщу о результатах
Уважаемый Pashgan,
Ну чего нам ссылаться на чужие источники,мало ли кто какой бред пишет?..)))и проверки этих сомнительных теорий,
Хотя,любая теория проверяется практикой,
поэтому,
давайте рассуждать логически и здраво,
возьмите в руку щуп осциллографа,и Вы сразу увидите эти наводки на экране в виде синусоиды 50 гц,
коснитесь пальцем НЧ усилителя,и в колонках Вы услышите этот самый фон 50 Гц,
наводимый на ваше тело, Ваш палец и передаёт на вход УНЧ этот самый сигнал, точно так же,как и в случае с сенсорами,
если только речь не идёт об действительно измерении ёмкости вашего тела в пикофарадах и сравнением этой ёмкости после измерения её с заданной величиной,
но в этой статье,как я понял ,речь идёт вовсе не о таком варианте работы схемы.
Ответить | Ответить с цитатой | Цитировать
# Владимир 23.02.2011 11:43
Цитата:
поэтому при поднесении пальца к сенсору суммарная емкость на входе микроконтроллера увеличится (ведь при параллельном соединении конденсаторов их емкости складываются). По именениям этой емкости и можно делать вывод о прикосновении к сенсору.

Я собственно об этом куске текста в Вашей статье.
Ответить | Ответить с цитатой | Цитировать
# Petrov 23.02.2011 14:10
"Я вам удивляюсь" Владимир :lol: .
Еще раз цитирую вами же процитированный кусок Цитата:
поэтому при поднесении пальца к сенсору
. Нет прямого контакта! по ТЗ, его нет :D По нахватались вершков. В коментах даже на апноуты от атмела ссылки есть, потрудитесь почитать. Цитата:
если только речь не идёт об действительно измерении ёмкости вашего тела в пикофарадах и сравнением этой ёмкости после измерения её с заданной величиной, но в этой статье,как я понял ,речь идёт вовсе не о таком варианте работы схемы.
Именно об этом идет речь. :P
Ответить | Ответить с цитатой | Цитировать
# Владимир 24.02.2011 08:53
Petrov
Я оказался не прав,вынужден признать,
невнимательно читал,сейчас перечитал заново статью.
получается нечто похожее на QT102 от Атмел.
Ответить | Ответить с цитатой | Цитировать
# ankar 13.03.2011 21:15
На гетчипе getchip.net эта система полностью отработана. И работает без помех. Так, что прежде чем критиковать автора повторите схему. А потом лезте в дебри.
Ответить | Ответить с цитатой | Цитировать
# кулибин 04.05.2011 08:29
данная кнопка врятли может применяться в реальных схемах так как много ресурсов и без того слабого avr потребляет -я предлагаю Вам использовать мой вариант сенсорной кнопки которая надежно работает=радо вход порта контроллера поставить на ноль (без подтяжки)и в обратном направлении подключить диод на плюс а кнопка будет состоять из этого входа и минусовой площадки рядом и при прикосновении этих двух контактов вход вполне надежно работает как сенсор сопротивление пальца вполне достаточно для работы входа
Ответить | Ответить с цитатой | Цитировать
# Alca 28.06.2011 08:58
Подскажите, а что можно сделать чтоб поднять чувствительност ь?
Ответить | Ответить с цитатой | Цитировать
# AVRson 17.11.2011 13:37
Спасибо большое автору за материалы на сайте! Много полезного нашел тут. Сижу перечитываю все статьи, хочу объединить многие вещи в один проект :).
Ответить | Ответить с цитатой | Цитировать
# Иван 25.12.2011 20:03
Сделал печатную плату, проверял несколько раз:

http://s002.radikal.ru/i197/1112/82/60e7235f654c.jpg

Впаял все компоненты, прошил, но не работатет.
При подаче питани постоянно горит красная один из светодиодов, второй не горит вообще. нет никакой реакции на прикосновение к сенсору.

Помогите разобраться.
Ответить | Ответить с цитатой | Цитировать
# ROM 02.01.2012 10:31
По схеме в протеусе...
Я пока не разобрался для чего у МК на ноге PD4 прямоугольные импульсы подаються на вход осцилографа, но если ее отключить - то реакция на нажатия кнопки довольно быстрая. Т.е. с осцилографом нужно подождать больше времни на то чтобы сработало нажатие.
Ответить | Ответить с цитатой | Цитировать
# ROM 02.01.2012 21:35
Может кто-то конвертировать исходик с Тини2312 на Атмегу8? Очень нужно, весь десь сам проседел - так и не получилось разобраться (не все понятно с таймерами). Помогите пожалуйста начинающему!!!
Ответить | Ответить с цитатой | Цитировать
# vikfreeman 29.01.2012 15:40
Добрый вечер! Я планирую использовать данную схема для своего проекта. Скажите мне пожалуйста, он через диэлектрик будет работать??? На сенсор (металл) хочу нанести один слой маслянной краски.
Ответить | Ответить с цитатой | Цитировать
# Сергей123 26.02.2012 11:56
Будет
Ответить | Ответить с цитатой | Цитировать
# DmitryyDAS 29.09.2012 23:26
Отличная статья - большое спасибо!!!))
Ответить | Ответить с цитатой | Цитировать
# oxidizer 08.02.2013 11:51
Полезная статья. Большое спасибо.
Но вроде напутано в коде с PD2 PD3 PD4.
Ответить | Ответить с цитатой | Цитировать
# mash 14.02.2015 16:09
Портировал проект на STM8L101. Кнопки работают отлично! Спасибо большое!!!
Попытался добавить звук, но включение еще одного таймера вызвало периодическое мигание светодиодов. Пока не разобрался где влияние. Прошу помочь, кто знает.
Код:
#include "stm8l10x_tim2.h"
#include "stm8l10x_tim3.h"
#include "stm8l10x_tim4.h"
#define Threshold 20
#define TouchCount 6 // подбор нужен
volatile unsigned char stpin0 = 0;
volatile unsigned char stpin1 = 0;
unsigned char comp = 0;

int main( void )
{
GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Fast);
GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Fast);
GPIO_Init(GPIOD,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Fast);
CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv1);

// TIM2 прерывания каждые 50 мкс
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2,ENABLE);
TIM2_TimeBaseInit(TIM2_Prescaler_1,TIM2_CounterMode_Up,200);
TIM2_ITConfig(TIM2_IT_Update,ENABLE); TIM2_Cmd(ENABLE);

// TIM3 прерывания каждые 10 мс
CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE);
TIM3_TimeBaseInit(TIM3_Prescaler_2, TIM3_CounterMode_Up, 40000);
TIM3_ITConfig(TIM3_IT_Update,ENABLE); TIM3_Cmd(ENABLE);

// TIM4 Звук
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4,ENABLE);
TIM4_TimeBaseInit(TIM4_Prescaler_256, 200);
TIM4_ITConfig(TIM4_IT_Update,ENABLE);
TIM4_Cmd(ENABLE);

__enable_interrupt();

Ответить | Ответить с цитатой | Цитировать
# mash 14.02.2015 16:32
Код:
while(1)
{
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)){if(stpin0>TouchCount){comp++;if(comp>=Threshold){GPIO_ToggleBits(GPIOC,GPIO_Pin_0);comp=0;}}stpin0=0;}
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)){if(stpin1>TouchCount){comp++;if(comp>=Threshold){GPIO_ToggleBits(GPIOC,GPIO_Pin_1);comp=0;}}stpin1=0;}
}
return 0;
}

INTERRUPT_HANDLER(TIM2_OVF, 19)
{
if (TIM2_GetFlagStatus(TIM2_FLAG_Update))
{
stpin0++; stpin1++;
TIM2_ClearFlag(TIM2_FLAG_Update);
}
}

INTERRUPT_HANDLER(TIM3_OVF, 21)
{
if (TIM3_GetFlagStatus(TIM3_FLAG_Update))
{
GPIO_Init(GPIOB, GPIO_Pin_0, GPIO_Mode_Out_OD_Low_Fast);
GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_Out_OD_Low_Fast);
GPIO_Init(GPIOB, GPIO_Pin_0, GPIO_Mode_In_FL_No_IT);
GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_In_FL_No_IT);
stpin0 = 0; stpin1 = 0;
// ? Обнуляем счетный регистр
TIM3_ClearFlag(TIM3_FLAG_Update);
}
}

INTERRUPT_HANDLER(TIM4_OVF, 25)
{
if (TIM4_GetFlagStatus(TIM4_FLAG_Update))
{
GPIO_ToggleBits(GPIOD,GPIO_Pin_0); // Вывод звука
TIM4_ClearFlag(TIM4_FLAG_Update);
}
}
Ответить | Ответить с цитатой | Цитировать
# mash 16.02.2015 05:51
Кнопки работают отлично, пока не разрешишь еще один таймер. Если частота его низкая (раз в секунду), то кнопки работают (но это же не звук!). Если частота звуковая, то либо диоды моргают, либо кнопки не реагируют (если TouchCount увеличить до 8, чтоб диоды не моргали). В общем почему то доп.таймер вызывает как бы сработку кнопок. Может быть быстродействия не хватает? Тактовая 16 МГц.
Ответить | Ответить с цитатой | Цитировать
# mash 18.02.2015 09:45
Вот, первая версия кнопок со звуком (многотон. звонок или пианино).
Код:
#define TouchCount 6
int time=6500;

void Sound(int Freq);
char ovf0,ovf1,ovf2,ovf3,ovf4,ovf5,ovf6,ovf7;

int main( void )
{
GPIO_Init(GPIOA,GPIO_Pin_2,GPIO_Mode_Out_OD_HiZ_Slow);

CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv1);

// TIM4 прер. 40 мкс
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4,ENABLE);
TIM4_TimeBaseInit(TIM4_Prescaler_4, 155);
TIM4_ITConfig(TIM4_IT_Update,ENABLE); TIM4_Cmd(ENABLE);

// TIM2 прер. 2.5 мс
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
TIM2_TimeBaseInit(TIM2_Prescaler_1, TIM2_CounterMode_Up, 40000);
TIM2_ITConfig(TIM2_IT_Update,ENABLE); TIM2_Cmd(ENABLE);

//----- Инициализация TIM3 -- Звук
CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE);
TIM3_TimeBaseInit(TIM3_Prescaler_2, TIM3_CounterMode_Up, 20000);
TIM3_ITConfig(TIM3_IT_Update,ENABLE); TIM3_Cmd(DISABLE);

__enable_interrupt();

while(1)
{
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)) {if(ovf0 > TouchCount) Sound(4000); ovf0=0;}
. . .

// пока проверил на 11 кнопках

if (time==0)
{
TIM3_Cmd(DISABLE); time=6500;
GPIO_Init(GPIOA,GPIO_Pin_2,GPIO_Mode_Out_OD_HiZ_Slow);
} else time--;
}
return 0;
}

INTERRUPT_HANDLER(TIM4_UPD, 25)
{
ovf0++; ovf1++; ovf2++; ovf3++; ovf4++; ovf5++; ovf6++; ovf7++;
TIM4_ClearFlag(TIM4_FLAG_Update);
}

INTERRUPT_HANDLER(TIM2_UPD, 19)
{
GPIO_Init(GPIOB, GPIO_Pin_All, GPIO_Mode_Out_OD_Low_Fast);
GPIO_Init(GPIOB, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
TIM2_ClearFlag(TIM2_FLAG_Update);
}

INTERRUPT_HANDLER(TIM3_UPD, 21) // Звук
{
GPIO_ToggleBits(GPIOA,GPIO_Pin_2);
TIM3_ClearFlag(TIM3_FLAG_Update);
}

void Sound(int Freq)
{
TIM3_TimeBaseInit(TIM3_Prescaler_2, TIM3_CounterMode_Up, Freq); TIM3_Cmd(ENABLE);
}
Ответить | Ответить с цитатой | Цитировать

Добавить комментарий

Защитный код
Обновить