Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define F_CPU 8000000UL // тактовая частота мк
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include "oled_ssd1306.h"
- uint8_t tiki;// глобальные тики показывает число прерываний с 0 до 256
- uint8_t clk;// флаг клика
- uint8_t clk1;// флаг клика
- uint16_t i;// 16 разрядная переменная ,т.к. АЦП имеет разрядность 10 бит(1024) и 8 бит(255) недостаточно для работы АЦП
- void adc_ini (void)
- {
- /*** Настройка АЦП ***/
- ADCSRA |= (1 << ADEN) // Включение АЦП
- |(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8
- ADMUX |= (0 << REFS1)|(1 << REFS0) // внешний ИОН
- |(1 << MUX0)|(1 << MUX1); // вход PC3
- }
- void adc (void)
- {
- ADCSRA |= (1 << ADSC); // Начинаем преобразование
- while ((ADCSRA&(1 << ADIF))== 0); // Ждем флага окончания преобразования
- i = (ADCL|ADCH << 8); // Считываем ADC
- if (i > 680)
- {
- PORTD |= (1<<PD0);
- PORTD &= ~(1<<PD1);
- }
- else
- {
- PORTD |= (1<<PD1);
- PORTD &= ~(1<<PD0);
- }
- }
- void Counter0_init()
- {
- TCCR1B |= (1 << CS12);
- TCCR1B &= ~(1 << CS11);
- TCCR1B &= ~(1 << WGM10);
- TCCR1B &= ~(1 << WGM11);
- TCCR1B |= (1 << WGM12);
- TCCR1B &= ~(1 << WGM13);
- TCCR1A &= ~(1 << COM1A1);
- TCCR1A |= (1 << COM1A0);
- DDRB |= (1 << PB1);
- }
- // обработчик прерывания по переполнению. ~61гц ( 122)
- ISR(TIMER2_OVF_vect)
- {
- tiki++;//инкрементируем с каждым прерыванием
- }
- // инициализация таймера
- void timer_ini(void)
- {
- TCCR2B|=(1<<CS22);// запуск таймера 0 с делителем 256
- TIMSK2|=(1<<TOIE0);// разрешить прерывание по переполнению
- }
- uint8_t tikies(void) //функция получения тиков(8 битное число прерываний в любой момент)
- {
- return tiki; //возвращает число прерываний (аналог времени между прерываниями умноженному на их число ,т.е. например при частоте 60гц -имеем
- // время между двумя прерываниями 1/60= 17мс и текущее время меняется от 17мс*0 =0 ,до 17*256 =4,2сек)
- }
- // инициализация блинков
- void blink_ini(void)
- {
- DDRB|=(1<<PB1);
- DDRC|=(1<<PC0)|(1<<PC1) |(1<<PC2);
- }
- void button_KA(void)
- {
- static uint8_t status, press;// переменная тип static для того ,чтобы сохранять свое значение (полученное в результате переключений в теле этой функции)
- //при последующем обращении к этой функции (при последующих иттерациях) ,а не начинать с первоначальгого значения (0) ,как с обычной локальной переменной
- uint8_t now=tikies();// получаем текущее время(текущее возвращенного функцией now=tikies() значения переменной тики (8битное значение)
- switch (status)
- {
- case 0:// опрос кнопки
- if (!(PINB&(1<<PB0))) // если кнопка нажата
- {
- status=1;// уходим в статус 1
- press=now;// запоминаем время нажатия например 25- это число прерываний (тики) назовем его "press"
- }
- break;
- case 1:// учет времени удеражания кнопки
- if (PINB&(1<<PB0))// если кнопка уже отжата
- {
- if ((uint8_t) (now-press)>=3) clk=1;//NB!!! переменная tiki имеет 8 бит и примерно через каждые 17*256 =4,2сек переполняется ,что вызывает сбой в
- //if ((now-press)>=3). чтобы избежать этого объявляем переменную (now-press) как 8 бит ,т.е. if ((uint8_t) (now-press)>=3)
- // рассчитываем время удержания кнопки,например после запомненных 25(т.е. press)
- //счетчик прераваний увеличился и стал now =press+число прерываний,прошедших после запоминания (что и является временем задержки (now-press)
- //в данной строке =3 тика(число прерываний (тики))если этой задержки достаточно поднимаем флаг клика clk
- //в случае частоты прерываний 60гц имеем задержку 3*17мс =51мс,что достаточно для антидребезга
- status=0;// уходим в статус 0 ( 3x8.2=24.6b ms)
- }
- break;
- }
- }
- void button_KA1(void)
- {
- static uint8_t status, press1;
- uint8_t now1=tikies();// получаем текущее время
- switch (status)
- {
- case 0:// опрос кнопки
- if (!(PINB&(1<<PB3))) // если кнопка нажата
- {
- status=1;// уходим в статус 1
- press1=now1;// запоминаем время нажатия
- }
- break;
- case 1:// учет времени удеражания кнопки
- if (PINB&(1<<PB3))// если кнопка уже отжата
- {
- if ((uint8_t) (now1-press1)>=3) clk1=1; //NB!!! переменная tiki имеет 8 бит и примерно через каждые 17*256 =4,2сек переполняется ,что вызывает сбой в
- //if ((now1-press1)>=3). чтобы избежать этого объявляем переменную (now1-press1) как 8 бит ,т.е. if ((uint8_t) (now1-press1)>=3)
- // рассчитываем время удержания кнопки, если достаточно поднимаем флаг клика
- status=0;// уходим в статус 0
- }
- else// иначе, кнопка всё еще удерживается
- {
- if ((uint8_t) (now1-press1)>=61) {
- // если удерживается уже достаточно долго,т.е. разница между запомненным press1 и текущим now1 больше или
- //равно 61(счетчик тиков)(в этом примере) это и есть длинная задержка .И сейчас поднимается флаг длинного клика clk1=10
- clk1=10;// поднимаем флаг длинного клика
- status=2;// уходим в статус 2
- }
- }
- break;
- case 2:// ждем пока кнопку отпустят
- if (PINB&(1<<PB3)) status=0;// когда на пине 1 уходим в статус 0
- break;
- }
- }
- uint8_t button_stat(void)//При подъеме флага (clk=1) функция возвращает переменную а=clk,о флаг сбрасывает (clk=0) ,подготавливая к следующему нажатию кнопки
- {
- uint8_t a=clk;
- clk=0;
- return a;
- }
- uint8_t button_stat1(void)
- {
- uint8_t a=clk1;
- clk1=0;
- return a;
- }
- void blink_click_KA(void)
- {
- static uint8_t status;
- uint8_t but=button_stat();// получение событий от кнопки
- switch (status)
- {
- case 0:// светодиод выключен
- TCCR1B&=~((1<<CS10)|(1<<CS12)|(1<<CS11));
- TCCR1A &= ~(1 << COM1A1);
- TCCR1A &= ~(1 << COM1A0);
- PORTB&=~(1<<PB1);
- oled_gotoxy(0,4);
- oled_write(" POSITIV");
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=1;
- }
- break;
- case 1:// светодиод включен
- TCCR1A &= ~(1 << COM1A1);
- TCCR1A &= ~(1 << COM1A0);
- PORTB|=(1<<PB1);
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=2;
- }
- oled_gotoxy(0,4);
- oled_write(" NEGATIV");
- break;
- case 2:// светодиод мигает
- OCR1A = 7813;
- Counter0_init();
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=3;
- }
- oled_gotoxy(0,4);
- oled_write(" 2 Hz ");
- break;
- case 3:// светодиод мигает
- OCR1A = 2594;
- Counter0_init();
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=4;
- }
- oled_gotoxy(0,4);
- oled_write(" 6 Hz ");
- break;
- case 4:// светодиод
- OCR1A =520;
- Counter0_init();
- oled_gotoxy(0,4);
- oled_write(" 30 Hz ");
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=5;
- }
- break;
- case 5:// светодиод
- OCR1A =313;
- Counter0_init();
- oled_gotoxy(0,4);
- oled_write(" 50 Hz ");
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=6;
- }
- break;
- case 6:// светодиод
- OCR1A =130;
- Counter0_init();
- oled_gotoxy(0,4);
- oled_write("120 Hz ");
- if (but)// если было нажатие меняем статус.
- {
- if (but==1)
- status=0;
- }
- break;
- }
- }
- void blink_click_KA1(void)
- {
- static uint8_t status;
- //uint8_t now1=tikies();// текущее "время"
- uint8_t but1=button_stat1();// получение событий от кнопки
- switch (status)
- {
- case 0:
- if (but1)// если было нажатие меняем статус.
- {
- //if (but1==1)
- status=1;
- }
- PORTC&=~(1<<PC0);
- oled_gotoxy(0,1);
- oled_write(" OFF ");
- break;
- case 1:
- if (but1)// если было нажатие меняем статус.
- {
- //if (but1==1)
- status=2;
- }
- PORTC|=(1<<PC0);
- oled_gotoxy(0,1);
- oled_write(" LOW");
- break;
- case 2:
- if (but1)// если было нажатие меняем статус.
- {
- //if (but1==1)
- status=3;
- }
- PORTC&=~(1<<PC0);
- PORTC|=(1<<PC1);
- oled_gotoxy(0,1);
- oled_write(" MIDDLE");
- break;
- case 3:
- if (but1)// если было нажатие меняем статус.
- {
- //if (but1==1)
- status=4;
- }
- PORTC&=~(1<<PC1);
- PORTC|=(1<<PC2);
- oled_gotoxy(0,1);
- oled_write(" HIGH ");
- break;
- case 4:
- if (but1)// если было нажатие меняем статус.
- {
- //if (but1==1)
- status=1;
- }
- //if ( (uint8_t) (now1-change1)<1)
- ////насчет (uint8_t) (now1-change1) смотри 198
- //break;
- PORTC&=~(1<<PC2);
- oled_gotoxy(0,1);
- oled_write(" OFF ");
- //change1=now1;
- break;
- }
- }
- int main(void)
- {
- DDRD|=(1<<PD0)|(1<<PD1);
- //timer_counter1_INIT();
- adc_ini ();
- blink_ini(); // инициализация блинков
- timer_ini();// инициализация таймера
- sei();// глобально разрешить прерывания
- oled_init();
- oled_gotoxy(0,0);
- //oled_font_size(0);
- //oled_gotoxy(0,0);
- //oled_write("12345");
- while(1)
- {
- adc ();
- oled_font_size(1);
- blink_click_KA();
- blink_click_KA1();
- button_KA();
- button_KA1();
- oled_font_size(0);
- oled_gotoxy(3,7);
- oled_write("*Tavger ltd*");
- //oled_gotoxy(0,0);
- //oled_write(" current");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment