Цифровой ввод данных

Visits: 4170


Цифровой ввод данных – Чтение состояния кнопок.

Для реализации этого проекта нам потребуется две тактовые кнопки. Надо будет к их выводам припаять проводки с контактами.

Порты контроллера (в последних моделях) Представляют собой комбинацию из четырех основных регистров. Это регистры управления направлением передачи цифровых (данных с логическими уровнями) данных TRIS. Регистры ввода цифровых данных PORT. Регистры вывода цифровых данных LAT. И регистры отвечающие за тип данных, т.е.аналоговые или цифровые ANSEL.

Для нашего примера мы будем использовать порт B. Для контроля мы применим светодиод подключенный к выводу RB1. Для ввода информации мы будем использовать выводы порта RB7 и RB6. К этим портам мы подключим тактовые кнопки.

ILLISSI-botton-01Схема приведена применительно к плате ILLISSI-4B-primum. Теперь когда мы собрали схему начинается самое интересное.

Первое это надо правильно сконфигурировать порты контроллера. В нашего контроллера PIC16F1936  три порта A, B, C. Первые два могут работать и аналоговыми сигналами. Третий только цифровой.

ILLISSI-botton-02-300x232


Возможный вариант настройки портов и тактового генератора:

// настройка внутренего генератора 8*4=32мГц 
 OSCCON=0b11110000;
       // ||||||||
       // ||||| ++-- SCS<1:0> основной гене-р (раб. через PLL) 
       // |++++----- IRCF<3:0> частота 8 мГц 
       // +--------- SPLLEN умножитель 1-включен
       // конфигурирование портов микроконтроллера
 TRISA = 0; // настроить на вывод данных
 PORTA = 0; // установит низний уровень
 ANSELA = 0; // настроить как цифровой 
 TRISB = 0b11000000; //два на ввод данных, остальные на вывод
        // ||    +--- порт на вывод данных - RB1 инд. - светодиод
        // |+ --------- порт на ввод данных - RB6
        // +---------- порт на ввод данных - RB7
 PORTB = 0; // установит низний уровень
 ANSELB = 0; // настроить как цифровой
 PORTC = 0; // настроить на вывод данных
 TRISC = 0; // установит низкий уровень

 nWPUEN = 0; // включить резисторы
 WPUB = 0b11000000; // выключить подтягивающие резисторы на выводах 5-0 (по сбросу включены)

Теперь необходимо к портам на которых установлены тактовые кнопки создать высокий проверь. Для этого мы будем использовать подтягивающие резисторы WEAK PULL-UPS которые встроены в порт B. Для этого необходимо выполнить следующее:

 nWPUEN = 0; // включить резисторы
 WPUB = 0b11000000; // выключить подтягивающие резисторы на выводах 5-0 (по сбросу включены)

На этом настройки контроллера окончены, теперь приступаем к самой программе.

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

Для проверки работы кнопки будем использовать включение светодиода.

while (1)
 {
      CLRWDT(); // сброс сторожевого таймера
      if (RB6==0)LATB1=1;
      else LATB1=0;
 }

В этом примере мы проверяем состояние на входе порта рано “0” (низкому уровню, если да включаем светодиод, иначе выключаем.


Хоть наши достижения и радуют, но усложним программу. Сделаем так чтобы при одном нажатии на нашу кнопку светодиод загорался, а при втором погасал. В принципе ничего сложного, только один маленький нюанс. При замы замыкании или размыкании механического контакта, происходить так называемый “дребезг”.

ILLISSI-botton-03-300x153В нашей схеме уровни сигнала будут иметь следующий вид. Это происходит в следствии свойства механического контакта, при соединении контактов сопротивление изменяется пропорционально силе сжатия и на протяжении 10-20 миллисекунд, пока кнопка нажимается возникает такой переходной процесс. Когда уровень сигнала пересекает логический уровень переключения входа порта контроллера, контроллер из-за своей высокой скорости опроса порта может “решить”, что кнопка нажималась не один раз а 20 :). Поэтому для входов которые выполняют подсчет импульсов приходящих с механических контактов необходимо решить проблему “отсеивания” дребезга контакта. Как это решить. Логически это решается просто. При опросе входа порта, если программа обнаружила низкий логический уровень необходимо подождать 10 миллисекунд и снова проверить уровень на входе порта. Если уровень низкий, делаем вывод кнопка нажата, если уровень высокий,  значит была “какая то помеха”.

