Радиосхемы для дома на atmega8. Схемы устройств на микроконтроллерах. Частотомер I от DANYK

Частотомер на АТ90S2313

Виртуальный частотомер это "комплект" из программы для PC и простого измерительного прибора, который подключается к COM порту компьютера. Виртуальный прибор позволяет измерять частоту, период, временные интервалы и вести подсчет импульсов.

Подробности: http://home.skif.net/~yukol/FMrus.htm

Рекомендую собрать простая конструкция не требует настройки и главное работает! Микроконтроллер программировал программатором PonyProg -отличный программатор, простой, большая номенклатура программируемых микроконтроллеров, работает под Windows, интерфейс русский.


Журнал "Радио" N1 2002г. Для Ni-Cd аккумуляторов. Позволяет заряжать 4 аккумулятора.



Частотомер на Pic 16F84A

Технические характеристики частотомера:

Максимальная измеряемая частота.............30 МГц;

Максимальное разрешение измеряемой частоты.. .10 Гц.

Чувствительность по входу....................250 мВ;

Напряжение питания.........................8... 12 В:

Потребляемый ток............................35 мА


Подробности, прошивка: http://cadcamlab.ru


Паяльная станция на Atmega 8


Переключение паяльника и фена осуществляется переключателями ПК. Управление феном осуществляется тиристором, т.к. фен на 110в вместо R1 диод катодом к в.6.


Подробности, прошивка: http://radiokot.ru/forum


Цифровой измеритель емкости без выпайки из схемы

Описание дано в журнале "Радио" №6 2009 г. Конструкция собрана на AT90S2313, без изменений в прошивке применил Tiny2313. В Поньке выставил галки для SUT1, CKSEL1, CKSEL0, остальные пустые. MAХ631 не ставил, она что то у нас дорогая, решил запитать от блока питания через стабилизатор 7805, R29, R32 , R33 посадил на плюс питания. Кроме измерителя емкости в корпусе смонтирован пробник, для проверки транзисторов без выпайки и генератор НЧ ВЧ сигналов.



Измеритель параметров полупроводниковых приборов на ATmega8

Прибор умеет:

Определять выводы полупроводников;
- определять тип и структуру;
- измерять статические парамеры.
Измеряет диоды, биполярные транзисторы,полевые транзисторы JFET и MOS, резисторы, конденсаторы.


Измеритель выполнен в одном корпусе с измерителем FCL, индикатор переключается между приборами переключателем ПК.

Частотометр, измеритель ёмкости и индуктивности - FCL-meter

Описываемый ниже прибор позволяет в широких пределах измерять частоты электрических колебаний, а также ёмкость и индуктивность электронных компонентов с высокой точностью. Конструкция обладает минимальными размерами, массой и энергопотреблением.

Технические характеристики:

Напряжение питания, В: 6…15

Ток потребления, мА: 14…17

Пределы измерения:

F1, МГц 0,01…65**

F2, МГц 10…950

С 0,01 пФ…0,5 мкФ

L 0,001 мкГн…5 Гн


Схема выносной головки


Подробнее: http://ru3ga.qrz.ru/PRIB/fcl.shtml


Миниатюрный вольтметр на микроконтроллере ATmega8L


Здесь рассматривается конструкция вольтметра на одном лишь микроконтроллере ATmega8L и индикаторе от электронного медицинского термометра. Диапазон измеряемых напряжений постоянного тока ±50 В. Как дополнительная функция – реализован режим звукового пробника для проверки целостности проводов, ламп накаливания. Устройство автоматически переходит в дежурный режим при отсутствии измерений. Питание микроконтрллера осуществляется от двух миниатюрных щелочных элементов (элементы питания для наручных часов), я поставил 1 элемент на 3в. Необходимости часто менять элементы питания не будет: потребляемый ток в активном режиме составляет всего 330 мкА, в дежурном режиме – менее 300 нА. Благодаря своей миниатюрной конструкции и возможностям устройство полезно и практично. В корпус от термометра не влезла у меня плата, и я сделал в корпусе от фламастера. Плату делал свою, резисторы R5-R7 установил ветикально на шинах. Прошивку из исходника помог сделать VADZZ спасибо ему. Выводы индикатора с лево на право, выводы внизу и лицом к себе.

Схема (для полноформатной схемы сохраните изображение себе на компьютер).

Подробнее смотри: http://www.rlocman.ru/shem/schematics.html?di=63917

ЗУ с функцией измерения емкости

Захотелось померять емкость аккумуляторов, импортные измерители достаточно дорого стоят, нашел интересную схему и собрал. Работает нормально, заряжает, измеряет, но с какой точностью затрудняюсь сказать - нет эталона. Мерял аккумуляторы довольно приличных фирм 2700 ма/ч - намерял 2000. Аккумуляторы от игрушек 700 ма/ч -350, заказывал на EBAY китайские аккумуляторы BTY 2500 ма/ч - 450 ма/ч, но при этом достаточно приличные, неплохо работают в игрушках, гораздо выгоднее батареек.


Устройство предназначено для зарядки NiMH аккумуляторов и контроля их емкости. Переключение режимов заряд/разряд осуществляется кнопкой SА1. Режим работы отображается с помощью светодиодов и десятичными точками двух первых разрядов семисегментного индикатора.
Сразу после включения питания устройство переходит в режим заряд. На индикаторе отображается время заряда. После истечения запрограммированного промежутка времени заряд прекращается. Об окончании заряда (и разряда то же) свидетельствует зажженная точка четвертого разряда. Ток заряда определяется как С/10 где С - емкость батареи, выставляется подстроечником R14.
Принцип действия измерителя основан на подсчете времени за которое напряжение аккумулятора снизится до1,1 В. Ток разряда должен быть равен 450 ма, выставляется R16. Для того чтобы измерить емкость, надо вставить аккумулятор в отсек для разряда и запустить процесс нажатием на кнопку! Устройство способно разряжать только один аккумулятор .

Подробнее: http://cxem.net

Универсальная печь радиолюбителя

Печка для пайки SMD деталей, имеет 4 программируемых режима.

Схема блока управления (для полноформатной схемы сохраните изображение себе на компьютер).


Блок питания и управление нагревателем


Собрал данную конструкцию для управления ИК паяльной станцией. Может когда нибудь и печкой управлять буду. Была проблема с запуском генератора, поставил конденсаторы 22 пф с выводов 7, 8 на массу, и стала нормально запускаться. Все режимы нормально отрабатывает, нагружал 250 вт керамическим нагревателем.

Подробнее: http://radiokot.ru/lab/hardwork/11/

Пока печки нет, сделал вот такой нижний подогрев, для небольших плат:

Нагреватель 250 вт, диаметр 12 см, прислали из Англии, покупал на EBAY.


Цифровая паяльная станция на PIC16F88x/PIC16F87x(a)

Паяльная станция с двумя одновременно действующими паяльником и феном. Можно использовать разные МК (PIC16F886/PIC16F887, PIC16F876/PIC16F877, PIC16F876a/PIC16F877a). Применен дисплей от Nokia 1100 (1110). Обороты турбины фена регулируются электронно, так же задействован встроенный в фен геркон. В авторском варианте применен импульсный блок питания, я применил трансформаторный БП. Всем мне нравится эта станция, но с моим паяльником: 60вт, 24в, с керамическим нагревателем, большое забегание и колебание температуры. При этом паяльники меньшей мощности, с нихромовым нагревателем имеют меньшие колебания. При этом мой паяльник, с описаной выше паяльной станцией от Михи-Псков, с прошивкой от Volu, поддерживает температуру с точность до градуса. Так что нужнен хороший алгоритм нагрева и поддержания температуры. В качестве эксперемента сделал ШИМ регулятор на таймере, управляющее напряжение подал с выхода усилителя термопары, отключение, включение от микроконтроллера, Колебание температуры сразу уменьшилось до нескольких градусов, это подтверждает что нужен правильный алгоритм управления. Внешний ШИМ это конечно порнография при наличии микроконтроллера, но хорошую прошивку пока не написали. Заказал другой паяльник если с ним не будет хорошей стабилизации, продолжу свои эксперементы с внешним ШИМ управлением, а может хорошая прошивка появится. Станцию собрал на 4 платах, соединяются между собой на разъемах.

Схема цифровой части устройсква представлена на рисунке, для наглядности показаны два МК: IC1 - PIC16F887, IC1(*) - PIC16F876. Другие МК подключаются аналогично, на соответствующие порты.

Для изменения контрасности нужно найти 67 байт, его значение "0х80" , для начала можно поставить "0х90". Значения должны быть от "0х80" до "0х9F".

По поводу дисплея 1110i (текст отображается зеркально), если не китай, а оригинал,открываем ЕЕПРОМ, ищем 75 байт, меняем его с A0 на A1.

Для рассмотрения и возможного повторения, очень простую схему, очень хорошего таймера. С удобной навигацией по меню, с жидкокристаллическом LCD дисплеем, с часами реального времени, с минимально возможным количеством деталей и при всем этом можно запрограммировать целых сто временных отрезков в течении суток.

Компактные размеры

Видео проверки таймера

Сердцем данного таймера является очень популярный и уже не дорогой микроконтроллер Atmega8. Вы можете сказать, что для прошивки нам потребуется программатор которого нет, но это не так, для прошивки Atmega достаточно всего пять коротких 10-15 см. проводков подключенных через резисторы 150-200 Ом. напрямую к LPT порту по этой схеме.


Вот по этой причине, эти микроконтроллеры стали самыми популярными у радиолюбителей.

На этом рисунке Вы видите: Схему распиновки ножек МК для подключения и прошивки.

Пункт 1. Подготовим все необходимое для изготовления таймера.

Самые обязательные радиодетали схемы, остальное обычно можно подобрать у себя дома, самая маленькая микросхема, это часы DS1307.

Нам потребуются такие радиоэлементы:

Интегральные часы DS1307
LCD жидкокристаллический индикатор
Стабилизатор 7805
500-1000 Мф - 16 вольт.
Реле или электронный ключ (в зависимости от нагрузки которая планируется подключаться).
сопротивлением 5,1ком - 3 шт., резистор переменный (по мануалу LCD дисплея).
Кварц часовой 32768 Гц.
Кнопки без фиксации - 4 шт.
Батарейка таблетка на 3 вольта.
Текстолит для платы.
Небольшой трансформатор ~220в. -> ~6-12в.
Коробка распаечная для корпуса.
+ Для программатора: резисторы 150-200 Ом. - 4 шт., разъем LPT порта (для удобства, не обязателен).

