Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
💸 Как сделать бизнес проще, а карман толще?
Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое раписание, но и напоминать клиентам о визитах тоже.
Проблема в том, что средняя цена по рынку за такой сервис — 800 руб/мес или почти 15 000 руб за год. И это минимальный функционал.
Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.⚡️ Для новых пользователей первый месяц бесплатно. А далее 290 руб/мес, это в 3 раза дешевле аналогов. За эту цену доступен весь функционал: напоминание о визитах, чаевые, предоплаты, общение с клиентами, переносы записей и так далее. ✅ Уйма гибких настроек, которые помогут вам зарабатывать больше и забыть про чувство «что-то мне нужно было сделать». Сомневаетесь? нажмите на текст, запустите чат-бота и убедитесь во всем сами! Пример 4. Вывод цифр от 0 до 99. ⇐ ПредыдущаяСтр 2 из 2
Преобразование двоичных чисел в двоично-десятичные (BCD) #define F_CPU 1000000UL #include < avr/io.h> #include < avr/iom16.h> #include < util/delay.h> #include < avr/interrupt.h>
unsigned char number[] = { 0x3f, //0 0x06, //1 0x5b, //2 0x4f, //3 0x66, //4 0x6d, //5 0x7d, //6 0x07, //7 0x7f, //8 0x6f //9 };
//числа для вывода на индикатор volatile unsigned char data1 = 0; volatile unsigned char data2 = 0; unsigned char counterProg = 0; int main(void) { //порт, к которому подкл. Сегменты PORTA = 0xff; DDRA = 0xff;
//порт, к которому подкл. Катод PORTB = 0; DDRB = (0< < 1)|(0< < 0);
//инициализация таймера Т0 частота прерываний 100Гц при кварце 8МГц TIMSK = (1< < TOIE0); TCCR0 = (1< < CS02)|(0< < CS01)|(1< < CS00); TCNT0 = 0xb2; sei();
while(1) { //программный счетчик секунд counterProg++; if (counterProg == 100) counterProg = 0; data1 = counterProg % 10; data2 = counterProg/10; _delay_ms(500); } return 0; }
//прерывания таймера Т0 - вывод на индикатор ISR(TIMER0_OVF_vect) { static unsigned char count = 0; TCNT0 = 0xb2; //гасим оба разряда PORTB & = ~((1< < 1)|(1< < 0)); //выводим в порт код цифры и зажигаем следующий разряд if (count == 0) { PORTA = number[data2]; PORTB |= (1< < 1); } if (count == 1) { PORTA = number[data1]; PORTB |= (1< < 0); } count++; if (count == 2) count = 0; } Следующий этап работы над программой – выделение кода обслуживающего светодиодный семисегментный индикатор в отдельные функции. Какой минимальный набор функций нам необходим? Функция инициализации, функция вывода на индикатор и функция преобразования чисел и записи их в буфер. Функция инициализации #define PORT_IND PORTB #define DDR_IND DDRB #define PORT_K PORTD #define DDR_K DDRD #define KAT1 0 #define KAT2 1 volatile unsigned char data[2]; void IND_Init(void) { //порт к которому подкл. Сегменты PORT_IND = 0xff; DDR_IND = 0xff; //порт, к которому подкл. Катоды PORT_K & = ~((1< < KAT2)|(1< < KAT1)); DDR_K |= (1< < KAT2)|(1< < KAT1); //очистка буфера data[0] = 0; data[1] = 0; }
Порты, к которым подключен семисегментный индикатор, определены с помощью директивы #define– в будущем это позволит быстро править код. Вместо двух переменных data1, data2 удобнее использовать массив unsigned char data[2]. Функция преобразования void IND_Conv (unsigned char value) { unsigned char tmp; tmp = value % 10; data[0] = number[tmp]; tmp = value/10; data[1] = number[tmp]; }
Процедура преобразования чисел аналогична описанной выше. Единственное отличие – в буфере (data[]) мы теперь сохраняем не результат преобразования, а коды цифр. Зачем делать в прерывании то, что можно сделать в основном цикле программы?
|