Для реализации такого варианта программы нам понадобиться еще один контрольный флаг. Назовем его NAG. Для чего он нужен. Он необходим чтобы программа могла понять при тестировании порта кнопка “только что нажата” или “уже давно начата”. Без этого флага у нас не получиться счетного входа.

    
while (1)// основной цикл программ
{
    CLRWDT();	// сброс сторожевого таймера
    if (RB6==0)	// тестируем состояние порта
    {
       __delay_ms(10); // ожидаем 10 мс, пропускаем дребезг
       if (RB6==0&&NAG==0) // снова тестируем состояние порта и флаг "кнопка была нажата"
        {  // если уровень низкий и клавиша, до этого не была нажата" выполняем код в скобках
	   NAG=1; // устанавливаем флаг кнопка нажата
	   LATB1=!LATB1; // переключаем свечение светодиода
	}
     }	
     else
     {
	NAG=0; // сбросить флаг "кнопка нажата" - исходя из логики
     }	
} // конец основного цикла

 


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

Как видите из этих промеров – микроконтроллеры это просто.

 В заключении усложним программу. Подключит к плате вторую кнопку. И используя интерфейс связи с ПК (программу Serial Bootloader AN1310). Организуем реверсивной счетчик. Информация будет выводиться прямо в оно программы.

 Саму программу описывать не буду, Пора включить мозги и разобрать самостоятельно. Для пояснения добавлю, что мы будем использовать стандартную библиотеку Си stdio.h. из её нас интересует функция printf. Для работы последовательным интерфейсом необходимо будет включить в нашей прорамме модуль UART и настроисть скорость для приложений в программе AN1310 – 115200 бод.

Все сообщения на ПК выводим на английском, к сожалению русскими символами наш терминал программы AN1310 не владеет только ANSI.

/************************************************************************
* Copyright (c) 2012,  Project - ILLISSI.
*
* Демонстрационная программа "опрос тактовых кнопок" + связи с последовательным портом
* системная плата ILLISSI-B4-primum
* для контроллеров PIC16(L)F1936
* функции
* при нажатии на клавиатуре ПК клавиши "1" - можно включать выключать светодиод на демо плате
* при нажатии на кнопки на демо плате можно включать ылючать светодиод, при этом увеличивается
* или уменьшается состояние переменной counter, значение которой выводиться на ПК.
* Author        Date        Comment
*************************************************************************
* Гена Чернов	27/07/12    V1.0
*                         
************************************************************************/

#include 
#include 

// конфигурирование контроллера

__CONFIG(
 FOSC_INTOSC 	& 		// INTOSC oscillator: I/O function on CLKIN pin
 WDTE_ON	&		// WDT disabled
 PWRTE_ON	&		// PWRT enabled
 MCLRE_ON	&		// MCLR/VPP pin function is digital input
 CP_ON		&		// Program memory code protection is enabled
 CPD_ON		&		// Data memory code protection is enabled
 BOREN_ON	&		// Brown-out Reset enabled
 CLKOUTEN_OFF	&		// CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
 IESO_OFF	&		// Internal/External Switchover mode is disabled
 FCMEN_OFF);			// Fail-Safe Clock Monitor is disabled

__CONFIG(
 WRT_ALL 	& 		// 000h to 7FFh write protected, no addresses may be modified by EECON control
 PLLEN_ON 	&		// 4x PLL enabled
 STVREN_OFF 	& 		// Stack Overflow or Underflow will not cause a Reset 
 BORV_HI 	&		// Brown-out Reset Voltage (VBOR) set to 2.7V
 LVP_OFF);			// High-voltage on MCLR/VPP must be used for programming

#define _XTAL_FREQ 32000000 
#define BAUDRG 68           // 115.2Kbps from 32MHz (BRG16 = 1)
__EEPROM_DATA(0, 1, 2, 3, 4, 5, 6, 7);

unsigned char data;

void interrupt isr(void);
void putch(unsigned char byte);

bit NAG;
int counter;

