Современные информационные технологии/Компьютерная инженерия

 

Мясищев А.А.

Хмельницкий национальный университет, Украина

Использование контроллеров 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.