Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

btnНа первом уроке мы научились подавать напряжение ножкой микроконтроллера. Теперь нужно научиться управлять микроконтроллером без перепрошивки.

Зачем это нужно? Например, вы сделали часы на микроконтроллере, нужно выставить время, но очень не удобно каждый раз перепрошивать, когда собьется время. Намного удобнее пользоваться кнопками, например, одной менять часы, другой минуты.

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

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

После создания проекта приведем код к такому виду:

#include <mega8.h>
#include <delay.h>
 
void main(void)
{
 
PORTB=0x02;
DDRB=0x01;
 
while (1)
{
 
if(PINB.1==0)
{
PORTB.0=1;
delay_ms(100);
PORTB.0=0;
delay_ms(100);
}
 
};
}

Как мы видим, по сравнению с первым уроком изменилась настройка порта

PORTB=0x02;
DDRB=0x01;

Подробнее о том что значат данные строки можно почитать тут

Также появилась новая строчка

if(PINB.1==0)
{}

данную строчку нужно читать так — если на ножке 1 порта В подключили землю (0 потенциал), то выполнить код в фигурных скобках. В нашем примере это код из первого урока. Если кнопка не замкнута, то ничего не делать. Промоделировать можно в Proteuse.

Вместо кнопки можно поставить датчик, реле и т.п., вместо светодиода — пищалку, получится сигнализация.

Архив с прошивкой и файлом протеуса доступен тут

Update1: Зачем нужна подтяжка порта?
У входа мк большое сопротивление, если будут течь даже микротоки вызванные помехами, то по закону Ома U=R*I это может привести к тому, что на входе появится лог 1. Чтобы не было таких проблем в AVR микроконтроллерах можно подключить ножку к плюсу питания, через подтягивающий резистор. В этом случае даже, логика работы меняется наоборот — но если появится помеха, нам это не важно, ведь у нас на входе уже логическая единица.

Почему подключение через резистор? Допустим мы подключили вход к плюсу напрямую без резистора. Когда кнопка сработает, она притянет вход к земле, поэтому на входе будет короткое замыкание между + и землей. Если же стоит резистор, то при замыкании кнопки с одной стороны он так и останется подключен к +, а со второй стороны на нем появится земля от кнопки. Через резистор потечет ток, но его величина будет не такой большой.
btn_pup

Update2: Добавлен тест, в котором вы можете проверить на сколько хорошо вы усвоили материал урока

This movie requires Flash Player 9