//--------------------------------
void main(void)
{
	CLRWDT();	// сброс сторожевого таймера

// настройка генератора 8*4=32мГц 
   OSCCON=0b11110000;
//          ||||||||
//          ||||| ++-- SCS	основной генератор (работа через PLL) 
//          |++++----- IRCF	частота 8 мГц 
//          +--------- SPLLEN	    умножитель 1-включен
// конфигурирование портов

    TRISA = 0;
    PORTA = 0;
    ANSELA = 0;

    TRISB = 0b11000000; // это типа гибридной настройки, два на ввод данных, остальные на вывод
    //        ||    +--- порт на вывод данных - RB1 индикация - светодиод
    //        |+--------- порт на ввод данных - RB6
    //        +---------- порт на ввод данных - RB7
    PORTB = 0;
    ANSELB = 0;
    PORTC = 0;
    TRISC = 0b11000000;	// для работы EUSART

    SPBRGH = 0;
    SPBRG   = BAUDRG;

    BAUDCON = 0; 		// регистр управления скорости передачи
    BRG16 = 1;			// установить бит BRG16: используется 16-битный генератор Baud Rate

    TXSTA   = 0b00100100;
    	//      |||||||+--TX9D:
    	//      ||||||+---TRMT:Transmit Shift Register Status bit
    	//      |||||+----BRGH:1 = High speed
    	//      ||||+-----SENDB:Send Break Character bit
    	//      |||+------SYNC:0 = Asynchronous mode
    	//      ||+-------TXEN:1 = Transmit enabled
    	//      |+--------TX9:0 = Selects 8-bit transmission
    	//      +---------CSRC: в асинхронном режиме не имеет значения (Все равно)
    RCSTA   = 0b10010000;
    	//      |||||||+--RX9D:
    	//      ||||||+---OERR: Overrun Error bit
    	//      |||||+----FERR: Framing Error bit
    	//      ||||+-----ADDEN: Address Detect Enable bit
    	//      |||+------CREN:1 = Enables receiver
    	//      ||+-------SREN: Single Receive Enable bit (Все равно)
    	//      |+--------RX9: 9-bit Receive Enable bit
    	//      +---------SPEN: Serial Port Enable bit Serial port enabled
    // configure timer 0 for maximum prescaler and enable interrupt
    TMR0 = 0;
    T0IE = 1;
    OPTION_REG = 0b11010111;
    nWPUEN = 0;	// включить резисторы
    WPUB = 0b11000000; // выключить подтягивающие резисторы на выводах 5-0 (по сбросу включены)    
    __delay_ms (100); // запрос задержки в миллисекундах

    ei();	// включить прерывания

    printf("\n\n   Version = 1.01 \r\n\n");
    printf(" Poll clock buttons!! \nPIC16(L)F1936 Demosoft\r\n");
    printf(" web site illissi.com\r\n");
    printf("       click!\r\n");
//--------------------------------------------------------------------------
    while (1)
    {
	CLRWDT();	// сброс сторожевого таймера
        if(RCIF)
        {
          //  RCIF=0;
            if(FERR && (RC7 == 0))
            {
                // RXD состояние BREAK обнаружено, переключиться обратно в режим загрузчика.
                di();                   // отключить прерыания
                #asm
                    clrf    _PCLATH     // сбросить страший регистр счетчика алресса
                    goto    0           // (должно быть выполненно только из основного цикла, чтобы избежать переполнения стека вызовов)
                #endasm
            }

            data = RCREG;
           // putch(data);
            switch(data)
            {
                case '1':
                    putch(data);
                    LATB1=!LATB1;
                    break;
                default:
                        printf("\r\n");
                        putch(data);
                        printf(" - it is not a command, type the commands LEDs 1,2,3,4\r\n");
                    break;
            }

        }
		if (RB6==0)	// тестируем состояние порта
		{
			__delay_ms(10); // ожидаем 10 мс, пропускаем дребезг
			if (RB6==0&&NAG==0) // снова тестируем состояние порта и флага "кнопка была нажата"
			{  // если уровень низкий и клавиша, до этого не была нажата" выполняем код в скобках
				NAG=1; // устанавливаем флаг кнопка нажата
				LATB1=!LATB1; // переключаем свечение светодиода
				counter++;
                printf("counter++: %d\r\n", counter);
			}
		}	
		else if (RB7==0)	// тестируем состояние порта
		{
			__delay_ms(10); // ожидаем 10 мс, пропускаем дребезг
			if (RB7==0&&NAG==0) // снова тестируем состояние порта и флага "кнопка была нажата"
			{  // если уровень низкий и клавиша, до этого не была нажата" выполняем код в скобках
				NAG=1; // устанавливаем флаг кнопка нажата
				LATB1=!LATB1; // переключаем свечение светодиода
				counter--;
                printf("counter--: %d\r\n", counter);
			}
		}
		else
		{
			NAG=0; // сбросить флаг "кнопка нажата" - исходя из логики
		}

    }    
}//

// прерывания
void interrupt isr(void)
{
    static signed char timerd = 0;
    T0IF = 0;
    if(timerd++ > 20) // период мигания светодиода 
    {
        timerd = 0;
        LATB0=!LATB0; // индикация работы таймера
    }
}//

// передача байта
void putch(unsigned char byte)
{
    while(TXIF == 0);       // ожидание готовности передачи
    TXREG = byte;
}//

 


Загрузить первый пример

Значок

Цифровой ввод данных - Чтение состояния кнопок 00 1.35 KB 838 downloads

