Файл: Техническое задание на разработку 14 2 Обоснование выбора инструмента программирования и отладки 15 3 Разработка программной части асу 15.docx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 18.01.2024
Просмотров: 103
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
1.1 Характеристика автоматизированной системы
1.2 Основные решения по автоматизации
1.2.2 Система автоматизации учета, регистрации отпуска и потребления газа.
2.1 Техническое задание на разработку
2.2 Обоснование выбора инструмента программирования и отладки
2.3 Разработка программной части АСУ
Обработчики прерываний
Основная программа представляет собой бесконечный цикл, в котором выполняются все основные функции программы.
Обработчик прерываний 1 предназначен для точного задания с помощью таймера-счётчика промежутков времени для выполнения основных подпрограмм. По переполнению таймера-счётчика TC0 выполнение основной программы приостанавливается и выполняется подпрограмма обработчика прерываний.
Обработчик прерываний 2 предназначен для точного задания с помощью таймера-счётчика ТС1 промежутков времени для выполнения команд обмена информации по интерфейсу 1-Wire.
Таблица 2.1 – Перечень переменных с назначением и диапазон изменений
Переменная | Назначение | Диапазон изменений |
Ttek[] | Массив текущих значений температур | -110 - +250 |
Tlim[] | Массив пределов температур | -109 - +249 |
Talarm[] | Массив срабатывания сигнализаций | -109 - +249 |
Mode | Номер режима интерфейса | 0 - 2 |
Pos1, Pos2, Pos3 | Позиции курсора в разных режимах интерфейса | 0 - 4 |
slog[] | Массив инкрементов для разрядов чисел | 1/2/20 |
Per_Key | Счётчик прерываний обработки ввода с клавиатуры, вывода на ЖКИ | 0 - 255 |
Per_Contr | Счётчик прерываний обработки получения измерений и сигнализации | 0 - 65535 |
Per_Impulse | Счётчик прерываний длительности импульса сброса | 0 - 255 |
keypress | Комбинация нажатой кнопки | 0 - 255 |
i | Счётчик для циклов | 0 - 255 |
Mode_Select | Флаг переключения режима интерфейса | 0/1 |
Err_Off | Флаг отключения сигнализации | 0/1 |
Mig[] | Массив флаг индикации сигнализации | 0/1 |
SerL[] | Массив младших байт серийных номеров термометров | 4 байт |
SerH[] | Массив старших байт серийных номеров термометров | 4 байт |
Таблица 2.2 – Состав и назначение подпрограмм и функций
Название подпрограммы | Функции |
wait_ready | Ожидание сброса флага занятости ЖКИ/ |
write_command | Записать команду в память ЖКИ |
write_data | Записать данныев в память ЖКИ |
send_bit | Отправить бит на термометр |
send_command | Отправить команду на термометр |
read_bit | Прочитать бит с термометра |
read_byte | Прочитать байт с термометр |
init_exchange | Инициализация обмена с термометрами |
Match_ROM | Команда Match ROM интерфеса 1-Wire |
Convert_T | Команда Convert_T интерфеса 1-Wire |
Read_Scratchpad | Команда Read_Scratchpad интерфеса 1-Wire |
cut_number | Вывести на ЖКИ число |
output_string | Вывести на ЖКИ строку |
Init_Device | Инициализация устройств |
Control | Сигнализация выхода за пределы температуры |
Key_Code | Обработка ввода |
Select | Переключение режимов интерфейса |
Display | Обработка вывода на дисплей/ |
Measure | Получение информации о измерениях с термометров |
T0_ISR | Обработка прерываний таймера Т0 |
T1_ISR | Обработка прерываний таймера Т1 |
main | Главная программа |
Текст программы с подробными комментариями
#include
#include
#define DB P2 // DB - синоним к порту P2
#define Buttons P1 // Buttons - синонимкпорту P1
////////////Глобальные переменные//////////////////////////////////
sbit E= P3^2; // E -синоним к контакту P3.2
sbit RW= P3^0; // RW -синоним к контакту P3.0
sbit RS= P3^1; // RS -синоним к контакту P3.1
sbit Error =P3^6; // Error - синонимк P3.6
sbit DQ =P3^7; // DQ - синоним к P3.7
int Ttek[5]; // текущее значение температур
int Tlim[10]; // минимальные пределы температур нечётные, максимальные - чётные
unsigned char Talarm[5]; //флаги срабатывания сигнализации термометра Ti
unsigned char Mode; // выборрежимаменю
unsigned char Pos1; unsigned char Pos2; unsigned char Pos3; // позициикурсоравменю
unsigned char slog[3]={20,2,1}; // инкримет/декремент
unsigned char Per_Key; //счётчикпрерыванийдляобработкиввода
unsigned int Per_Contr; //счётчик прерываний для контроля
unsigned char Per_Impulse; //счётчик прерываний для импульсов
unsigned char keypress=0xFF;
unsigned char i; // счётчикдляциклов
bit Mode_Select; //флагсменырежима
bit Err_Off;// флаг сброса сраьатывания сигнализации
unsigned char Mig[5];// флаг мигания сигнализации термометра Ti
unsigned long int SerL[5]; //массивы младших 4 байт семейства, серийного номера термомтров и контрольных сумм
unsigned long int SerH[5]; //массивы старших 4 байт семейства, серийного номера термометров и контрольных сумм
/////////////////////////////////////////////////////////////////////////
//////////////Ожидание сброса флага занятости ЖКИ//////////////////////////////////
void wait_ready()
{unsigned char BF;//переменная для проверки флага занятости
DB=255; // на порт DB послать 255
do {E=0; // на всякий случай сбросить линию E в 0
RS=0;// линия RS на команды
RW=1;// линия RW на чтение
E=1;//начать чтения
BF=DB;//считать с порта DB в BF
E=0;//закончить чтение
} while (BF&0x80);// пока старший бит BF равен 1
}
///////////////////////////////////////////////////////////////////
//////////////Записать команду в память ЖКИ///////////////////////////////
void write_command(char B)
{wait_ready();//дождаться готовности
RS=0;// линия RS на команды
RW=0;// линия RW на запись
E=1;//начать запись
DB=B;// записать на порт DB число B
E=0;//закончить запись
}
////////////////////////////////////////////////////////////
//////////////Записать данныев память ЖКИ/////////////////////////////
void write_data(char B)
{wait_ready();//дождаться готовности
RS=1;// линия RS на данные
RW=0;// линия RW на запись
E=1;//начать запись
DB=B;// записать на порт DB число B
E=0;//закончить запись
}
////////////////////////////////////////////////////////////
/////////////////Отправить бит на термометр////////////////////////////////////////
void send_bit(bit B)
{
DQ=0; //Сбросить линию данных DQ в ноль
DQ=B; //Установить на линии DQ требуемое значение
TH1=186; // нач состояние таймера для 70 мкс
TL1=186; TF1=0; // исх состояние таймера и прерываний
ET1=0; //запретить прерывания таймера Т1
TR1=1; //запустить таймер Т1
do {} while(!TF1); //делать пока сброшен флаг прерывания таймера Т1
TR1=0; //остановить таймер Т1
DQ=1; //Установить на линии DQ лог. единицу
ET1=1; //разрешить прерывания таймера Т1
TF1=0; // сбросить флаг прерывания таймера Т1
}
/////////////////////////////////////////////////////////////////////////////
/////////////////Отправить команду на термометр////////////////////////////////////////
void send_command(char command)
{unsigned char B; // переменная для отправляемого бита
unsigned char k; // переменная для цикла
for (k=0;k<8;k++)
{B= command&1; // записать k-ый бит с команды
send_bit(B); // отправить бит B
command>>=1; // сдвинуть полученную коаманду на бит впарво
}
}
////////////////////////////////////////////////////////////////////////
/////////////////Прочитать бит с термометра////////////////////////////////////////
char read_bit()
{char B; // переменная для прочтённого бита
DQ=0; //Сбросить линию данных DQ в ноль
DQ=1; //для состояния готовности к чтению
TL1=253; // нач состояние таймера для 3 мкс
TH1=253;TF1=0; // исх состояние таймера и прерываний
ET1=0; //запретить прерывания таймера Т1
TR1=1; //запустить таймер Т1
do{}while (!TF1); //делать пока сброшен флаг прерывания таймера Т1
B=DQ; // прочитать с линии DQ бит
TR1=0; //остановить таймер Т1
TL1=TH1=189; // нач состояние таймера для 67 мкс
TF1=0; // сбросить флаг прерывания таймера Т1
TR1=1; //запустить таймер Т1
do{}while (!TF1); //делать пока сброшен флаг прерывания таймера Т1
TR1=0; //остановить таймер Т1
DQ=1; //Установить на линии DQ лог. единицу
ET1=1; //разрешить прерывания таймера Т1
return B; // функция возвращает значение прочтённого бита
}
/////////////////////////////////////////////////////////////////////////////
/////////////////Прочитать байт с термометр////////////////////////////////////////
char read_byte()
{unsigned char B; // переменная для прочтённого бит
unsigned char k; // переменная для цикла
unsigned char rez=0; // переменная для прочтённого байта
for (k=0;k<8;k++)
{B=read_bit(); // прочитатьбит
B=(B&1)<
rez+=B; //запить бит в байт
}
return rez; // функция возвращает значение прочтённого байта
}
////////////////////////////////////////////////////////////////////////
/////////////////Инициализация обмена с термометрами////////////////////////////////////////
void init_exchange()
{Per_Impulse=0; //сбросить счётчик для обработки времени импульса сброса
TH1=6; // нач состояние таймера для 250 мкс
TL1=6; TF1=0; // исх состояние таймера и прерываний
TR1=1; //запустить таймер Т1
DQ=0; //Сбросить линию данных DQ в ноль
do {} while(Per_Impulse<2); // делать в течении 2X250 мксек
TR1=0; //остановить таймер Т1
Per_Impulse=0; //сбросить счётчик для обработки времени импульса сброса
TH1=6; // нач состояние таймера для 250 мкс
TL1=6; TF1=0; // исх состояние таймера и прерываний
TR1=1; //запустить таймер Т1
DQ=1; //Установить линию данных DQ в единицу
do {} while(Per_Impulse<2); // делать в течении 2X250 мксек
TR1=0; //остановить таймер Т1
Per_Impulse=0; //сбросить счётчик для обработки времени импульса сброса
}
////////////////////////////////////////////////////////////
/////////////////////Команда Match ROM интерфеса 1-Wire///////////////////////////////////////////////
void Match_ROM(long int A, long int B)
{unsigned char j; // переменная для цикла
send_command(0x55);//кодкоманды Match ROM
for(j=0;j<4;j++)
{send_command(A&0x000000FF);// отправитьбайтсерийникатермометра
A>>=8; //сдвинуть серийник термометра на байт вправо
}
for(j=0;j<4;j++)
{send_command(B&0x000000FF);// отправить байт серийника термометра
B>>=8; //сдвинуть серийник термометра на байт вправо
}
}
////////////////////////////////////////////////////////////////////
/////////////////////Команда Convert_T интерфеса 1-Wire///////////////////////////////////////////////
void Convert_T()
{send_command(0x44);//кодкоманды Convert_T
}
////////////////////////////////////////////////////////////////////
/////////////////////Команда Read_Scratchpad интерфеса 1-Wire//////////////////////////////////
void Read_Scratchpad()
{send_command(0xBE);//кодкоманды Read_Scratchpad
}
////////////////////////////////////////////////////////////////////
/////////////Разделить число на разряды и вывести на ЖКИ//////////////////////////////
void cut_number(int N, unsigned char adress)
{unsigned char N_char; //переменнаядля перевода числа к типу char
unsigned char ost; //переменная для остатка деления
unsigned char j; // переменная для цикла
write_command(0x04); // декремент адреса,экран не движется
write_command(adress);// установить на требуемый адресс памяти ЖКИ
if (N<0) //если число меньше нуля
{N_char=((N&0x7FFF)^0x7FFF)+1; //получить модуль числа привести его к типу char
write_data('-'); //вывести на ЖКИ символ '-'
}
else {write_data(' ');//вывести на ЖКИ символ ' '
N_char=N; //привести чило к типу char
}
write_command(adress+4);// установить на требуемый адресс, сдвинутый на 4, памяти ЖКИ
if (N_char%2) {write_data('5');} //если последний бит числа равен 1, то вывести на ЖКИ символ '5'
else {write_data('0');}//вывести на ЖКИ символ '0'
write_data('.'); //вывести на ЖКИ символ '.'
N_char>>=1; //сдвинуть число на 1 бит вправо
write_command(adress+2);// установить на требуемый адресс, сдвинутый на 2, памяти ЖКИ
j=0;//обнулить счётчик цикла
do{ost=N_char%10; // делить до остатка число на 10
write_data(ost+0x30);//вывести на ЖКИ символ остаток деления
N_char/=10;//раделить число на 10
j++; //инкремент счётчика
}while (N_char); // пока не обнолуться переменная
write_command(0x06); // инкремент адреса,экран не движется
write_command(adress+1);// установить на требуемый адресс, сдвинутый на 1, памяти ЖКИ
while (j<2){write_data(' '); j++;} //заполнить не задействованные разряды числа пробелами
}
/////////////////////////////////////////////////////////////
//////////////////////ВывестинаЖКИстроку/////////////////////////////
void output_string(char adress, char *s, char l)
{char j;
write_command(adress); // установить на требуемый адресс памяти ЖКИ
for ( i = 0; i < l; i++ ) write_data(s[i]);// записать i-ый символ выводимой на ЖКИ строки
}
/////////////////////////////////////////////////////////////
///////////Инициализация устройств//////////////////////////
void Init_Device() //инициализация МПК
{TMOD=0x22; //настройка таймера
TH0=6; // Т0 на 250 машинных циклов
ET0=1; //разрешение прерываний таймера Т0
ET1=1; //разрешение прерываний таймера Т1
TF0=0; //сброс флага прерываний Т0
TF1=0; //сброс флага прерываний Т1
write_command(0x38); // 8-битная шина, 2 строки, шрифт 5x8
write_command(0x01); // очистить экран
write_command(0x06); // инкремент адреса,экран не движется
}
////////////////////////////////////////////////////////////
///////////////Контроль (сигнализация)////////////////////////////////
void Control()
{Err_Off=1;// установить флаг сброса сигнализации
for (i=0;i<5;i++)
{if( Ttek[i]>Tlim[2*i+1] || Ttek[i]
{Error=1; //зажечь светодиод Error красным
Err_Off=0;//сбросить флаг сброса сигнализации
Talarm[i]=1;// установить флаг срабатывания сигнализации термометра Ti
}
else {Talarm[i]=0;} //сбросить флаг срабатывания сигнализации термометра Ti
}
if (Err_Off==1)// если установлен флаг сброса сигнализации
{Error=0;//зажечь светодиод Error зелёным
}
}
///////////////////////////////////////////////////////////
///////////////////Обработка ввода//////////////////////////////////////
char Key_Code()
{unsigned char cod; //пременная номера нажатой клавиши
cod=0xFF; // значение cod при ненажатых кнопках
switch (Buttons)
{
case 0xFE : { cod=1; break;} //нажатакнопка Up
case 0xFD : { cod=2; break;} //нажатакнопка Down
case 0xFB : { cod=3; break;} //нажатакнопка Left
case 0xF7 : { cod=4; break;} //нажатакнопка Right
case 0xEF : { cod=5; break;} //нажатакнопка Ok
case 0xDF : { cod=6; break;} //нажатакнопка ESc
}
if (cod == keypress) cod = 0xFF; // нажатиеужеесть
else keypress = cod; // новоенажатие
return cod; //функциявзвращаетномернажатойклавиши
}
/////////////////////////////////////////////////////////
///////////////////Переключение режимов//////////////////////////////////////
void Select()
{unsigned char index; //переменная для вычисления индекса элемента массива
index=2*Pos1+Pos2; // вычислить индекс
switch(Mode)//переключатель режимов меню
{case 0://первый режим меню "Выбор термометра Ti"
switch(Key_Code())
{case 3://нажатакнопка "Left"
if (Pos1>0) {Pos1--;} //если позиции не крайняя слева, то менять позицию курсора влево
else{Pos1=4;} //иначе установить позиции курсора на крайнюю справа
break;
case 4://нажата кнопка "Rigth"
if (Pos1<4) {Pos1++;} //если позиции не крайняя справа, то менять позицию курсора вправо
else{Pos1=0;} //иначе установить позиции курсора на крайнюю слева
break;
case 5://нажата кнопка "Ok"
Mode=1; //втрой режим меню
Mode_Select=1; //установить флаг переключения режима
break;
}
break;
case 1://второй режим меню "Выбор Tmin или Tmax"
switch(Key_Code())
{case 1://нажата кнопка "Up"
if (Pos1<4) {Pos1++; Mode_Select=1;}//если позиции не крайняя справа, то менять позицию курсора вправо
else{Pos1=0;Mode_Select=1;} //иначе установить позиции курсора на крайнюю слева
break;
case 2://нажата кнопка "Down"
if (Pos1>0) {Pos1--; Mode_Select=1;}//если позиции не крайняя слева, то менять позицию курсора влево
else{Pos1=4;Mode_Select=1;} //иначе установить позиции курсора на крайнюю справа
break;
case 3: //нажата кнопка "Left"
if (Pos2>0) {Pos2--;} //если позиции не крайняя слева, то менять позицию курсора влево
else{Pos2=1;} //иначе установить позиции курсора на крайнюю справа
break;
case 4://нажата кнопка "Rigth"
if (Pos2<1) {Pos2++;} //если позиции не крайняя справа, то менять позицию курсора вправо
else{Pos2=0;} //иначе установить позиции курсора на крайнюю слева
break;
case 5://нажата кнопка "Ok"
Mode=2; //втрой режим меню
Mode_Select=1; //установить флаг переключения режима
break;
case 6://нажатакнопка "Esc"
{Mode=0;Mode_Select=1;}//если нажата кнопка "Esc", то выйти в первый режим меню
break;
}
break;
case 2://третий режим меню "Выбор разряда числа"
switch(Key_Code())
{
case 1://нажатакнопка "Up"
if (Tlim[index]<250-slog[Pos3])Tlim[index]+=slog[Pos3];//если Tlim больше 124,5, топрибавить
else Tlim[index]=249;// иначе Tlim равно 124,5
if (Pos2==0 && Tlim[index]>=Tlim[index+1]-1 ){Tlim[index]=Tlim[index+1]-2;}// если Tmin=>Tmax, тоотнять Tmin=Tmax-1
break;
case 2://нажатакнопка "Down"
if(Tlim[index]>-110+slog[Pos3])Tlim[index]-=slog[Pos3];//если Tlim больше -54,5, тоотнять
else Tlim[index]=-109;// иначе Tlim равно -54,5
if (Pos2==1 && Tlim[index]<=Tlim[index-1]+1 ){Tlim[index]=Tlim[index-1]+2;}// если Tmax<=Tmin, тоотнять Tmax=Tmin+1
break;
case 3://нажатакнопка "Left"
if (Pos3>0) {Pos3--;} //если позиции не крайняя слева, то менять позицию курсора влево
else{Pos3=2;} //иначе установить позиции курсора на крайнюю справа
break;
case 4://нажата кнопка "Right"
if (Pos3<2) {Pos3++;} //если позиции не крайняя справа, то менять позицию курсора вправо
else{Pos3=0;} //иначе установить позиции курсора на крайнюю слева
break;
case 6://нажата кнопка "Esc"
{Mode=1;Mode_Select=1;}//если нажата кнопка "Esc", то выйти в первый режим меню
break;
}
break;
}
}
/////////////////////////////////////////////////////////
//////////////Обработка вывода на дисплей///////////////////////////////////
void Display()
{unsigned char index1; //переменная для вычисления индекса элемента массива
unsigned char index2; //переменная для вычисления индекса элемента массива
index1=2*Pos1; // вычислить индекс
index2=8*Pos2; // вычислить индекс
write_command(0x0C); //включить дисплей, курсор не отображается
switch(Mode)//переключатель режимов меню
{
case 0://первый режим меню "Выбор термометра Ti"
if (Mode_Select==1)//Если флаг смены режима установлен
{write_command(0x01); // очиститьэкран
for (i=0;i<5;i++)
{output_string(130+8*i,"T",1); //вывести на ЖКИ символ 'T'
write_data(49+i); // вывести на ЖКИ символ "i"
}
Mode_Select=0;// сбросить флаг смены режима
}
for (i=0;i<5;i++)
{
cut_number(Ttek[i],192+i*8);//разделить Ttek наразряды
if (Talarm[i]==1 && Mig[i]==1)// если установлен флаг срабатывания сигнализаци Talarm[i]
{output_string(129+8*i,"!",1); //вывести на ЖКИ символ '!'
output_string(132+8*i,"!",1); //вывести на ЖКИ символ '!'
Mig[i]=0; //сбросить флаг мигания
}
else
{output_string(129+8*i," ",1);//вывести на ЖКИ символ ' '
output_string(132+8*i," ",1);//вывести на ЖКИ символ ' '
Mig[i]=1; // установать флаг мигания
}
}
write_command(130+8*(Pos1)); //курсор на выбранную температуру
break;
case 1://второй режим меню "Выбор Tmin или Tmax"
if (Mode_Select==1)//Если флаг смены режима установлен
{write_command(0x01); // очистить экран
output_string(138,"Ttek",4);//вывести на ЖКИ строку
output_string(146,"Tmin",4);//вывести на ЖКИ строку
output_string(154,"Tmax",4); //вывести на ЖКИ строку
output_string(193,"T",1); //вывести на ЖКИ символ
write_data(49+Pos1); // вывести символ с номером выбранного термометра
cut_number(Tlim[index1],209); //вывести минимальный предел температуры на ЖКИ
cut_number(Tlim[index1+1],217); //вывести максимальный предел температуры на ЖКИ
Mode_Select=0;// сбросить флаг смены режима
}
if (Talarm[Pos1]==1 && Mig[Pos1]==1) // если установлен флаг срабатывания сигнализации выбранного термометра T
{output_string(192,"!",1);//вывести на ЖКИ символ '!'
output_string(195,"!",1);//вывести на ЖКИ символ '!'
Mig[Pos1]=0;// сбросить флаг мигания
}
else //если флаг мигания сброшен
{output_string(192," ",1);//вывести на ЖКИ символ ' '
output_string(195," ",1);//вывести на ЖКИ символ ' '
Mig[Pos1]=1; // установить флаг мигания
}
cut_number(Ttek[Pos1],201);//вывести текущую температуру на ЖКИ
write_command(147+index2); // установить курсор на выбранную температуру
break;
case 2: //третий режим меню "Выбор разряда числа"
if (Talarm[Pos1]==1 && Mig[Pos1]==1) // если установлен флаг срабатывания сигнализации выбранного термометра T
{output_string(192,"!",1); //вывести на ЖКИ символ '!'
output_string(195,"!",1); //вывести на ЖКИ символ '!'
Mig[Pos1]=0;// сбросить флаг мигания
}
else //если флаг мигания сброшен
{output_string(192," ",1); //вывести на ЖКИ символ ' '
output_string(195," ",1); //вывести на ЖКИ символ ' '
Mig[Pos1]=1; // установить флаг мигания
}
cut_number(Ttek[Pos1],201);//разделить Ttek на разряды
cut_number(Tlim[index1],209);//разделить Tlim на разряды
cut_number(Tlim[index1+1],217);//разделить Tlim наразряды
if (Pos3!=2){write_command(210+8*Pos2+Pos3);} // установитькурсорна
else {write_command(210+8*Pos2+Pos3+1);} // выбраннуыйразрядтемпературы
break;
}
write_command(0x0E);// появляетсякурсор
}
////////////////////////////////////////////////////////////////////////
///////////////////////////////Получения информации о измерениях с термометров/////////////////////////////////
void Measure()
{bit A; //переменная для знака температуры
for(i=0;i<5;i++)
{init_exchange();// установить обмен с термометрами
Match_ROM(SerL[i],SerH[i]); // отправить команду Mach ROM и серийник требуемого термометра
Read_Scratchpad(); // отправитькоманду Read_Scratchpad
Ttek[i]=(read_byte())&0xFF;// прочитать значение температуры
A=read_bit(); // прочитать знак
if (A) Ttek[i]-=256; // если знак отризательный то отнять 256
init_exchange(); // установить обмен с термометрами
init_exchange(); // установить обмен с термометрами
Match_ROM(SerL[i],SerH[i]); // отправить команду Mach ROM и серийник требуемого термометра
Convert_T(); // отправить команду начала ковертирования температуры
}
}
/////////////////////////////////////////////////////////////////
///////////Обработка прерываний таймера Т0//////////////////////////
void T0_ISR(void) interrupt 1
{Per_Key++; //инкремент счётчика прерываний для обработки ввода
Per_Contr++; //инкремент счётчика прерываний для обработки контроля
}
/////////////////////////////////////////////////////////////
///////////Обработка прерываний таймера Т1/////////////////////
void T1_ISR(void) interrupt 3
{Per_Impulse++; //инкремент счётчика прерываний для обработки импульса сброса
}
////////////////////////////////////////////////////////////
/////////////////Главная программа///////////////////////////////
void main()
{Mode_Select=1;// установить флаг смены режима
Init_Device();//инициализация устройств
TR0=1; TR1=0;//запустить таймеры Т0 и остановить Т1
Mode=0;//первый режим меню
EA=1; //разрешить индивидуальные разрешения прерываний
Per_Key=0;//обнулить счётчик прерываний для обработки ввода
Per_Contr=0;//обнулить счётчик прерываний для обработки контроля
Pos1=0; Pos2=0;Pos3=0;//позиции курсора во всех режимах меню на первое положение
for (i=0;i<5;i++)
{Ttek[i]=0; // //задание массива текущих значений температур
}
SerL[0]=0xC8C53010;SerL[1]=0xC8C53110;SerL[2]=0xC8C53210;SerL[3]=0xC8C53310;SerL[4]=0xC8C53410; // задание массивов серийников термометров
SerH[0]=0xC3000000;SerH[1]=0xF4000000;SerH[2]=0xAD000000;SerH[3]=0x9A000000;SerH[4]=0x1F000000;
for (i=0;i<5;i++)
{Tlim[2*i]=-109; // задание массива знчений
Tlim[2*i+1]=249; // пределов температур
}
for (i=0;i<5;i++)
{Talarm[i]=0; //сбросить все флаги срабатывания сигнализации термометра Ti
Mig[i]=0; // сбросить флаг мигания сигнализации Ti
}
Error=0;//зажечь светодиод Error зелёным
do
{if (Per_Key>=250){ Select();Display(); Per_Key=0;}// делатьна 700 прерываниитаймера T0
if (Per_Contr>=3000){Measure(); Control(); Per_Contr=0;}// делатьна 3000 прерываниитаймера T0
} while (1);
}
////////////////////////////////////////////////////////////////////////////
1 2 3 4
2.3 Конструктивное исполнение устройства
Рисунок 2.1 – Структурная схема
Рисунок 2.2 – Принципиальная схема:
-
МПК; -
Кнопка «OK»; -
Кнопка «ESC»; -
Кнопка «UP»; -
Кнопка «DOWN»; -
Кнопка «LEFT»; -
Кнопка «RIGHT»; -
ЖКИ; -
Светодиод; -
Осциллограф; -
Подтягивающий резистор; -
Цифровые термометры.
При включении в цепь питания/сбросе микроконтроллера все порты переводятся в начальное состояние, соответствующее высокому импедансу на порту Р0 и логической единице на остальных портах. При этом сразу же начинается инициализация контроллера и ЖКИ.
На первом этапе происходит инициализация таймеров-счётчиков МПК (1) и ЖКИ (6). Инициализация ЖКИ представляет собой передачу настроечных байтов от МПК к контроллеру HD44780, встроенному в модуль ЖКИ. Настроечные байтов представляют собой команды включения, очистки дисплея, а также перевода курсора в начальное положение.
На втором этапе происходит опрос кнопок и индикация интерфейса в первом режиме на ЖКИ (режиме при котором на экране ЖКИ выводятся все текущие значения температур со всех пяти термометров) (рис.2.3):
Рисунок 2.3 - Табло
Кнопками «LEFT» и «RIGTH» можно передвигать курсор между термометрами T1-T5, а нажав кнопку «OK» можно выбрать термометр, на котором находится курсор. После нажатия кнопки «OK» интерфейс переходит во второй режим (отображение значений текущей температуры, а также минимального и максимального её пределов для выбранного термометр Ti) рис.2.4:
Рисунок 2.4 - Табло
По умолчанию минимальные пределы температур все термометров равны -54,5 оС, а максимальные +124,5 о