Обязательные инструменты каждого радиолюбителя:
Паяльник для пайки микросхем, паяльник для пайки пассивных радиодеталей и проводов.
Тестер для прозвонки дорожек и проверки радиодеталей.
Олово, канифоль.
+ Принтер лазерный (для изготовления платы или другой способ).

Пункт 2. Приступим к изготовлению.

Таймер будем делать по этой главной схеме.


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

Лично я своем таймере применил вот такую схему БП и исполнительное устройство на транзисторе и реле.


Но вы можете захотеть в качестве исполнительного устройства применить триаки, тиристоры и симисторы, варианты таких схемных показаны ниже.



Они более компактные (без радиатора), но менее мощные, чем простое реле.

В соответствии с главной принципиальной схемой + БП + ИУ и анализом монтажных габаритов вашей коробки для корпуса, а также размеров подобранных радио элементов, проектируем форму, размер и рисунок дорожек на плате. Для этого удобно пользоваться программой Sprint Layout.

Для моего устройства получилась вот такая простая плата.


Полученный рисунок переносим с помощью специального маркера или по технологией ЛУТ (с помощью лазерного принтера и утюга) на медный слой текстолита. Если у вас принтер лазерный Brother (как у меня), то идею с ЛУТ лучше сразу забросить, по причине используемого в нем тугоплавкого тонера ~400C вместо обычных~200С, я кстати когда-то по глупости купил этот принтер именно для ЛУТ:(., поэтому в результате моя плата рисована маркером.
Нанесенный на медь рисунок вытравливаем в ванночке с хлорным железом или любым другим специальным раствором.


На готовую плату припаиваем детали согласно схеме, особое внимание обращаем при монтаже и пайке микросхемы часов и кварцевого элемента. Длина дорожек между ними должна быть минимальной, а лучше использовать микро кварц из наручных часов и припаять его непосредственно к ножкам МС часов. Все свободное пространство рядом с МС часов и кварца заполняем площадками корпуса (GND). Батарея необходима для поддержания часов в рабочем состоянии во время отключения от сети. Если по какой-то причине вы не стали устанавливать эту батарейку, то посадите плюсовой провод на корпус, иначе часы просто не пойдут.

Микроконтроллер прошиваем программатором или с помощью 5 проводков.

*Прошивка* (скачиваний: 1414)

Автор прошивки специально для удобства (за что ему спасибо) и не стал изменять заводские фьюзы, что очень сильно облегчает, без заморочки, прошивку для начинающего радиолюбителя. Если МК еще не использовался, новый из магазина, то просто заливаете прошивку и все, но если уже есть изменения в фьюзах, то надо выставить их так CKSEL=0001. Все остальное просто и не нуждается в пояснении.

Пункт 3. Сборка.

Для корпуса очень удобно использовать распаечные коробки из пластмассы, они бывают разных размеров и форм.




В прорезанную ножом крышку, при помощи термоклея из пистолета, закрепляем LCD экран., прорезаем отверстия под кнопки управления и кнопку питания.



Подрезаем выступающий клей.

Общие сведения

Этот вариант Arduino-контроллера, если уж не самый простой, то уж наверняка самый доступный для самостоятельного изготовления. В основе - уже ставшая классической схема Arduino на контроллере ATMega8.

Всего разработано два варианта:

  • Модульный
  • Одноплатный

Модульный вариант

Этот вариант контроллера состит из трех плат:

Одноплатный вариант

Все тоже самое, только на одной плате:

Плата выполнена из одностороннего фольгированного текстолита и может быть повторена в домашних условиях с использованием, наприрмер, ЛУТ-технологии. Размеры платы: 95x62

Программирование микроконтроллера

После сборки платы - необходимо "прошить" контроллер, загрузить в него "bootloader" - загрузчик. Для этого потребуется программатор. Берем чистый контроллер типа ATMega8, устанавливаем его в программатор, подключаем к компьютеру. Я использовал программатор Программатор AVR ISP mkII c адаптером ATMega8-48-88-168 . Программируем с помощью Arduino IDE, она сама выставит необходимые fuse bits. Последовательность такая:

1. Выбор программатора (Сервис > Программатор > AVRISP mkII). Если этот программатор используется впервые - необходимо установить драйвер AVRISP-MKII-libusb-drv.zip . Если используется не AVRISP mkII, а другой программатор, то из списка нужно выбрать нужный.

2. Выбор платы для микроконтроллера (Сервис > Плата > Arduino NG or older w/ ATmega8). Если используется не ATmega8, а другой микроконтроллер, то и платку нужно выбирать соответствующую ему.

3. Запись bootloader (Сервис > Записать загрузчик).

4. Устанавливаем контроллер на плату, и все, Arduino готова к работе.

Проекты на АТMega8.

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

Для работы вам понадобится как минимум CodeVision AVR2.04.4a и Proteus 7.2 SP6. Если желаете поработать с "железом", вам понадобится и программатор. Советую вот такой - легко собирается, хорошо работает. Единственная проблема с первоначальной прошивкой ATMega8, это можно сделать либо через порт LPT - 5-provodov-avr , либо купить "зашитый" микроконтроллер, я брал .


Светофор №1.

Простейший светофор на одно направление не требует для создания больших усилий и навыков. Схема собирается за несколько минут. Резисторы подбираются исходя из используемых светодиодов (номинал 470 Ом указан для "советских" АЛ307), следует заметить, что на схеме вывод AVCC подключен к питанию, если его не подключить на реальном микроконтроллере независимо от использования встроенного АЦП (аналого-цифрового преобразователя), то можно вывести микросхему из строя (справедливо для любых контроллеров серии Mega)!!!

Исходный код настолько простой, что я его представлю прямо здесь. Этот код для Си я нашёл в интернете и немного подправил, однако, любой программист скажет вам, что этот код является бестолковым (далее я опишу, как именно требуется писать такие программы), но зато - простым, наглядным и рабочим.

Chip type: ATmega8
Program type: Application

Memory model: Small
Data Stack size: 256


#include

#include

void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x00;

// Port C initialization
PORTC=0x00;
DDRC=0x00;

// Port D initialization
PORTD=0x00;
DDRD=0x07;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;


// Analog Comparator: Off

ACSR=0x80;
SFIOR=0x00;

while (1) {

PORTD.2=1; //зеленый загорается
delay_ms(8000); //горит 8 секунд


delay_ms(500); //Ждем пол секунды


PORTD.2=0; //Выключаем зеленый

PORTD.2=1; //Включаем зеленый

/*delay_ms(500);//Ждем полсекунды
PORTD.2=0; //Выключаем зеленый
delay_ms(500); //Ждем полсекунды
PORTD.2=1; //Включаем зеленый
delay_ms(500); //Ждем полсекунды*/

PORTD.1=1; //Включаем жёлтый
PORTD.2=0; //Выключаем зеленый
delay_ms(3000); //Ждем 3 секунды

PORTD.0=1; //Включаем красный
PORTD.1=0; //выключаем жёлтый
delay_ms(9000); //на 9 секунд

PORTD.1=1; //включаем жёлтый к красному
delay_ms(3000); //ждем 3 секунды
PORTD.0=0; //Выключаем красный
PORTD.1=0; //и жёлтый
};
}

Код можно ещё несколько сократить, если учесть, что по умолчанию практически все порты и регистры ATMega8 инициализированы в 0. Теперь для начинающих некоторые пояснения:

#include

#include

Это так называемые заголовочные файлы, в них написаны процедуры, которые мы применим из других файлов. Например, процедура delay_ms(X), которая определяет задержку в миллисекундах, была написана другим человеком и содержится в файле delay.с (на самом деле всё может быть не совсем так, или совсем не так, - процедуры может содержать объектный файл типа *.obj, *.asm), а правила её применения описаны в файле delay.h, который мы подключаем.

PORTB=0x00;
DDRB=0x00;

Зарезервированные имена, обозначающие регистры порта контроллера (его ножки сгруппированные байтом - по 8, каждый бит регистра порта соответствует своей ножке) и регистры направления обмена порта (0-вход, 1-выход)

Например, запись DDRB.5=1 означает что ножка PB5 контроллера настроена на выход, и при записи PORTB.5=0 или =1, на данной ножке получим 0 (0...0.8 Вольта) или 1 (4...5 Вольт). Разумеется, можно и сразу целиком присвоить значение порту: PORTB=0xFF, т.е. все ножки порта PB равны 1.

while(1) {expression};

представляет собой бесконечный цикл, так как 1=TRUE.

Светофор №2.


Чтобы получить светофор на два направления, надо модифицировать схему светофора №1:


и код светофора №1:

/*****************************************************
Chip type: ATmega8
Program type: Application
AVR Core Clock frequency: 1.000000 MHz
Memory model: Small
External RAM size: 0
Data Stack size: 256
*****************************************************/

#include
#include

void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x00;

// Port C initialization
PORTC=0x00;
DDRC=0x00;

// Port D initialization
PORTD=0x00;
DDRD=0b00111111;

ACSR=0x80;
SFIOR=0x00;

while (1)
{
PORTD.2=1; //зеленый1 загорается Z1
PORTD.3=1; //красный2 загорается K2
delay_ms(8000); //зеленый1 горит 8 секунд

PORTD.2=0; //выключаем зеленый1 ZM1
delay_ms(500); //ждем пол секунды

delay_ms(500); //ждем полсекунды

delay_ms(500); //ждем полсекунды
PORTD.2=1; //включаем зеленый1
delay_ms(500); //ждем полсекунды

PORTD.1=1; //включаем оранжевый1 J1 K2+J2
PORTD.4=1; //включаем оранжевый2
PORTD.2=0; //выключаем зеленый1


PORTD.0=1; //включаем красный1 K1
PORTD.5=1; //включаем зеленый2 Z2
PORTD.1=0; //выключаем оранжевый1
PORTD.4=0; //выключаем оранжевый2
PORTD.3=0; //выключаем красный2
delay_ms(8000); //ждём 8 секунд

PORTD.5=0; //выключаем зеленый2 ZM2
delay_ms(500); //ждем полсекунды

delay_ms(500); //ждем полсекунды

delay_ms(500); //ждем полсекунды
PORTD.5=1; //включаем зеленый2
delay_ms(500); //ждем полсекунды

PORTD.1=1; //включаем оранжевый1 к красному1 K1+J1
PORTD.4=1; //включаем оранжевый2 J2
PORTD.5=0; //выключаем зеленый2
delay_ms(2000); //ждем 2 секунды
PORTD.0=0; //Выключаем красный1
PORTD.1=0; //и оранжевый1
PORTD.4=0; //и оранжевый2
};
}

