Заголовок сообщения: ATmega8, динамическая индикация, switch case и десятичная то
Добавлено: Сб сен 28, 2024 16:49:42
Родился
Зарегистрирован: Сб сен 28, 2024 16:19:04 Сообщений: 12
Рейтинг сообщения:0
Доброго всем времени суток. Начал недавно изучать программирование AVR на Си. Поднакопил немного знаний и решил сделать свое первое устройство, нагрузку для разряда АКБ. Набросал в протеусе вот такую схемку [img][url=https://img.radiokot.ru/files/158040/medium/3kcp23hfco.jpg][/img] Написал в AtmelStudio вот такой код Спойлер
//---------- динамической индикации------------------------------ unsignedchar n = 0; //переменная количества вхождений в прерывание unsignedchar r1_1000 = 0; //переменная значения разряда тысяч unsignedchar r2_100 = 0; //переменная значения разряда сотен unsignedchar r3_10 = 0; //переменная значения разряда десятков unsignedchar r4_1 = 0; //переменная значения разряда единиц //----------
//---------- времени--------------------------------------------- unsignedchar sec = 0; //переменная количества секунд unsignedchar min = 0; //переменная количества минут unsignedchar hour = 0; //переменная количества часов //----------
//---------- кнопок (внешние прерывания)---------- unsignedchar button_1 = 0; //переменная количества секунд unsignedchar button_2 = 0; //переменная количества минут //----------
unsignedint temp = 0; //переменная хранения значения температуры float volt = 0; //переменная хранения значения напряжения АКБ unsignedchar n_ADC = 0; //переменная количества преобразований АЦП
//---------- индикация и отображение информации---------------- voidLED_DISP_pin_setup(void)//функция настройки пинов LED индикатора { //настройка сегментов A, B, Dp, C, G DDRB |= (1<<4) | (1<<3) | (1<<2) | (1<<1) | (1<<0); //режим работы - выход PORTB &= ~((1<<4) | (1<<3) | (1<<2) | (1<<1) | (1<<0)); //низкий потенциал на пинах //настройка сегментов E, D, F DDRD |= (1<<7) | (1<<6) | (1<<5); //режим работы - выход PORTD &= ~((1<<7) | (1<<6) | (1<<5)); //низкий потенциал на пинах //настройка разрядов 1-4 DDRC |= (1<<3) | (1<<2) | (1<<1) | (1<<0); //режим работы - выход PORTC |= (1<<3) | (1<<2) | (1<<1) | (1<<0); //высокий потенциал на пинах }
voidshow_min_sec(unsignedint znach_min, unsignedchar znach_sec) { r1_1000 = znach_min / 10; //определение значения десятков минут r2_100 = znach_min % 10; //определение значения единиц минут r3_10 = znach_sec / 10; //определение значения десятков секунд r4_1 = znach_sec % 10; //определение значения единиц секунд }
voidshow_hour_min(unsignedint znach_hour, unsignedchar znach_min) { r1_1000 = znach_hour / 10; //определение значения десятков часов r2_100 = znach_hour % 10; //определение значения единиц часов r3_10 = znach_min / 10; //определение значения десятков минут r4_1 = znach_min % 10; //определение значения единиц минут }
ISR(INT0_vect) //макрос обработки прерывания, изменение отображаемой информации { if (++button_1 > 3) button_1 = 1; }
ISR(INT1_vect) {
} //----------
//---------- voidADC_pin_setup(void) { DDRC &= ~((1<<5) | (1<<4)); //пин PD4 и PD5 в режим работы вход PORTC &= ~((1<<5) | (1<<4)); //высокое входное сопротивление на пинах PD4 и PD5 }
voidADC_setup() { //разрешаем работу АЦП ADCSRA |= (1<<ADEN); //непрерывный режим работы АЦП ADCSRA |= (1<<ADFR); //частота дискретизации 125 кГц (частота МК 8 МГЦ, делитель 64) ADCSRA |= (1<<ADPS2) | (1<<ADPS1); ADCSRA &= ~(1<<ADPS0); //подключаем внешний ИОН - 5В //ADMUX |= (1<<REFS0); //ADMUX &= ~(1<<REFS1); //подключаем внутренний ИОН - 2,56В ADMUX |= (1<<REFS1) | (1<<REFS0); //выравнивание результата преобразования в регистре ADC по правой стороне ADMUX &= ~(1<<ADLAR); //настраиваем 5-й канал АЦП ADMUX |= (1<<MUX2) | (1<<MUX0); ADMUX &= ~((1<<MUX3) | (1<<MUX1)); //разрешаем преобразование АЦП ADCSRA |= (1<<ADSC); //разрешаем прерывание от АЦП ADCSRA |= (1<<ADIE); }
После включения, при нажатии на кнопку (подключена к пину PD2) изменяется отображаемая информация на семисегментном индикаторе. Поле первого нажатия отображается время прошедшее с момента включения, после второго - температура, после третьего - напряжение на АКБ. И вот тут возник вопрос. А как включить десятичную точку во втором разряде при отображении напряжения?
Очень у вас хорошо читаемый код получился. Хотя могут, конечно, набежать и сказать, что не по феншую, и какие-то непонятные константы в тексте тут и там)
По мне так лучше держать сразу отображаемый код в переменных, а не цифру от 0 до 9. Хоть у вас и в двух разных регистрах сегменты, но все равно по номерам битов от 0 до 7 - простой char получается. Лучше переделать иначе с точкой будет слишком кучеряво.
а не поличилось, патамучто "GyverTM1637 — бибилотека для 7 сегментного дисплея на чипе TM1637 с кучей приколюх" (орфография сохранена) и пака одна дурака макака совитует хирню, дргая дурака макака не мажит то же думот. да здраствуят адурина! с кучей приколюх
Вообще, это обычный путь начинающего - одиночные светодиоды, семисегментный индикатор в один разряд, и наконец - динамическая индикация на семисегментниках. Всё по классике, это же изучение. Затем должен быть двустрочный знакосинтезирующий ЖК-дисплей, желательно не на I2C, а на параллельной шине. А вот ассемблер нынче не нужен. Его можно знать, но писать на нем - смысла нет никакого.
А вот ассемблер нынче не нужен. Его можно знать, но писать на нем - смысла нет никакого.
То, что я пишу на асме, я бы и не стал здесь упоминать, это не тема данного обсуждения. Сказал лишь для того, что бы развеять "уверенность" мартиана что все сидят на ардуине и на библиотеках:
Martian писал(а):
а не поличилось, патамучто "GyverTM1637 — бибилотека для 7 сегментного дисплея на чипе TM1637 с кучей приколюх" (орфография сохранена) и пака одна дурака макака совитует хирню, дргая дурака макака не мажит то же думот. да здраствуят адурина! с кучей приколюх
к чему эта реплика вообще?
По поводу есть смысл или нет, то это обычный холивар на тему асм/яву, гимп/фотошоп, линукс/виндовс... А писАть я могу хоть на тетрадке в клеточку, главное результат.
Ардуина существует уже больше 15 лет, поэтому немудрено, что многие её используют. Я вот например использую готовые платы от WeAct, китайцы научились ставить на них мощные МК.
По поводу затронутой темы с дин.идникацией. Я тоже в своих первых опытах писал нечто подобное Однако, затем переделал на таблицу. То есть, список зажигаемых сегментов можно представить в виде таблицы - индексированный одномерный массив на 10 элементов. То есть, примерно так:
Код:
/* Распиновка сегментов на одном порту (можно в любом порядке пинов) */ #define SEGA (1 << 0) #define SEGB (1 << 1) #define SEGC (1 << 2) #define SEGD (1 << 3) #define SEGE (1 << 4) #define SEGF (1 << 5) #define SEGG (1 << 6) #define SEGp (1 << 7)
(GPIOA и GPIOB написаны условно) И затем функцию Phase() вызывать через заданные промежутки времени в соответствии с порядком индикации (можно даже и в любом порядке разрядов). В функцию передаем номер выбираемого разряда, отображаемую цифру и признак включения десятичной точки в разряде. Да, в эту функцию можно еще добавить параметр - признак гашения цифры, и по этому признаку гасить все сегменты в разряде, то есть, не отображать его.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения