Только начинаю изучать микроконтроллеры. Выбрал AVR, только потому, что Atmel studio базируется на visual studio, а его я большой поклонник (привык в ней работать). Программатора у меня нету, делал тему пытался понять какой лучше, да и деталей ( мк, датчиков, дисплеев резисторов) тоже нету. https://www.radiokot.ru/forum/viewtopic ... 7&t=158041
Но есть желание поэтому немного поискав наткнулся на протеус . Очень мне понравилась данная программа (тогда я еще не знал, что в жизни все не так как на экране). Поэтому Atmel studio + proteus 7. (качал с рутрекера крякнутый).
Так как в программировании мк не силен, нашел уроки и по ним стал учится. Попались уроки по датчикам и дисплеям, решил все знания уроков объединить и сделать часы.
МК выбрал ATmega 8A что значит буква А так и не понимаю, но она в клеящемся корпусе и дырок под нее сверлить не продеться. https://www.chipdip.ru/product/atmega8a-au
Создал проект в студии и первым делом, что мне понадобилось это определится с дисплеем, а так же организацией вывода на него информации. В протеусе к сожалению только семи сегментные или LCD дисплеи. LCD как по мне, для часов не очень круто. Поэтому решено было использовать 4 разряда семи сегментных. Для их управления мне нехотелось тратить много ножек МК и я нашел решение по управлению на базе микросхемы МАХ7219. Очень хорошая микросхема, позволяет очень легко управлять сразу 8разрядами индикатора. Мне конечно столько не нужно. Посмотрел на ее цену и ахнул, за эти деньги можно второй мк купить и им управлять индикатором, не выгодно и растратно получается очень. Наткнулся на другое решение с использованием 74HC595. Стоит это удовольствие всего 10руб. https://www.chipdip.ru/product/74hc595d
Но для реализации управления надо 2ш. что в целом всего 20руб. Соответственно одна 74HC595 для выставления уровней на одном индикаторе, а вторая 74HC595 для переключения между индикаторами (динамическая индикация), правда останется лишних 4 ножки, но при низкой цене не жалко. Так же при таком использовании придётся использовать круговую схему передачи информации, что немного снизит скорость работы, но ее все равно должно хватить.
Передача информации происходит по SPI поэтому задействуется всего 3 ножки МК. Но тут встала другая проблема. Я хотел изменять яркость свечения индикаторов. Прочитал и понял что для этого нужен ШИМ. Просто то подавать, то нет высокий уровень для питания индикатора. Как оказалось все не так просто. SPI в Atmega8 занимает выходы почти всех таймеров, остается только одна свободная доступная ножка, это PB1/OC1A. Это значит, что только на 1 таймере я могу реализовать ШИМ. Стал искать как вообще запустить, и так как я ничего почти не понял в скорости этих таймеров( точнее понял, но зачем столько настроек, каких то зависимостей между ними). Реализовал вот так:
Код: Выделить всё
DDRB |= (1<<PINB1); //ножка fast шим
PORTB = 0;
TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<WGM11) | (0<<WGM10);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (0<<CS11) | (0<<CS12) | (1<<CS10);
ICR1 = 0xFFFF; // модуль счета - максимумНе знаю, на сколько, это правильно, но импульсы дает в зависимости от величины OCR1A.
Очень прошу проверить и подсказать правильно ли я его настроил.
Для изменения яркости я подсмотрел хитрое решение на АЦП с использованием фоторезистора. Когда меняется сопротивление на резисторе от освещенности, изменятся величина напряжения на резисторном делителе, которую я снимаю АЦП реализованном на ножке PC0\ADC0.
Для запуска написал следующее :
Код: Выделить всё
ADCSRA |= (1<<ADEN) // Разрешение использования АЦП
|(1<<ADSC)//Запуск преобразования
|(1<<ADFR)//Непрерывный режим работы АЦП
|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)//Делитель 128 = 64 кГц
|(1<<ADIE);//Разрешение прерывания от АЦП
ADMUX |= (1<<REFS1)|(1<<REFS0); //Внутренний Источник ОН 2,56в, вход ADC0В прерывании как раз использовал значение OCR1A
Код: Выделить всё
ISR(ADC_vect)
{
low_adc = ADCL;
high_adc = ADCH;//Верхняя часть регистра ADC должна быть считана последней, иначе не продолжится преобразование
adc_value= (high_adc<<8)|low_adc;
OCR1A = 0xFFFF - (adc_value*64);
}Число 64 просто экспериментальное, я его взял исходя из того что OCR1A максимум 0xFFFF, а adc_value максимум 1024, значит 0xFFFF/1024 = 64. На деле конечно придется подобрать минимальное значение при котором индикатор будет светится и ограничить его.
Осталось всего два таймера. Если честно мне таймеры очень понравились, и я старался использовать их по максимум. Почитав я понял, что нулевой таймер очень слабенький и не быстрый, поэтому для индикации, т.е. подачу сигнала на индикацию использовал таймер 2.
Включил его вот так, если кто может, подскажите как правильно, про регистры вроде прочитал, но хз чет сомневаюсь:
Код: Выделить всё
TIMSK |= (1<<TOIE2); // Разрешаем прерывание по переполнению
TCCR2 |= (1<<CS22)|(1<<CS20); // Предделитель на 128В прерывании ISR (TIMER2_OVF_vect) код получился сложный, не в один заход написанный, все зависит от режима, от того что показываю и т.д.
Ну а последний нулевой таймер решил использовать для обработки нажатия кнопки. В принципе кнопок можно сделать больше чем одну, свободные ножки позволяют, но для корпуса проще одну кнопку выводить и с ее помощью вроде все должно получиться.
Запустил таймер и ножку настроил
Код: Выделить всё
DDRB&=~(1<<DDRB0); //Настраиваем ножку PB0 в режим входа
PORTB|=(1<<PORTB0); //Устанавливаем pull-up режим ножки PB0
TCCR0 |= (1<<CS02)|(1<<CS00);
TIMSK |= (1<<TOIE0);Опять просьбы проверить и подсказать все ли так. Кнопка подключена к PB0.
В обработчике TIMER0_OVF_vect прерывания, считаю, сколько циклов нажата кнопка если больше 3 и меньше 60 то короткое нажатие, если больше 60 длинное. Длинные нажатия меняют режимы редактирования: часы, минуты, день, месяц, год, день недели, вкл будильника, часы будильник, минуты будильник. Короткие нажатия увеличивают значения этих величин. В случае с вкл будильника, вкл или выкл.
Так же применил микросхему DS18B20 датчик температуры. Очень как мне показалось дорогое удовольствие. Стоит больше 100руб. дороже мк. Работает по шине 1-Wire. На этой шине может быть много этих датчиков ( 125 по-моему), но чтобы не искать их на шине и не писать код я использовал 1 и пропустил его идентификацию.
Сам ход часов реализован на DS1307ZN. Думаю статей про нее предостаточно поэтому особенно распыляться не буду, проблем с ней не возникло.
Очень прошу опытных проверить код и подсказать, как его можно улучшить.
Начал подбирать компоненты, возникла проблема с индикатором. Не могу найти индикатор с точками и двоеточием одновременно. Чтобы показывать время нужно двоеточие, для даты точка под двоеточием, и для температуры у меня нужна точка в предпоследнем знаке. Везде либо двоеточие для времени, либо точки под знаками, а надо и то и то. Подскажите какой можно найти в Москве.
Какие лучше транзисторы использовать для управления индикаторами? Мне желательно маленькие клеящиеся, чтобы не сверлить дырок.
Под большим вопросом, но мысли не отпускают связь с интернетом. Я понимаю что часы со временем будут либо убегать либо отставать, и это будет зависеть от окружающей среды кварца. Чем теплее скорее всего тем часы сильнее будут убегать вперед ( это я предполагаю) , чем холоднее наоборот. Поэтому хотелось бы связаться с интернетом, но постоянная связь мне не нужна, а это значит можно и блютус например, подключится и подправить время ( думаю что такое решение тоже удобное ). Вся проблема в том что нету железа пробовать и возможности такой, а в протеусе такое не смоделировать. ( боюсь не потяну).