комментарии по коду:

DDRD=0b00111111; //0b(b7)(b6)(b5)(b4)(b3)(b2)(b1)(b0)

Справа битовое(двоичное) представление числа в котором слева - самый старший разряд, его же можно было записать в десятичном (DDRD=63;) или в шестнадцатиричном виде (DDRD=0x3F;).

void main(void)

Main главная процедура, с неё начинается выполнение программы, void означает буквально ничего (нулевой тип), вместо void можно подставить (signed или unsigned) int, long; float, double и так далее (и даже указатель на другую переменную, о чём будет рассказано позже). Причём замена void на какой-либо тип в первой позиции обозначает что данная конструкция - функция, а не процедура, и может возвращать значение, т.о. она должна быть дополнена внутри словом return .

int fun(void) {
int a=10;
return(a);
}

Все изменения производились согласно диаграмме работы:


Диаграмма работы светофора на два направления с мигающим зелёным сигналом. Данная диаграмма взята также с просторов интернета, и по-моему: миганий зелёного сигнала должно быть больше.



Светофор №3.


В примерах №1 и №2 было указано на несколько "прямолобое" применение кода, которое позволительно для небольших программ, однако не может быть применено из-за расточительности ресурсами в больших приложениях.
Для упрощения и сокращения кода в технологических применениях программисты обычно используют автоматы. Автомат является упрощённой и достаточной моделью процесса. Например, всю работу светофора можно разбить на некоторое конечное число состояний, которые будут повторятся с некоторым периодом. Для представления автомата потребуется программный счётчик состояний и дешифратор состояний. Светофор №3, который состоит из транспортного светофора на 4 направления, 4-х пешеходных светофоров, 1-го железнодорожного для переезда, 1-го мигающего пешеходного, было бы проблематично создать без автомата.


Код без обработки пешеходных и ж/д светофоров приведен ниже. Несложно понять что процедуры типа
void SetRedT1(void) //Транспортный светофор1 включить красный D3
{
ptc|=0x01;
}
устанавливают либо стирают отдельные биты.

В главном цикле значение счётчика i постоянно увеличивается пока не достигнет 48.
i++;
При этом счётчик обнуляется.
if (i==48) {i=0;}; // 24c=0.5*48

В цикле постоянно происходит сравнение значения счётчика с константами, и производится работа с портами. Хоть данный код и более совершенный, чем предыдущие два, но он также более подходит для наглядности чем для работы. Профессионалы чаще всего не используют наборы отдельных операций сравнения, а пользуются операторами switch-case, или вовсе записывают заранее рассчитанные данные в массивы - пользуются готовой таблицей:

flash unsigned char sw[N]={
//G1Y1R1G2Y2R2 XX
0b10000100, //1 Х периодов горят Зелёный1 и Красный2
0b10000100, //2
...
0b00000100, // Х периодов Зелёный1 мигает,

0b10000100, //
...
0b01001100, //K-1 Зелёный1 гаснет, загораются Жёлтый1 и Жёлтый2
0b00110000, //K Загорается Красный1, загорается Зелёный1, гаснут Жёлтый2 и Красный2

...
0b01101000 //N
};

while (1)
{
i++;


PORTC=(sw[i]>>x) | mask;
PORTD=(sw[i]>>x) | mask;
delay_ms(500);
};
}

Разумеется, выражения (sw[i]>>x) | mask описаны условно, всё зависит от положения информации о сигналах в константе sw.

/*****************************************************
Chip type: ATmega8
Program type: Application
AVR Core Clock frequency: 1.000000 MHz
Memory model: Small
External RAM size: 0
Data Stack size: 256
*****************************************************/

#include
#include

unsigned char ptb=0;
unsigned char ptc=0;
unsigned char ptd=0;

void SetRedT1() //Транспортный светофор1 включить красный D3
{
ptc|=0x01;
}

void ResetRedT1() //Транспортный светофор1 выключить красный D3
{
ptc&=~0x01;
}

void SetYelT1() //Транспортный светофор1 включить жёлтый D2
{
ptc|=0x02;
}

void ResetYelT1() //Транспортный светофор1 выключить жёлтый D2
{
ptc&=~0x02;
}

void SetGrnT1() //Транспортный светофор1 включить зелёный D1
{
ptc|=0x04;
}

void ResetGrnT1() //Транспортный светофор1 выключить зелёный D1
{
ptc&=~0x04;
}

void SetRedT2() //Транспортный светофор2 включить красный D6
{
ptc|=0x08;
}

void ResetRedT2() //Транспортный светофор2 выключить красный D6
{
ptc&=~0x08;
}

void SetYelT2() //Транспортный светофор2 включить жёлтый D5
{
ptc|=0x10;
}

void ResetYelT2() //Транспортный светофор2 выключить жёлтый D5
{
ptc&=~0x10;
}

void SetGrnT2() //Транспортный светофор2 включить зелёный D4
{
ptc|=0x20;
}

void ResetGrnT2() //Транспортный светофор2 выключить зелёный D4
{
ptc&=~0x20;
}


void SetRedT3() //Транспортный светофор3 включить красный D9
{
ptd|=0x01;
}

void ResetRedT3() //Транспортный светофор3 выключить красный D9
{
ptd&=~0x01;
}

void SetYelT3() //Транспортный светофор3 включить жёлтый D8
{
ptd|=0x02;
}

void ResetYelT3() //Транспортный светофор3 выключить жёлтый D8
{
ptd&=~0x02;
}

void SetGrnT3() //Транспортный светофор3 включить зелёный D7
{
ptd|=0x04;
}

void ResetGrnT3() //Транспортный светофор3 выключить зелёный D7
{
ptd&=~0x04;
}


void SetRedT4() //Транспортный светофор2 включить красный D12
{
ptd|=0x08;
}

void ResetRedT4() //Транспортный светофор2 выключить красный D12
{
ptd&=~0x08;
}

void SetYelT4() //Транспортный светофор2 включить жёлтый D11
{
ptd|=0x10;
}

void ResetYelT4() //Транспортный светофор2 выключить жёлтый D11
{
ptd&=~0x10;
}

void SetGrnT4() //Транспортный светофор2 включить зелёный D10
{
ptd|=0x20;
}

void ResetGrnT4() //Транспортный светофор2 выключить зелёный D10
{
ptd&=~0x20;
}

// Declare your global variables here

void main(void)
{
unsigned char i=0;

PORTB=0x00;
DDRB=0xFF;
PORTC=0x00;
DDRC=0xFF;
PORTD=0x00;
DDRD=0xFF;
ACSR=0x80;

while (1)
{
if (i==0) {ResetYelT1();ResetRedT1();SetGrnT1();
ResetYelT2();SetRedT2();
ResetYelT3();ResetRedT3();SetGrnT3();
ResetYelT4();SetRedT4();

}; //0s
if (i==16) {ResetGrnT1();
ResetGrnT3();

}; //8s
if (i==17) {SetGrnT1();
SetGrnT3();

};
if (i==18) {ResetGrnT1();
ResetGrnT3();

};
if (i==19) {SetGrnT1();
SetGrnT3();

};
if (i==20) {ResetGrnT1();SetYelT1();
SetYelT2();
ResetGrnT3();SetYelT3();
SetYelT4();

}; //10s
if (i==24) {ResetYelT1();SetRedT1();
ResetYelT2();ResetRedT2();SetGrnT2();
ResetYelT3();SetRedT3();
ResetYelT4();ResetRedT4();SetGrnT4();

}; //12s
if (i==40) {ResetGrnT2();
ResetGrnT4();

}; //20s
if (i==41) {SetGrnT2();
SetGrnT4();

};
if (i==42) {ResetGrnT2();
ResetGrnT4();

}; //21s
if (i==43) {SetGrnT2();
SetGrnT4();

};
if (i==44) {SetYelT1();
ResetGrnT2();SetYelT2();
SetYelT3();
ResetGrnT4();SetYelT4();

}; //22s
i++;
if (i==48) {i=0;}; // 24c=0.5*48 - цикл

//PORTB=ptb;
PORTC=ptc;
PORTD=ptd;
delay_ms(500);
};
}

Столбчатый индикатор.

Если в предыдущих примерах использовались цифровые ресурсы микроконтроллера, то данный пример использует аналоговые - АЦП. Аналого-цифровой преобразователь предназначен для дискретных преобразований аналогового сигнала в цифровой код с определённой частотой дискретизации. Для начинающих скажу лишь, что максимальная скорость оцифровки ограничена.

Столбчатый индикатор отображает входное напряжение в виде столбца светящихся сегментов (или просто отдельных излучателей), что очень полезно для всяких индикаторов, примерами могут являться столбчатые индикаторы уровня записи (ИУЗ).

Входное напряжение не должно превышать напряжение питания, и в качестве опорного напряжения используется источник питания микроконтроллера на 5 вольт, в качестве фильтра используется внешний конденсатор на выводе AREF.

Код программы приведен ниже:

/*****************************************************
Chip type: ATmega8
Program type: Application
AVR Core Clock frequency: 4.000000 MHz
Memory model: Small
External RAM size: 0
Data Stack size: 256
*****************************************************/

#include
#include

#define ADC_VREF_TYPE 0x40 //5V Vcc + C 4.7uF AREF

//PD0 LED1
//PD1 LED2
//PD2 LED3
//PD3 LED4
//PD4 LED5
//PD5 LED6
//PD6 LED7
//PD7 LED8
//PB0 LED9
//PB1 LED10
//PB2 LED11
//PB3 LED12
//PB4 LED13
//PB5 LED14

//PC4 LED15
//PC5 LED16

const
unsigned char PD=
{
0b00000000, //0
0b00000001, //1
0b00000011, //2
0b00000111, //3
0b00001111, //4
0b00011111, //5
0b00111111, //6
0b01111111, //7
0b11111111, //8
//_____________
0b11111111, //9
0b11111111, //10
0b11111111, //11
0b11111111, //12
0b11111111, //13
0b11111111, //14
0b11111111, //15
0b11111111 //16
};
unsigned char PB=
{
0b00000000, //0
0b00000000, //1
0b00000000, //2
0b00000000, //3
0b00000000, //4
0b00000000, //5
0b00000000, //6
0b00000000, //7
0b00000000, //8
//_____________
0b00000001, //9
0b00000011, //10
0b00000111, //11
0b00001111, //12
0b00011111, //13
0b00111111, //14
//_____________
0b00111111, //15
0b00111111 //16
};

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