Цифровой ввод данных - Чтение состояния кнопок...
Загрузить второй пример
Значок

Цифровой ввод данных - Чтение состояния кнопок 01 1.62 KB 760 downloads

Цифровой ввод данных - Чтение состояния кнопок...
Загрузить третий пример
Значок

Цифровой ввод данных - Чтение состояния кнопок 02 2.97 KB 752 downloads

Цифровой ввод данных - Чтение состояния кнопок...
Загрузить проект (все три файла) 
Значок

Цифровой ввод данных - Чтение состояния кнопок 03 9.43 KB 883 downloads

Цифровой ввод данных - Чтение состояния кнопок...


 



Это может быть интересно


  • Development Boards PIC18F47Q84Development Boards PIC18F47Q84
    Visits: 871 Microchip тішить новими мікроконтролерами. Особливістю цього MCU – це багата інтелектуальна периферія, що дозволяє вирішувати такі завдання на 8 бітних MCU, які неможливо реалізувати на деяких навіть 32 …
  • Стабилизатор тока для светодиодов SN3350Стабилизатор тока для светодиодов SN3350
    Visits: 2581 SN3350 ближайший аналог ZXLD1350 Как собрать готовый вариант, читайте во второй части – http://catcatcat.d-lan.dp.ua/stabilizator-toka-na-sn3350-chast-2/ 40V  драйвер светодиодов с внутренним ключом  SN3350 – импульсный понижающий преобразователь, разработанный для того, чтобы эффективно управлять одним или …
  • CLUBBEST – reasoning on the visualization of music.CLUBBEST – reasoning on the visualization of music.
    Visits: 101 ВІД ЗАХОДУ ДО СВІТАНКУ АБО ПОБАЧИТИ МУЗИКУ.     Час доби, коли почуття людини загострюються, – це час від заходу до світанку. В цей час людина відкрита для …
  • PIC18F25K42 – v. A001 – выявленные баги.PIC18F25K42 – v. A001 – выявленные баги.
    Visits: 589 Модуль I2C Не работает при использовании в стандартной конфигурации MCC. Требует особой нестандартной конфигурации и управления для нормальной работы. Обойти Обход проблемы возможен библиотека см статью. Модуль ADC2 На …
  • Ссылки на интересные источникиСсылки на интересные источники
    Visits: 814 Сбор 3D моделей от André L’Hérault конденсаторы, резисторы, индуктивности dropbox IPC-SM-782 Surface Mount Design and Land Pattern Standard Видео уроки по Altium designer Alexey Sabunin https://www.youtube.com/channel/UCG7N5CqXpyK8nQjr1EmMgng Сергей Булавинов https://www.youtube.com/channel/UCISAMXRnN_Qw9UTjUwZI1Jw Robert Feranec https://www.youtube.com/user/matarofe …
  • My libraries for Altium DesignerMy libraries for Altium Designer
    Visits: 3809 Attention, this version of the database is outdated today. See updates in articles https://catcatcat.d-lan.dp.ua/altium-designer-my-setup-system-and-project-structure  and https://catcatcat.d-lan.dp.ua/altium-designer-my-setup-system-and-project-structure-v23-2/    My libraries for Altium designer  (Updated V – 29/05/2022) (c) 2021 …
  • Регулятор влажности ch-3800Регулятор влажности ch-3800
    Visits: 1400   И еще один проект на плате ch-c3xxx –  универсальный регулятор влажности ch-3800. Регулятор позволяет работать как в режиме индикатора влажности, так и в режиме регулятора. Рабочий диапазон …
  • APA102 – светодиоды со встроенным драйвером и SPI интерфейсомAPA102 – светодиоды со встроенным драйвером и SPI интерфейсом
    Visits: 3251 APA102 В 2014 году фирма Shenzhen Led Color Optoelectronic Co., Ltd http://www.szledcolor.com/ начала производство светодиодов на драйвере APA102. Это серия так называемых светодиодов со встроенным драйвером. Основной особенностью этих …
  • MAX7219/21 и 8х8 LED дисплеиMAX7219/21 и 8х8 LED дисплеи
    Visits: 914 MAX7219, MAX7221 предназначены для вывода информации на 8 разрядов семисегментного индикатора, но на нем легко организовать вывод на светодиодные индикаторы 8х8. продолжение следует…. Это может быть интересно
  • Простой цифровой регулятор мощностиПростой цифровой регулятор мощности
    Visits: 6406 Простой регулятор мощности с цифровой индикацией. Этот проект создан как обучающий, для ознакомления с основами построения сетевых регуляторов мощности. Устройства подобного типа можно использовать для управления освещением, скоростью …



Поделись этим!