Современные информационные
технологии/Компьютерная инженерия
Мясищев А.А.
Хмельницкий национальный
университет, Украина
Использование
контроллеров AVR
для управления технологическим оборудованием через TCP/IP сети
Компьютерные
сети, построенные на базе стека протоколов TCP/IP в настоящее время, получили
наибольшее распространение в связи с
масштабным развитием Интернет. В связи с этим возникает много задач, связанных
с управлением технологическим оборудованием на расстоянии по компьютерной сети,
снятия показаний с различных датчиков и отображении их на удаленном компьютере-клиенте, анализом этих показаний и на
основании этого введения изменений в работу удаленного оборудования и т.д., а
также другие задачи. Рассмотрим, как можно просто решить подобные задачи с
использованием распространенных, достаточно дешевых микроконтроллеров фирмы ATMEL. В работе используется
микроконтроллер ATmega8, который следствие своей дешевизны и функциональности
широко распространен на Украине.
Для работы устройства
по сети необходим сервер с RS232 интерфейсом, который должен
быть настроен на работу с протоколами TCP/IP. На сервере должен запускаться
демон telnet при обращении к нему с удаленной клиентской машины по telnet и программа по обработке запросов
с COM порта (RS232). Для этих целей в работе
использована операционная системы Unix FreeBSD 7.1-RELEASE, которая удовлетворяет всем
представленным выше требованиям. Она установлена на компьютере с процессором Pentium IV и объемом памяти 256 Мбайт. Предлагаемое
в работе устройство должно решать следующие задачи:
1.По COM порту получать и передавать
команды от компьютера.
2.На основании полученных команд
менять содержимое своих регистров для управления оборудованием, которое к нему
подключено.
3.Снимать показания с датчика температуры
и выводить их на монитор удаленного компьютера и на жидкокристаллический
индикатор (LCD), подключенный непосредственно к микроконтроллеру.
4.По заданному по сети временному интервалу включать и выключать
подключенное к нему оборудование.
5.Измерять текущее напряжение в
электрической сети переменного напряжения и отображать его удаленно по
компьютерной сети и на LCD, подключенного непосредственно к
микроконтроллеру.
6.Выполнять функцию часов,
отображая время, день недели удаленно по сети на клиентский компьютер и на свой LCD. Производить программную
корректировку времени для максимальной точности показаний часов.
Принципиальная схема устройства для
решения определенных выше задач представлена на рис.1.
Рис.1.
В качестве LCD используется индикатор с числом столбцов и строк 16х20 соответственно (LCD 16x20), который поддерживает систему
команд, совместимую с контроллером HD44780 (фирма Hitachi) и его аналогами, например, KS0066 (фирма Samsung), SED1278 (фирма Epson), ST7066 (фирма Sitronix). А для измерения температуры -
цифровой датчик DS18B20 температуры с точностью до
0,0625C (при
разрешающей способности температурного преобразователя 12 бит) и диапазоном от
-55 до +125С. Датчик с микроконтроллером
сопрягается по протоколу 1wire. Для
работы с компьютером через интерфейс RS-232 у микроконтроллера ATmega8 встроен
универсальный асинхронный приемопередатчик (UART) который, согласно рис.1, подключен к компьютеру по нуль-модемному
кабелю (рис.2) через микросхему MAX232,
выполняющую функцию согласования уровней напряжения. Задача заключается лишь в
том, чтобы программно установить режим работы UART (см. листинг программы).
Рис.2.
После включения устройства, на LCD высвечивается время, день недели,
температура (рис.3). Это автономный режим работы.
Рис.3.
Как отмечалось устройство
можно подключить к COM порту удаленного сервера. Если
используется операционная система Unix FreeBSD, то на сервере должен быть открыт
доступ по telnet. Также должно быть установлено устройство cuaa0, которое обеспечивает работу с
последовательным портом (в данном случае с COM1). Для подключения к устройству с клиентской
машины и управления им необходимо по telnet выполнить подключение к удаленному
серверу:
telnet server.tup.km.ua
После авторизации запустить команду
cu -l
cuaa0 –s 9600
Далее нажать клавишу «пробел» и на
экране появляется приглашение
Enter time
После него необходимо ввести время
в формате «ччмм». После ввода на экране LCD появиться другой формат вывода,
представленный на рис.4. Здесь в первой строке выводится время и температура, а
во второй – время начала срабатывания исполнительного механизма, время конца
его срабатывания, напряжение в осветительной сети. Дальнейший диалог
взаимодействия можно проследить по листингу программы, в котором даны подробные
комментарии.
Рис.4.
Для
определения напряжения используется встроенный в микроконтроллер
аналого-цифровой преобразователь (АЦП) 10 битной точности. Преобразованные
после измерения напряжения помещаются в регистры ADCH (старшие 2 бита) и ADCL (младшие 8 битов). Источником опорного уровня Vref здесь служит напряжение питания AVCC. В этом случае диапазон измеряемых
напряжений составляет 0…5В с интервалом изменения 5мВ.
В процессе работы АЦП
может функционировать в режимах однократного или непрерывного измерений. В
однократном режиме результат появляется через 65…260 мкс, например, после
нажатия на кнопку. Измерения в непрерывном режиме не требуют перезапуска,
результат можно прочитать в любой момент времени, однако обновление показаний
также будет происходить через 65…260 мкс. Установка режимов производится
записью байтов в два регистра: ADMUX (Analog-to-Digital MUlti-pleXer) и ADCSRA (Analog-to-Digital Control and Status Register A). В таблице 1 [1] собраны команды
на языке Си, которые отвечают за тот или иной режим АЦП.
Таблица
1
В
устройстве АЦП настроен для работы в режиме непрерывного измерения. Согласно
листингу программы производится непрерывный замер на конденсаторе 0.1мк выпрямленного диодом IN4007 напряжения c интервалом примерно 1мс. Так как
напряжение изменяется в пределах периода колебаний сети(~50Гц) то рассчитывается среднее напряжение
несколько раз. Для преобразования выпрямленного после трансформатора напряжения
в действительные напряжения осветительной сети, полученные значения умножались
на коэффициенты 65.8 и 65.3, которые были получены при сравнении найденных
напряжений по эталонному вольтметру.
Рассмотрим
программирование LCD индикатора. Для индикации данных на экране необходимо, чтобы
микроконтроллер посылал по правилам, определенным контроллером
индикатора, соответствующие команды и синхронизирующие импульсы. Сигнал RS должен быть установлен в 0, когда
необходимо в LCD передать команды, и в 1 – при передаче данных. Поэтому в листинге
программ выделяются две функции: lcd_com
– запись команд и lcd_dat – запись данных. По перепаду сигнала EN с 1 в 0 выполняется запись в LCD команды. Сигнал RD равен 0 при записи данных в LCD и 1 при чтении данных с LCD. Так как данные для устройства
всегда записываются в LCD, вывод RD занулен. В таблице 2 представлены
некоторые команды LCD на базе HD44780,
которые используются в программе.
Таблица 2
Команды LCD |
HEX код |
Время
выполнения в мкс |
Очистка
дисплея |
0x01 |
1640 |
Возврат
курсора в начало |
0x02 |
1640 |
Сдвиг
курсора вправо |
0x06 |
40 |
Выключение
дисплея |
0x08 |
40 |
Интерфейс
связи 8 бит, 1 строка на дисплее |
0x30 |
40 |
Интерфейс
связи 4 бит, 1 строка на дисплее |
0x20 |
40 |
Выключение
курсора |
0x0C |
40 |
Интерфейс
связи 4 бит, 2 строки на дисплее |
0x28 |
40 |
Из таблицы 2 видно, что LCD может использовать две ширины
интерфейса связи – 8 бит и 4 бита. Согласно рис.1 LCD подключен к микроконтроллеру по
шине связи шириной 4 бита. Поэтому байты необходимо передавать двумя порциями.
На рис.5 показаны временные диаграммы выполнения команды 0xC0 “Установка курсора в первое
знакоместо второй строки экрана” и индикация в нем буквы “Д” пересылкой команды
0xE0.
Рис.5
В
листинге программы в соответствии с рис.5 представлены отдельно функция
передачи команд (lcd_com, RS=0), функция передачи данных (lcd_dat, RS=1) и функция инициализации LCD (lcd_init) согласно DATASHEET на HD44780 http://www.gaw.ru/pdf/lcd/Chips/Hitachi/hd44780u.pdf.
По опыту работы с LCD для вывода информации на экран без
«мусора» необходимо было дополнительно
добавить две команды - lcd_com(0x01) и lcd_com(0x02) (см. листинг программы).
Для программирования
микроконтроллера ATMega8 воспользуемся компилятором языка Си CodeVision AVR фирмы HP InfoTech, Румыния (http://www.hpinfotech.ro/html/cvavr.htm). Рассмотрим последовательно этапы
программирования микроконтроллера для решения представленной выше задачи [2].
Предположим, что пакет CodeVision AVR установлен на компьютере. В работе
в качестве примера используется CodeVision AVR Version
1.25.8 Professional. Перед запуском программы CodeVision AVR создаем каталог, где будут
храниться файлы.
1.
Запускаем
CodeVision AVR и выбераем пункт
CodeWizardAVR:
2.Выбираем тип микроконтроллера и
частоту.
3.Инициализируем шину 1wire и температурный датчик DS1820, хотя по заданию используется
датчик DS18B20.
4. Заходим во вкладку Timers. Выбираем для ATMega8 Timer 1. Выполняем его настройку, как в
работе [2].
5.Выбираем вкладку USART. Устанавливаем режимы его работы,
как показано ниже:
6. Заходим последовательно во
вкладки File
-> Generate, Save and Exit. Даем имена проекту и исходному
файлу. В результате появится окно с текстом программы на языке Си. Корректируем
ее следующим листингом:
// ATmega8 частота 8МГц
#include <mega8.h>
#include <1wire.h>
#include <math.h>
#include <ds18b20.h>
#include <delay.h>
#include <stdio.h>
#include <stdlib.h>
#define VREF 5000
// Напряжение Vref в милливольтах
#define TIME 10 // Базовая задержка при частоте 8МГц
#asm //Вставка ассемблерного кода для снятия показаний с датчика
DS18B20
.equ
__w1_port=0x15 ;PORTC
.equ __w1_bit=3
#endasm
float temp1,volt_ss1; int
m_min=99,h_min=99,m_max=99,h_max=99,iii=0,x;
unsigned int s, m=0, h=0, den=1,
ii=0;
void pause(unsigned int a) // Функция задержки времени,
a-длительность паузы
{ unsigned int cn;
// cn-счетчик времени
for (cn=a;cn>0;cn--);
} // Цикл задержки времени
void lcd_com(unsigned char p) //Функция записи команды LCD,
p-байт команды
{ PORTD.3=0; //
Сигнал RS=0 (Запись команд)
PORTD.2=1; //
Сигнал EN=1
PORTD &= 0x0F; PORTD |= (p & 0xF0); // Установка
старшей части байта
pause(TIME); //
Длительность сигнала EN
PORTD.2=0; //
Сигнал EN=0 - запись старшей части байта в LCD
pause(TIME); //
Длительность сигнала EN
PORTD.2=1; //
Сигнал EN=1
PORTD &= 0x0F; PORTD |= (p << 4); // Установка
младшей части байта
pause(TIME); //
Длительность сигнала EN
PORTD.2=0; //
Сигнал EN=0 - запись младшей части байта в LCD
pause(5 * TIME); } // Пауза для выполнения команды
void lcd_dat(unsigned char p) // Функция записи данных в LCD, p-байт данных
{PORTD.3=1; //
Сигнал RS=1 (Запись данных)
PORTD.2=1; //
Сигнал EN=1
PORTD &= 0x0F; PORTD |= (p & 0xF0); // Установка
старшей части байта
pause(TIME); // Длительность сигнала EN
PORTD.2=0; //
Сигнал EN=0 - запись старшей части байта в LCD
pause(TIME); //
Длительность сигнала EN
PORTD.2=1; //
Сигнал EN=1
PORTD &= 0x0F; PORTD |= (p << 4); // Установка
младшей части байта
pause(TIME); //
Длительность сигнала EN
PORTD.2=0; //
Сигнал EN=0 - запись младшей части байта в LCD
pause(5 * TIME); } // Пауза для выполнения команды
void lcd_init(void) //Функция инициализации LCD
{lcd_com(0x30);delay_ms(5); //Инициализация по DATASHEET на
HD44780
lcd_com(0x30);delay_ms(1); // Инициализация по DATASHEET на
HD44780
lcd_com(0x30); // Инициализация по DATASHEET на HD44780
lcd_com(0x01);// Очистка дисплея (по опыту)
lcd_com(0x02);// Возврат курсора в начало (по опыту)
lcd_com(0x20);// Инициализация по DATASHEET на HD44780
lcd_com(0x28); // 4-е линии данных, двухстрочный LCD
lcd_com(0x08); //
Выключение дисплея
lcd_com(0x01); delay_ms(2); // Очистка дисплея
lcd_com(0x06); // Сдвиг курсора вправо
lcd_com(0x0c);} // Включение дисплея, выключение курсора
// Вызов функции обработки прерывания Timer1
interrupt [TIM1_COMPA] void
timer1_compa_isr(void)
{ int a; char
lcd_t[12],lcd_v[12];
TCNT1H=0;
TCNT1L=0;
s++; // Увеличиваем секунду на 1 в случае
появления
// в регистре A числа 7813(изменено на 7811)
if
(PINC.0==0) // Если нажата кнопка m+
{ m++; } // к числу минуты прибавляется единица
// (для выполнения
установки времени на устройстве локально)
if
(PINC.1==0) // Если нажата кнопка h+
{ h++;} // к числу
часов прибавляется единица
if (PINC.5==0) //
Если нажата кнопка den+
{ den++; } // к
числу дней прибавляется единица
if(s==60) // Если число секунд = 60
{ m++; s=0;} // к
минутам добавляется 1
if(m==60) // Если
число минут = 60
{h++; m=0;} // к часам добавляется 1
if (h==24) // Если число часов = 24
{ den++;h=0;m=0;s=0;} // к дням добавляется 1
if (den==8) // Если число дней = 8
{den=1; h=0;m=0;s=0;ii=0;} // то опять начинаем с 1
(понедельника)
// Корректировка времени (на семь секунд в неделю)
// выполняется в воскресенье в 22 часа 30 минут 30
секунд
if (den==7 && h==22
&& m==30 && s==30 && ii==0) { s=s-7;ii=1;}
DDRD = 0xFC; // Переводим D2...7 в режим вывода
PORTD = 0xF3; // Устанавливаем PD0,PD1, PD4...7 в 1
lcd_init(); // Инициализация LCD
// При нажатии на +lcd переключить формат вывода на LCD
if (PINC.4==0) { if(iii==0) {iii=1; goto ac;} if(iii==1)
{iii=0;} ac: }
// Вывод данных на LCD в формате при включении устройства
// (автономный режим)
if ( iii==0 ) // Выполнить в 1-й строке LCD распечатку по
примеру
// " ВРЕМЯ=10:11:15 "
{lcd_dat(' '); lcd_dat(0x42);lcd_dat(0x70);lcd_dat(0x65);lcd_dat(0xBC);
lcd_dat(0xC7);lcd_dat('=');
lcd_dat(h/10+0x30); lcd_dat(h%10+0x30); lcd_dat(':');
lcd_dat(m/10+0x30); lcd_dat(m%10+0x30); lcd_dat(':');
lcd_dat(s/10+0x30); lcd_dat(s%10+0x30);
lcd_com(0xc0); // Переход на 2-ю строку LCD
// Во 2-й строке LCD распечатать по примеру "День=Пн
t= 28.2C"
lcd_dat(0xE0);lcd_dat(0x65);lcd_dat(0xBD);lcd_dat(0xC4);
lcd_dat('='); if (
den==1 ) {lcd_dat(0xA8);lcd_dat(0xBD);}
if ( den==2 )
{lcd_dat(0x42);lcd_dat(0xBF);}
if ( den==3 )
{lcd_dat(0x43);lcd_dat(0x70);}
if ( den==4 )
{lcd_dat(0xAB);lcd_dat(0xB3);}
if ( den==5 )
{lcd_dat(0xA8);lcd_dat(0xBF);}
if ( den==6 )
{lcd_dat(0x43);lcd_dat(0xB2);}
if ( den==7 )
{lcd_dat(0x42);lcd_dat(0x63);} lcd_dat('
');
// Вывод температуры
sprintf(lcd_t,"t=%5.1fC",temp1); for(a=0;a<12;a++){lcd_dat(lcd_t[a]);}
// Каждую секунду выполнять опрос температурного датчика
temp1=ds18b20_temperature(0); }
// Вывод данных на LCD в формате после ввода времени
// с клавиатуры удаленного компьютера (удаленный режим)
else {
// Выполнить в 1-й строке LCD распечатку по примеру
// "10:12:12 t=
28.2"
lcd_dat(h/10+0x30);
lcd_dat(h%10+0x30);
lcd_dat(':');
lcd_dat(m/10+0x30);
lcd_dat(m%10+0x30);
lcd_dat(':');
lcd_dat(s/10+0x30); lcd_dat(s%10+0x30);
lcd_dat(' '); sprintf(lcd_t,"t=%5.1f",temp1);
for(a=0;a<12;a++){lcd_dat(lcd_t[a]);}
lcd_com(0xc0); // Переход на
2-ю строку LCD
// Выполнить во 2-й строке LCD распечатку по примеру
// "1030 1100 U=
221"
lcd_dat(h_min/10+0x30);lcd_dat(h_min%10+0x30);
lcd_dat(m_min/10+0x30);lcd_dat(m_min%10+0x30);
lcd_dat(' ');lcd_dat(h_max/10+0x30);lcd_dat(h_max%10+0x30);
lcd_dat(m_max/10+0x30);lcd_dat(m_max%10+0x30);
lcd_dat('
');
// Распечатка напряжения
sprintf(lcd_v,"U=%4.0f",volt_ss1); for(a=0;a<12;a++){lcd_dat(lcd_v[a]);} } }
// ---Основная программа-----
void main(void)
{ float
volt1[55],volt_s[11],volt_ss;
char
ho[2],mi[2],m_min1[2],h_min1[2],m_max1[2],h_max1[2];
int prin1,usl=0,i,j,ii; unsigned long volt[55];
// Port C initialization
PORTC.0=1; PORTC.1=1; PORTC.4=1;
PORTC.5=1; DDRC=0x00;
// Timer/Counter 0
initialization
TCCR0=0x00; TCNT0=0x00;
// Timer/Counter 1
initialization
TCCR1A=0x00; TCCR1B=0x05; TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00; ICR1L=0x00;
OCR1AH=0x1E; // Частота работы таймера
OCR1AL=0x83; // скорректирована на 7,811(0x1E83)
OCR1BH=0x00; OCR1BL=0x00;
// Timer/Counter 2
initialization
ASSR=0x00; TCCR2=0x00; TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s)
initialization: INT0: Off, INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s)
Interrupt(s) initialization
TIMSK=0x10; //Инициализация таймера
// USART initialization: Communication
Parameters: 8 Data, 1 Stop, No Parity
UCSRA=0x00; UCSRB=0x18; UCSRC=0x86;
UBRRH=0x00; UBRRL=0x33;
// Analog Comparator
initialization
ACSR=0x80; SFIOR=0x00;
#asm("sei") // Глобальное разрешение прерываний
w1_init(); // Инициализация линии 1 wire
DDRB.0=1; // Режим вывода для порта B0 (для исполнительного
устройства)
PORTB=0x00; // Установить B0...7=0
// Устанавливаем режим работы АЦП
ADMUX &= 0xDF &
0x7F & 0xF2; ADMUX |= 0x40 | 0x02;//Разрядность
// 10бит, опорное напряжение AVCC (5В) вольт,
// внутренний источник опорного напряжения, канал PC2
ADCSRA |= 0x80 | 0x40 | 0x20 | 0x07;// Включить АЦП, запуск
нового замера,
// постоянное измерение, частота АЦП=8МГц/128
ac:
// В случае ввода пробела распечатывается "Enter time"
x=getchar(); if (x==32) { printf("\n\rEnter
time:");}
else goto ac;
// Ввод с клавиатуры времени в формате "ччмм"
// Ввод часов
for (i=0;i<=1;i=i+1)
{ho[i]=getchar();putchar(ho[i]);} // Чтение и распечатка
h=atoi(ho); // Преобразование строку в число (часы)
ho[0]=0; // Без обнуления
ho[1]=0; // ввод - вывод работает некорректно
iii=1;
// Ввод минут
for (i=0;i<=1;i=i+1)
{mi[i]=getchar();putchar(mi[i]);}
m=atoi(mi); mi[0]=0; mi[1]=0;
bb: usl=0;
printf("\n\rEnter mode
work:\n\r"); // Ввод с клавиатуры режима работы
// Включение и выключение исполнительного устройства
// с клавиатуры (ручной режим)
printf("1-Manual\n\r");
// Включение и выключение исполнительного устройства
// по установленному времени (автоматический режим)
printf("2-Automatic\n\r");
// Определение переменного напряжения в осветительной сети
printf("3-Voltage\n\r");
prin1=getchar();
if (prin1==50) goto aa; if
(prin1==51) goto cc;
// Ручной режим (клавиши 1,2,3)
printf("1-On\n\r"); printf("2-Off\n\r"); printf("3-Goto
up\n\r");
while(1)
{ prin1=getchar();
temp1=ds18b20_temperature(0); // Снятие температуры с датчика
// Распечатка времени на мониторе компьютера
printf("Time=%02i:%02i:%02i",h,m,s);
printf(" Temp=%f\r",temp1); // Распечатка температуры на мониторе
if (
prin1==49 ) // При вводе 1
{PORTB.0=1; }//
включить исполнительное устройство
if ( prin1==50 ) // При вводе 2
{ PORTB.0=0; } //
выключить исполнительное устройство
if ( prin1==51 ) // При вводе 3
{ goto bb; }//
Перейти на ввод режима работы
}; // при вводе любой клавиши (не 1,2,3)
// будут распечатываться на мониторе время и температура
aa: // Автоматический режим
usl=0;
printf("Enter the time
interval:\n\r");
// Запрос на ввод времени начала срабатывания
// исполнительного механизма в формате, например: 0805 - 8 часов 5 минут
printf("Bottom time(example 1245):");
// Чтение и распечатка часов
for (i=0;i<=1;i=i+1)
{h_min1[i]=getchar();putchar(h_min1[i]);}
h_min=atoi(h_min1); // Пребразовать строку в число
(часы)
// Чтение и распечатка минут
for (i=0;i<=1;i=i+1)
{m_min1[i]=getchar();putchar(m_min1[i]);}
m_min=atoi(m_min1); // Преобразовать строку в число
(минуты)
//Запрос на ввод времени конца срабатывания
// исполнительного механизма в формате, например 0809 - 8 часов
5 минут
printf("\n\rTop
time(example 1246):");
// Чтение и распечатка часов
for (i=0;i<=1;i=i+1) {h_max1[i]=getchar();putchar(h_max1[i]);}
h_max=atoi(h_max1); // Преобразовать строку в число
(часы)
for (i=0;i<=1;i++) //
Обнуление
{h_min1[i]=0;m_min1[i]=0;h_max1[i]=0;m_max1[i]=0;}
// Чтение и распечатка минут
for (i=0;i<=1;i=i+1) {m_max1[i]=getchar();putchar(m_max1[i]);}
m_max=atoi(m_max1); // Преобразовать строку в число
(минуты)
m_max1[0]=0; m_max1[1]=0; printf("\n\r"); // Обнуление
while
(1) {
if ( m==m_min &&
h==h_min ) { usl=1;}
if ( m==m_max &&
h==h_max ) { usl=2;}
temp1=ds18b20_temperature(0);
// Снятие температуры с датчика
// Распечатка времени на мониторе компьютера
printf("Time=%02i:%02i:%02i",h,m,s);
// Распечатка на мониторе температуры
printf("
Temp=%f\r",temp1);
delay_ms(1000);
if
( usl==1 ) // Если время соответствует
началу срабатывания -
{ PORTB.0=1; } // включить исполнительный
механизм
if ( usl==2 ) { // Если время соответствует концу
срабатывания -
PORTB.0=0; // выключить исполнительный механизм
goto bb; } //
Перейти на ввод режима работы
usl=0; };
// Определение переменного напряжения в осветительной сети
cc:
for (ii=0;ii<20;ii++) // Вывод на печать
{ // 20 раз
осредненного напряжения
volt_ss=0.0; for(j=0;j<10;j++)
{ volt_s[j]=0.0;
for(i=0;i<50;i++) { // Цикл измерения напряжения
delay_ms(1);// Для каждого замера выдерживаем паузу в 1
миллисекунду
volt[i]=ADCL; //
Чтение младших 8 битов напряжения
volt[i] +=
((int)ADCH << 8);// Добавление 2-х старших бита напряжения
volt[i]=volt[i]*VREF/1024; // Вычисление напряжения в милливольтах
volt1[i]=volt[i]/1000.0;
// Преобразование в вольты
} // Завершение
цикла измерения напряжения
for(i=0;i<50;i++) // Вычисление суммы измеренных напряжений
{
volt_s[j]=volt_s[j]+volt1[i]; }
volt_s[j]=volt_s[j]/50.0;
// Вычисление среднего напряжения
volt_ss=volt_ss+volt_s[j]; }// Вычисление суммы средних
напряжений
volt_ss=volt_ss/10;
//Вычисление среднего напряжения
// Преобразование
напряжения с трансформаторного выхода в напряжение
// осветительной
сети
if
(volt_ss<=3.05) {volt_ss=volt_ss*65.8; goto ee;}
if
(volt_ss>3.05)
{volt_ss=volt_ss*65.3; goto ee;}
ee: delay_ms(200); volt_ss1=volt_ss;
// Вывод
напряжения на экран монитора
printf("Voltage=%6.0f Volt\r",volt_ss1); };
goto bb; }//
Перейти на ввод режима работы
7.
Выбираем закладку
Project->Configure->C Compile и устанавливаем в поле
(s)printf Features значения
float, width, precision.
8. Компилируем проект командой Compile.
9. Собираем проект командой Make.
В
каталоге, где расположена программы на Си, появится файл с расширением .hex, который необходимо будет
переслать в микроконтроллер с помощью адаптера и программатора. Для этой цели
воспользуемся программой-программатором PonyProg с адаптером для COM порта [2]. С помощью программы PonyProg необходимо установить для
микроконтроллера фьюз-биты (биты
конфигурации). Для этого заходим в закладку Command->Security and Configuration Bits и снимаем в полученном окне все
галочки. Далее пересылаем программу в микроконтроллер.
После
подключения запрограммированного устройства к COM порту, запуска программы терминал
в CodeVision AVR и включении устройства на LCD должна появиться заставка,
подобная представленной на рис.3. При нажатии на клавишу «пробел» на клавиатуре
компьютера на терминале CodeVision AVR появиться строка
Enter time:
Далее необходимо ввести время в формате согласно листингу программы. На LCD заставка преобразуется в вид,
подобный рис.4. Дальнейший ввод данных
понятен из листинга программы и из отображаемого на экране монитора диалога
работы с устройством.
С помощью кнопок m+,
h+, den+, lcd+ можно
управлять устройством в автономном режиме. Для установки минут, часов, дня
недели необходимо удерживать нажатой соответствующую кнопку. При нажатии кнопки
lcd+ меняется формат вывода на LCD индикаторе (рис.3, рис.4).
Выводы.
1.Показан простой способ
использования недорогого и распространенного микроконтроллера ATmega8 для управления технологическим
оборудованием через компьютерную сеть.
2.Используя сетевые возможности
компьютера, представлен способ удаленной
установки работы устройства по таймеру для управления оборудованием.
3. Показана с помощью устройства
возможность передачи на удаленный
компьютер по сети рассчитанного напряжения осветительной сети в районе установки сервера и данных, снятых
с температурного датчика.
4. Недостатком приведенного
устройства является необходимость использования совместно с ним дорогостоящего компьютера, который должен быть
настроен для работы с компьютерной сетью.
Литература.
1. Рюмик С.М. Микроконтроллеры AVR. Ступень 1. http://forum.radiospec.ru/index.php?showtopic=5612 - 2007
2.Мясищев А.А. О практическом использовании
микроконтроллеров AVR. Materialy VI Miedzynarodowej naukowi-praktycznej
konferencji “Naukowa przestrzec Europy - 2010” Volume 17. Nowoczesne informacyjne technologie.:
Przemysl . Nauka I studia – 96 str.