220 комментариев: Урок 2. Управление кнопками в AVR

  • Привет всем!
    Возникли трудности в обработке переменной с плавающей точкой Float
    есть простая менюшка в которой надо увиличивать-уменшать переменною но по непонятным причинам условия не работают(не уменш_не увил) прошу помощи у знающих

    float VBmin;
    ////////////////////////////////////////////////////////////////////
    void show_3()
    {

    //////////////////////////////////////////////////////////
    if(PIND.6==0)
    {
    esc++;
    delay_ms(200);
    }
    //////////////////////////////////////////////////////////
    if(esc>>2)
    {
    esc=0;
    lcd_gotoxy(0,1);
    lcd_putsf(» «);
    }
    ////////////////////////////////////////////////////////////
    if(esc==1)
    {
    lcd_gotoxy(0,0);
    lcd_putsf(«>»);

    if(PIND.4==0)
    {
    VBmin++;
    delay_ms(200);
    }
    if(VBmin>30) VBmin=0;

    }
    /////////////////////////////////////////////////////////////
    if(esc==2)
    {
    lcd_gotoxy(0,0);
    lcd_putsf(» «);

    lcd_gotoxy(0,1);
    lcd_putsf(«>»);

    }

  • не понятно esc>>2 это у вас опечатка или ошибка в коде

  • Добрый день.
    Помогите подправить код что бы работал 🙁
    Уже 3 день ничего не получается (

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

    #include
    #include
    unsigned char blink = 0;
    void main(void)
    {
    PORTB=0x02;
    DDRB=0x01;
    while (1)
    if (PINB.1==1)
    { blink=1; }
    if (PINB.3==1)
    { blink=0; }
    if (blink)
    {PORTB.0=1;
    }
    else { PORTB.0=0;

    }
    }

  • для такого кода ноги мк, которые идут к кнопке должны быть физически подтянуты к 0, через резистор.

  • Кстати говоря…
    Если нога порта сконфигурирована как вход и подтянута к питанию, то вместо
    if (PINB.1==0)
    годнее писать просто
    if (!PINB.1)
    По сути ничего не меняется, но компилятор под такую конструкцию отжирает меньше памяти контроллера, иногда бывает критично, особенно при low level optimization.

  • А как сделать чтобы после отпускание кнопки светодиод горел еще минуту?

  • запустить таймер

  • Как подключить несколько независимых кнопок ?

  • Владимир От чего независимы Каждую кнопку можно настроить индеведуально

  • admin а как на Attiny 13 это сделать

  • абсолютно так же

  • добрый вечер
    у меня ни как не получается записать в меню числа с точкой.
    программа работает отлично, показания на LCD от 0,00 до 10,00
    а в меню настраиваться только от 0 до 10
    пожалуйста подскажите как исправить код

    void menuChislo (void)
    {
    Max=alertMax;
    Min=alertMin;
    Hig=alertHig;
    Low=alertLow;
    Out1=alertOut1;
    Out2=alertOut2;
    Out3=alertOut3;
    while(menu)
    {
    switch (editCount)
    {
    //——————OUT 1————————-
    //—————-МАКСИМАЛЬНОЕ ЧИСЛО——————-

    case 0:

    if(PINC.2==0)
    {
    while
    (PINC.2==0)
    delay_ms(40);
    Max++;
    }

    if(Max > 9)
    {
    Max = 9;
    }

    if(PINC.3==0)
    {
    while
    (PINC.3==0)
    delay_ms(40);
    Max—;
    }

    if(Max = Max)
    {
    Min =Max-1;
    }

    if(PINC.3==0)
    {
    while
    (PINC.3==0)
    delay_ms(40);
    Min—;
    }

    if(Min < 0)
    {
    Min = 0;
    }

    if(PINC.1==0)
    {
    while
    (PINC.1==0)
    delay_ms(40);
    editCount++;
    alertMin=Min;
    chislo=1;
    }

    lcd_gotoxy(2,0);
    lcd_puts("OUT1 LOW PRES");

    lcd_gotoxy(5,1);
    lcd_putchar((Min/1)%10+0x30);
    lcd_putsf(" BAR");
    chislo=1;
    break;

  • если используется форматированный вывод, то в настройках проекта нужно выбрать, sprintf features float

  • добрый день
    а можно по подробней пожалуйста

  • if(PINC.3==0)
    {
    while
    (PINC.3==0)
    delay_ms(40);
    Max++
    }
    прибавляет целое число, а для проекта, для более точного контроля, желательно прибавлять и отнимать с десятыми

  • вопрос в том чтобы сделать это Max += 0.1?

  • добрый вечер
    да, и чтоб на дисплее отображалось также, я пока не полностью понял как это сделать
    если бы подробнее были описания таких тонкостей, то было бы замечательно
    спасибо за Ваши уроки и Вашу помощь

  • Добрый день! Подскажите как реализовать например я портом ADC PORTС.0 измеряю напряжение 0-50в через делитель подходит минус к порту постоянно, как сделать чтобы при подачи минуса на порт PORTС.0 например выполнялся код? if(PINС.0==0)
    {
    PORTB.0=1;
    delay_ms(100);
    PORTB.0=0;
    delay_ms(100);
    }
    Заранее благодарю!

  • #define OUT1 PORTB.0
    #define OUT2 PORTA.0
    #define OUT3 PORTA.1
    #define IN1 PINB.1
    #define IN2 PINB.2
    #define IN3 PINA.7
    unsigned char a, b, q=0;

    void main(void)
    {

    #pragma optsize-
    CLKPR=(1<<CLKPCE);
    CLKPR=(0<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<5&&q==0)
    {
    q=1;
    OUT1=1;
    delay_ms(1000);
    OUT1=0;
    b=0;
    }
    if(IN1==1) b++;
    if(IN1==1&&b>5&&q==1)
    {
    q=0;
    b=0;
    }

    if(IN2==0) a++;
    if(IN2==0&&a>5&&q==0)
    {
    q=1;
    OUT1=1;
    delay_ms(1000);
    OUT1=0;
    delay_ms(1000);
    OUT1=1;
    delay_ms(1000);
    OUT1=0;
    b=0;
    }
    if(IN2==1) b++;
    if(IN2==1&&b>5&&q==1)
    {
    q=0;
    b=0;
    }
    }

    }
    А как сделать, чтоб при нажатии и удержании кнопки IN1 светодиод моргнул один раз OUT1.При нажатии и кнопки IN2 светодиод моргнул два раза OUT1. Сильно не пинайте если что не так , только учусь.

  • Начало не скопировалось вот исправил.
    while(1)
    {

    if(IN1==0) a++;
    if(IN1==0&&a>5&&q==0)
    {
    q=1;
    OUT1=1;
    delay_ms(1000);
    OUT1=0;
    b=0;
    }
    if(IN1==1) b++;
    if(IN1==1&&b>5&&q==1)
    {
    q=0;
    b=0;
    }

    if(IN2==0) a++;
    if(IN2==0&&a>5&&q==0)
    {
    q=1;
    OUT1=1;
    delay_ms(1000);
    OUT1=0;
    delay_ms(1000);
    OUT1=1;
    delay_ms(1000);
    OUT1=0;
    b=0;
    }
    if(IN2==1) b++;
    if(IN2==1&&b>5&&q==1)
    {
    q=0;
    b=0;
    }
    }

    }

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Свежие записи
Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика