Тестовая программа контроллера станции CI-LAN
2.6. Тестовая программа контроллера станции CI-LAN
В настоящем разделе рассмотрим некоторые фрагменты тестовой программы микроконтроллера станции CI-LAN. Программа написана на языке «С» для микроконтроллера АТ89С51 при частоте кварцевого резонатора 11,059 МГц.
В первом фрагменте сведены определения используемых переменных инициализация данных и все основные подпрограммы общего пользования:
Фрагмент 1:
/***********************************/
/* Test Program for CI LAN "MISNET" */
/***********************************/
#include "..\include\io51.h"
#define ERROR 0
#define OK 1
#define byte unsigned char
code byte StartSpeed =24;
#pragma memory - data
byte FR[5]; /* Массив фрейма */
byte PTR; /* Счетчик */
byte MyAddress; /* Адрес станции */
byte Ready; /* Готовность приемника */
byte FLAG; /* Флаг приема фрейма */
#pragma memory = default
interrupt [0x23] void SCON_int (void) /* Процедура прерывания порта RS232C */
{
Ready=1;
ES=0;
}
void SpeedInit (byte NewSpeed) /* Подпрограмма настройки 1 таймера */
/* для работы RS232C */
{
char ch:
TR1 = 0; /* Таймер 1 выключить */
PCON = PCON | 0x80; /* Установка двойной скорости «/
ТН1 = TL1 = (NewSpeed`OxFF)+1;
ch = SBUF; /* Очистить приемный буфер */
SCON = 0x52;
TR1 =1; /* Таймер 1 включить */
}
void SendB (byte SendByte) /* Подпрограмма передачи байта */
{
while (!TI); /* Ожидать пока завершится предыдущая передача (ТI=0) */
ТI=0; /* Очистить флаг передачи */
SBUF=SendByte; /* Послать байт */ }
byte GetB (void) /* Подпрограмма приема байта */
{
byte InputByte;
Командно-информационные сети
while (!RI); /* Ожидать прием байта (RI=0) */
InputByte = SBUF; /* Получить байт */
RI = 0; /* Очистить флаг приема */
return InputByte; /* Вернуть принятый байт */ }
void Time (char Delay) /* Подпрограмма задержки " (10+7*Delay) мкс */
{
while (Delay)
{
Delay=Delay-1;
}
}
void Init_Ports (void) /* Начальная инициализация микроконтроллера */
{
EA=0; /* Запретить все прерывания */
RI=TI=PTR=0;
FLAG=0;
TMOD=Ox22; /* Таймер в режиме 2: */
/* автоперегружаемый 8-битный счетчик */
SpeedInit (StartSpeed); /* Установить начальную скорость 2400 */
MyAddress =Р2 & 0x7F; /* Прочитать адрес станции через порт Р2 */
Time (100); /* Задержка " 750 мкс */
Ready=0; /* Очистить флаг приема */
Т1=0; /* Очистить флаг передачи */
ЕА=1; /* Разрешить все прерывания */
}
Приведенный фрагмент содержит достаточно полные комментарии, поэтому следует добавить только, что в описываемой программе все контроллеры после аппаратного сброса, настраиваются на минимальную скорость 2400. После формирования PC аппаратного сетевого сброса и инициализации микроконтроллеров PC передает каждому контроллеру команду настройки на свою скорость, а затем команду автотестирования для определения состояния станции и устойчивости связи на заданной скорости.
Фрагмент 2 показывает основные подпрограммы приема и передачи фреймов:
Фрагмент 2:
/***************************************************/
/*** GET COMMAND ***/
/***************************************************/
int Frame_Get (void)
{
byte Bi;
while (1)
{
PTR=0; /* Очистить счетчик */
FLAG=0; /* Сбросить флаг приема фрейма */
while (PTR<6) /* Осуществить прием 6 байтов фрейма +/
{
Тестовая программа контроллера станции CI-LAN
ES=1; /* Разрешить прерывания RI & TI */
while ('RI&!Ready); /* Если поступил байт, принять его */ FLAG=1, /* Установить флаг приема фрейма */
Ready=0; /* Очистить флаг готовности приемника */
Bi=GetB(); /* Полученный байт записать */
if (!PTR) /* Если байт первый (PTR==0) и не равен коду преамбулы (Bi!=OxAA), ждать следующий байт */
{
if (Bi!=0xAA) /* Синхронизация */
continue;
}
FR[PTR++]=Bi; /* Записать принятый байт во массив фрейма FR[PTR]
и увеличить счетчик */
}
FLAG = 0; /* Фрейм принят, сбросить флаг приема */
Bi =(FR[0]+FR[1]+FR[2]+FR[3]+FR[4])&0x00FF;
/* Расчет контрольной суммы */
if (FR[5]!=Bi) /* Если контрольная сумма фрейма не равна расчетной */ {
PTR=0, /* Сбросить счетчик */
continue; /*Ожидать следующий фрейм */
}
if ((FR1&0x7F)==MyAddress)
break; /* Если адрес фрейма равен адресу станции
- завершить, иначе ожидать следующий фрейм */
}
ES=1; /* Разрешить прерывания RI & TI */
return OK;
}
/*************************/
/*** SEND FRAME ***/
/*************************/
void Frame_Send (void)
{
while (FLAG); /* Ожидать завершения приема фрейма */
PTR=0, /* Обнулить счетчик */
TI =1; /* Разрешить передачу */
while (PTR<6)
SendB (FR[PTR++]); /* Передать 6 байт фрейма */ }
Фрагмент 3 показывает подпрограммы монитор, примеры написания нескольких команд и подпрограммы формирования фрейма ответа:
Фрагмент 3:
/**************************/
/*** OUTPUT FRAME ***/
/**************************/
void Output_Frame (byte B2, byte B3, byte Stat) /* Подпрограмма формирования фрейма ответа */
FR[0]=0xAA, /* Преамбула */
FR[1]=MyAddress; /* Адрес станции */
Командно-информационные сети
FR[2]=Stat; /* Статус или ошибка */
FR[3]=B2; /* Данные или детализация состояния */
FR[4]=B3; /* Данные или детализация состояния */
FR[5]=(FR[0]+FR[1]+FR[2]+FR[3]+FR[4])&0x00FF;
/* Контрольная сумма */
}
void Form_Comm_Error (void) /* Подпрограмма формирования фрейма ответа при получении */
{ /* несуществующей команды. Код 0x01 */
Output_Frame (0x02, 0x00, 0x01);
}
/***************************/
/*** Command Subroutines ***/
/***************************/
int Command_0 (void) /* Подпрограмма команды установки скорости 2400 */
{
SpeedInit (StartSpeed); /* Установить скорость 2400 */ Output_Frame (2400,0,0); /* Сформировать ответный фрейм */ Frame_Send (); /* Отправить фрейм */
return OK;
}
/* …………………………………………. Ряд команд пропущено */
int Command_F (void) /* Подпрограмма пустой команды */
{
/* Тело подпрограммы */
return OK;
}
/*****************************/
/*** N 0 N I Т 0 R ***/
/****************************/
int Monitor (void) /* Подпрограмма монитора */
{
switch (FR[2]) /* Дешифрировать код команды
{
case 0x00: return Command_0 (); /* Вызвать команду 0 */
case 0x01: return Command_1 (); /* Вызвать команду 1 */
/*………………………………. Ряд кодов команд пропущено */
case 0x0f: return Command_F (); /* Вызвать команду F */
/*………………………………. Ряд кодов команд пропущено */
default: return ERROR; /* При поступлении кода несуществующей команды
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.