void ADC_init()
{
// ADC initialization
// ADC Clock frequency: 125.000 kHz
// ADC Voltage Reference: Vcc, cap. on AREF
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x85;
}

void Decode(int signal)
{
PORTD=PD;
PORTB=PB;

if (signal==15) {PORTC |= 0b00010000;PORTC &= 0b11011111;}
else if (signal==16) {PORTC |= 0b00110000;}
else {PORTC &= 0b11001111;}
}

void SetupIO ()
{
// Input/Output Ports initialization
PORTB=0b00000000;
DDRB= 0b00111111;

PORTC=0b00001100;
DDRC= 0b00110000; //PC0,PC1 = ADC0,ADC1, PC2,PC3 setup pins with PUP

PORTD=0x00;
DDRD=0xFF;
}

void main(void)
{
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

SetupIO();
ADC_init();

while (1)
{
Decode(read_adc(0)*0.049*0.32);
delay_ms(100);
};
}

Практически все приёмы, используемые в данном коде, были рассмотрены выше. Единственно хотелось бы отметить расширенную конструкцию с оператором if:
if () {} //если (условие соблюдается) то { }
else if () {} //иначе если (условие соблюдается) то { }
else {} //иначе { }

И выражение read_adc(0)*0.049*0.32
дело в том, что АЦП выдаёт свои значения по шкале 0-1023 (2^10), что соответствует шкале 0-5 вольт (т.к. опорное напряжение 5 вольт), а нам нужно получить сначала вольты, а потом перевести в количество сегментов. 1024*0.049*0.32=16 т.е. вся шкала АЦП, это 16 сегментов.
Число 0.049 взято кратным числу 5 вольт /1024 отсчёта =0.0048828 (~10 отсчётов АЦП), а потом домножено на 0.32 экспериментальным методом, чтобы получить зажигание последнего сегмента при нужном входном напряжении.



Последовательный порт.

А теперь предлагаю окунуться в мир интерфейсов. Самый простой и широко используемый до недавних пор последовательный протокол RS232, хоть и считается устаревшим, но всё ещё входит в состав выпускаемых современных микроконтроллеров - и не в количестве одного, как правило теперь их не менее 4-х. Также, многие устройства, всё еще используют данный интерфейс (например, некоторые экраны VFD NoritakeItron, медленные устройства для производств и т.п.). Данный пример позволяет оценить, насколько легко и просто настроить и использовать RS232 (USART) в микроконтроллерах.


Ниже приведен код, который осуществляет передачу символа 0.

/*****************************************************
Chip type: ATmega8
Program type: Application
AVR Core Clock frequency: 1.000000 MHz
Memory model: Small
External RAM size: 0
Data Stack size: 256
*****************************************************/

#include

// Standard Input/Output functions
//#include

#define BAUDRATE 57600
#define BaudValue ((11059200UL/(BAUDRATE*16UL))-1)

void USART_Transmit(unsigned char data)
{
//{while (!(UCSRA & (1<
UDR = data;
while(!(UCSRA & (1<
//UDR = data; //Начало передачи данных
}

void USART_init(void)
{
UBRRH = BaudValue >> 8;
UBRRL = BaudValue & 0xFF;
//
UCSRB=(1<
DDRD=0x02;
UCSRC = (1<
//UCSRA = (1<
}

void main(void)
{
ACSR=0x80;
SFIOR=0x00;
USART_init();
while (1) { USART_Transmit(0x30); };
}


Учтите, что Proteus не поддерживает эмуляцию UCSRC (установка параметров связи порта), поэтому установите частоту генератора 3500000, а в терминале поставьте следующие параметры:




Здравствуйте, датагорцы!

После публикации моей первой статьи, меня завалили вопросами о микроконтроллерах, как, что, куда, почему…

Чтобы вы смогли разобраться, как этот чёрный ящик работает, я расскажу вам, о микроконтроллере (далее МК) ATmega8. В принципе фирма Atmel выпускает целую серию МК семейства AVR – это подсемейства Tiny и Mega. Я не буду расписывать достоинства тех или иных МК, это уж вам решать, что вам больше всего подходит. Некоторые представители большой семьи:

Итак, ATmega8, самый простой МК из всех ATmega:

Начнем изучать внутренности по упрощенной структурной схеме:

Это обобщённая схема всех ATmega.

Все микроконтроллеры AVR построены по так называемой Гарвардской архитектуре, то есть использована раздельная адресация памяти программ и памяти данных. Преимущества этой архитектуры заключаются в повышенном быстродействии, например ATmega выполняет одну инструкцию за один тактовый импульс, то есть при частоте 16МГц МК выполняет 16 миллионов операций в секунду.

А теперь о требухе по порядку.
1. Тактовый генератор выполняет синхронизацию всех внутренних устройств.
2. ПЗУ – постоянное запоминающее устройство, используется для хранения программы и неизменяемых данных (констант).
3. Дешифратор команд – он тут самый главный, управляет всем, что ему под руку попадётся.
4. АЛУ – арифметико-логическое устройство, выполняет арифметические (сложение, вычитание и т.д.) и логические (И, ИЛИ, НЕ, Исключающее ИЛИ) операции над числами.
5. РОН – регистры общего назначения, ими АЛУ оперирует, а так же используются для временного хранения данных. Регистры РОН могут объединяться в регистровые пары:
r26: r27 – X;
r28: r29 – Y;
r30: r31 – Z.

Регистровые пары используются для косвенной адресации данных в ОЗУ.
6. ОЗУ – оперативное запоминающее устройство, используется для хранения данных, массивов и стека.
7. PORTA-PORTn – связь с внешним миром, порты ввода/вывода, ну енто понятно для чего…
8. Спец. УВВ – специальные устройства ввода/вывода, контроллеры разной периферии, например USART (по другому СОМ-порт), иногда USB, АЦП, ЦАП, I2C, короче, чего только там нет…

Ну да это всё теория, а вам не терпится что-то склеить, попробовать, и чтобы енто дело работало! Тогда перечислим что нам нужно:

1. Программатор с соответствующим софтом, об этом я писал в прошлой статье;
2. Компилятор языка Си, Code Vision AVR, имеет неплохой инструментарий для разработки программ для МК;

Перед тем как начать программирование на Си, неплохо бы ознакомиться с какой-нибудь литературой по этому языку, например есть замечательная книга Кернигана и Ритчи «Язык С».

Ну да ладно, начнём…

Тестовая схема.

Давайте соберём такую схему:

Это будет базовая модель. Кстати схему лучше собрать на макетной плате, а МК сунуть в панельку. Но такая схема бессмысленна. Добавим, например, светодиод, и не забудем про токоограничивающий резистор. Подключим его к нулевому выводу порта В.
Схема будет иметь следующий вид:

Включим питание… НОЛЬ!!! А что вы хотели без программы?
Значит…

Пишем программу!

Итак, вы запустили CVAVR, что нужно сделать первым делом? Запускаем мастер Code Wizard AVR, нажав на кнопочку с шестерёнкой в панели инструментов, появится окно мастера:

Здесь выбираем тип МК и тактовую частоту. Далее переходим на вкладку Ports:

И настраиваем, какой бит какого порта у нас будет настроен на ввод или вывод, порт В бит 0 у нас будет выдавать сигнал, а остальные принимать.
Чтобы сохранить настройки выбираем меню File / Generate Save and Exit, вводим имена файлов на все последующие запросы, желательно чтобы они были одинаковые, ну например «prj». Всё, мы сгенерировали исходный текст программы с установками заданными в мастере.

Давайте посмотрим что у нас вышло. Первые 22 строки это комментарий, то есть на действия программы он не имеет никакого влияния, таким образом, всё, что находится между «/*» и «*/» является комментарием, и компилятор всё это дело игнорирует. В 24 сроке у нас подключается заголовочный файл, в нём описано как какие регистры называются и по какому адресу находятся. Для программирования на Си подробности здесь излишни.
С 28 строки у нас начинается основная программа определением функции main() ,

Прокрутим ниже. Обратите внимание на строки 36 и 37, здесь присваивается значение порту В и выбирается направление передачи. Вообще наглядно это выглядит так:

То есть, если в какой-нибудь бит регистра DDRB записать единичку, то соответствующий бит порта В будет работать на вывод. В нашем случае это бит 0.
Кстати, у портов в ATmega есть одна приятная особенность, даже если порт настроен на ввод, а в регистр PORTx записать единички, то подключатся внутренние подтягивающие резисторы к плюсу питания, что исключает использование внешних навесных резисторов. Это удобно при подключении всяких датчиков и кнопок.

Скомпилируем программу, для этого нажмём кнопочку Make the Project, или через меню Project / Make. Ошибок быть не должно, если вы что-нибудь не подправили.

Откроем папку C:\cvavr\bin\, найдём там файл prj.hex. Это и есть скомпилированная нами программа для МК. Подключим программатор к ПК и МК. Запустим программу Pony Prog и перетащим в её окно файл prj.hex. Включите питание МК и залейте в него нашу программу… Опять ничего? А проблема в том что мы ничего на нулевой разряд порта В не вывели, вернее вывели, только это ноль. А чтобы наш светодиод загорелся, надо вывести единицу. Так и сделаем, заменим в 36 строке «PORTB=0x00;» на «PORTB=0x01;». Скомпилируем заново программу. А в программе Pony Prog перезагрузим файл при помощи сочетания клавиш Ctrl+L или меню File / Reload Files. Сотрём МК и снова зальём «прошивку» в него. УРА!!! ОНО РАБОТАЕТ!!!

Кстати, Pony Prog поддерживает скрипты, и чтобы не мучаться с перезагрузкой, стиранием и записью, можно просто написать скрипт с расширением.e2s, и обозвать его, например, prog.e2s. Сделать это можно с помощью блокнота. Содержимое у него будет такое:

SELECTDEVICE ATMEGA8
CLEARBUFFER
LOAD-ALL prj.hex
ERASE-ALL
WRITE-ALL

Поместить скрипт следует в одну папку с.hex-файлом, и запускать его двойным щелчком мыши. Можно поместить ярлык на рабочий стол, это уж кому как удобно…

Продолжение следует…

Понравилась статья? Поделитесь ей
Наверх