Как стать автором
Обновить

Ваттметр поглощаемой СВЧ мощности и мое участие в его разработке

Время на прочтение 10 мин
Количество просмотров 12K
Доброго времени суток, уважаемые читатели. Зарегистрировался на хабре я давно, но никак не решался оформить свой первый пост.

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

И вот, буквально на днях, я закончил работу над одним из своих первых проектов, после чего, мне в голову пришла мысль сделать некий видео обзор и написать небольшую статью о приборе, над которым я работал достаточно продолжительный период времени. Работал не один, но речь пойдет о части, которая «висела» целиком и полностью на мне.

Для начала приведу немного сухой технической информации


image

Ваттметр поглощаемой СВЧ мощности М3-114 предназначен для измерения в коаксиальном тракте среднего значения мощности непрерывных и импульсно- модулированных СВЧ сигналов при электропитании от промышленной электросети 220 В, 50 Гц, так и в автономном режиме, от внутренней или внешней аккумуляторной батареи 12 В. В приборе применён четырёх строчный текстовый вакуумно-люминесцентного дисплей высокой яркости. Подготовка прибора к работе осуществляется в диалоговом режиме, что упрощает эксплуатацию. Прибор оснащён портом RS-232, что позволяет выводить данные на ЭВМ.

Диапазон рабочих частот от 0,00 до 17,85 ГГц.

Диапазон измерения средних значений мощности от 1,0 мкВт до 100 Вт.

В диапазоне измеряемой мощности более 10 мВт на частотах от 0 до 12,05 ГГц предел основной погрешности ваттметра не превышает ±4 %, а в диапазоне частот свыше 12,05 ГГц до 17,85 ГГц — ±6 %.

КСВН ваттметра не более:
1,3 в диапазоне частот от 0,02 до 12,05 ГГц;
1,4 в диапазоне частот свыше 12,05 до 17,85 ГГц.

Нестабильность показаний ваттметра с учетом дрейфа “электрического нуля” не более 40 мкВт/мин.

Мощность, потребляемая ваттметром от сети напряжением 220 ±22 В, частотой 50±0,5 Гц при работе с ППК1 – ППК3, не более 12 ВА, при работе с ППК 4 — не более 15 ВА, при работе от автономного источника питания 6,5 ВА


Теперь перейдем непосредственно к тем задачам, которые были поставлены передо мной


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

Во-вторых, и это собственно самая сложная часть для меня, необходимо было разработать программу, управляющую блоком обработки информации и индикации. В БОИ входят такие узлы, как дисплей, клавиатура, пара вспомогательных светодиодов и управляющий всем этим микроконтроллер AT89C51RC2 (МК_БОИ). Обзор всех основных функций ваттметра представлен на видео.

К ваттметру подключается один из четырех преобразователей, в зависимости от измеряемой мощности. Данные с преобразователя поступают на аналого-цифровой преобразователь фирмы Analog Devices и далее с помощью RS232 передаются на еще одни ADUC814 (МК_АЦП), в котором проходят предварительную обработку. Программа пред. обработки и связи непосредственно с АЦП разрабатывалась не мной.

МК_АЦП по RS232 получает от МК_БОИ одну из нескольких команд, каждая из которых состоит из трех байт, далее он анализирует команду и в зависимости от нее, посылает обратно три байта номера команды и запрашиваемый результат. Это может быть номер преобразователя или, например, результаты измерений, которые подвергаются дальнейшей математической обработке. Некоторые команды отвечают за коррекцию нуля или калибровку АЦП. Всего около 8-9 команд, подробно останавливаться на них я также не вижу смысла.

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

С помощью меню можно выполнять ряд функций

  • Управлять яркостью дисплея
  • Выбирать частотный диапазон, на котором проводятся измерения. В зависимости от выбранного диапазона применяются те или иные поправочные коэффициенты, влияющие на конечный результат. Коэффициенты рассчитаны путем сравнения с эталонным прибором.
  • Устанавливать некую величину P, с которой сравнивается измеряемая величина. Результат выводится на дисплей в процентах
  • Устанавливать диапазон измеряемой величины, при выходе из которого, на дисплей выводиться соответствующая надпись < Pmin, > Pmax

В режиме работы пользователь может:

  • Проводить коррекцию нуля и калибровку АЦП.
  • Включить усреднение измеряемой величины или выключить его.
  • «Заморозить» дисплей, путем нажатия кнопки СТОП


Вся необходимая информация выводится на дисплее. Значение измеряемой величины, которое так же переводится в dBm и dB, во время дрейфа нуля попадаются и отрицательные значения, в этих случаях на экран выводится сообщение Err. Результат сравнения мощности с величиной Рс. Номер подключенного преобразователя. Информация о том, что нажата кнопка СТОП, а так же при выходе из возможного диапазона измерений конкретного преобразователя также выводится соответствующее сообщение.

Еще хотелось бы добавить, что помимо частотных поправочных коэффициентов так же имеется и динамический поправочный коэффициент, рассчитывается индивидуально для каждого конкретного измерения.

На этом все, надеюсь, что найдутся люди, которым данный пост понравится, а так же хотелось бы увидеть комментарии, критического характера, возможно у кого-то будут интересные идеи, которые я смогу реализовать в дальнейшем в рамках этого проекта, учитывая, что намечается замена МК_БОИ на аналогичный, с большим объемом памяти, так как эти 32 кБ забиты под завязку.

Спасибо за внимание.



КОДИНГ


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

Алфавит дисплея

Вывод информации на дисплей был организован следующим образом. Был составлен список повторяющихся фраз и написана под них библиотека «alphabetLCD.h»:

void m3114();	                                          // "МЕТЕОР МЗ-114"
void noSignalADC();	                                      // "НЕТ СВЯЗИ С АЦП"
void wait();	                                          // "ОЖИДАНИЕ"
void norma();	                                          // норма
void PPK1();
void PPK2();
void PPK3();
void PPK4();
void prepareToWorkOnPPKEnter();	                          // подготовка к работе подключите ппк к источнику сигнала и нажмите "ввод"
void heating();	                                          // прогерв 6с прервать? 34
void ifTNorm();	                                          // ЕСЛИ Т=15-25 НАЖМИТЕ "ВВОД" ЕСЛИ НЕТ НАЖМИТЕ "ОТМЕНА"
void Kcoeff();	                                          // К преобразования 1,000
void preparationOfMeasurement();                          // ПОДГОТОВКА ИЗМЕРЕНИЙ САМОКАЛИБРОВКА 12с
void resetMenuParams();                                   // переустновка параметров в меню
void readyToMeasurement();                                // ваттметр готов к измерениям
void menuSet1();                                          // установка К частот *** установка частоты *** установка Р сравнения *** допусковый контроль
void switchOffSVCHAndPressEnter();	                      // "ВЫКЛЮЧИТЕ свч сигнал и нажмите ввод
void preparationOfMeasurementCorrection0();               //  подготовка измерений коррекция "0" норма
void preparationOfMeasurementCooling();                   //  подготовка измерений остывание 30 с
void preparationOfMeasurementStop32();                    //  подготовка измерений 32с прервать? 24
void preparationToWork();                                 // подготовка к работе выключите свч сигнал и нажмите ввод
void hertzType0();                                        // 0-1 1-4 4-8 8-12
void hertzType1();                                        // 12-15 15-17.85
void setPCompare();	                                      //установка Р сравн. сохранить значение? 1,000 mW
void setPCompareChange();	                              //установка Р сравн. зпт - кнопкой зпт измените цифру: х,ххх
void allowenceControlMin();                               // допусковый контроль Рmin: сохранить значение? Х,ХХХ 	W
void allowenceControlMax();                               // допусковый контроль Рmax: сохранить значение? Х,ХХХ 	W
void setAllowenceControlMin();                            //установка Р min зпт - кнопкой зпт измените цифру: х,ххх
void setAllowenceControlMax();                            //установка Р max зпт - кнопкой зпт измените цифру: х,ххх
void menuSet2();                                          // без усреднения усреднение по 4м 8ми 16ти
void brightnessSet();									  // 25% 50% 75% 100%
void fault();                                             // НЕИСПРАВНОСТЬ!!! 
void incorrectValue();                                    // ОШИБКА ВВОДА! ОВТОРИТЕ ПОПЫТКУ
void overload();                                          // ПЕРЕГРУЗКА!!! при Р > крайнего значения диаппазона


Приведу пример реализации одной из функций из «alphabetLCD.с»:

void noSignalADC()	   // "НЕТ СВЯЗИ С АЦП"
{
	writeData('H');
	writeData('E');
	writeData('T');
	writeData(' ');
		
	writeData('C');
	writeData('B');
	writeData(0x99);
	writeData(0x8D);
	writeData(0x8E);
	writeData(' ');
	
	writeData('C');
	writeData(' ');
		
	writeData('A');
	writeData(0x90);
	writeData(0x85);
}

Так как иногда приходилось выводить на дисплей результаты вычислений, реализованных в «main.c», я использовал ключевое слово extern:
extern bit hertzType;
extern float         xdata calibrFl;
extern unsigned char xdata ppkNumberCh; // номер ППК char
extern float         xdata pCompareFl;
extern float         xdata pMinFl;      // записывает массив в float
extern float         xdata pMaxFl;      // записывает массив в float

Плавно перейдем к основной программе

Ниже описаны все основные функции «main.h»:
void initialization();
void delay(unsigned int);
void delay2s();
void zeroCorrection();
void calibration();
void measurement();
//****UART****
void sendData (unsigned char);  // send to UART
//unsigned char recvData();       // recive from UART
void iToA (int , char * );
void getPPKnumber();

//****Keyboard****
void keyboardInit();
void keyboardPolling();
void downZero();	             
void upCalibr();
void lessAveraging();
void morePC();
void commaStop();
void cancel();
void enter();
void menu();

//****Display****

void dispInit();
void writeCmd(int);
void writeData(char);
void readBF();
void returnHome();
void clearDisp();
void reloadDisp();
void moreLessCheck();

Макросы

Для удобства программирования дисплея, вызова его команд, перемещения курсора по строкам и т.п. активно использовались макросы:
/* __________MAKROS BLOCK__________ */
#define FIRST_LINE      0x80
#define SECOND_LINE     0xC0
#define THIRD_LINE      0x94
#define FOURTH_LINE     0xD4
#define CURSOR_HOME     0x02
#define CLEAR_DISP      0x01 
#define DISP_OFF        0x08 
#define DISP_ON_CB_OFF  0x0C // Disp ON cursore & blink OFF
#define DISP_ON_CB_ON   0x0F
#define FIRST_SIMBOL    0xD4
#define SECOND_SIMBOL   0xD5
#define THIRD_SIMBOL    0xD6
#define FOURTH_SIMBOL   0xD7
#define FIFTH_SIMBOL    0xD8
#define SIXTH_SIMBOL    0xD9
/* __________MAKROS BLOCK END__________ */

Конфигурирование ножек процессора

* __________PINS BLOCK__________ */
sbit E =         P3^4;
sbit RS =        P3^6;
sbit RW =        P3^5;
sbit workLed =   P3^2;
sbit menuLed =   P3^3;
sbit enterBut =  P1^6;
sbit cancelBut = P1^5;
sbit uartPC =    P3^7;
/* __________PINS BLOCK END__________ */

Описание переменных

/* __________VARIABLES BLOCK__________ */
unsigned char       keyPressed =         0; // key pressed value 
bit                 keyFlag =            0; // software flag 
unsigned char xdata uartDataRecv =       0; // запоминает данные с уарт
unsigned char xdata uartDataSend =       0; // отправляет данные с уарт
char          xdata uartRecvCount =      0; // счетчик принятых данных с уарт
bit                 menuFlag =           0; // контролирует зажигание диодов клавиатуры, если 1 - горит верхний, если 0 - нижний
char          xdata move =               1; // перемещение по пунктам меню
bit                 signalFlag =         0; // если флаг установлен значит есть инфа о номере ППК
char          xdata enterFlag =          0; // инкрементируется при нажатии ввод
char          xdata cancelFlag =         0; // инкрементируется при нажатии отмена
bit                 modeFlag =           0; // игнорирует нажатие кнопок вне бесконечного цикла
bit                 brightnessFlag =     0; // устанавливается, если мы внутри меню яркости дисплея
char          xdata brightnessMove =     1; // флаг для перемещения по меню яркости
char          xdata brightnessSetFlag =  0; // установка яркости дисплея, контролирует нажатие ввод 
bit                 hertzFlag =          0; // устанавливается, если мы внутри меню установки частоты    
char          xdata hertzSetFlag =       0;
char          xdata menuStep =           0; // глубина меню
char          xdata hertzMove =          1; // флаг для перемещения по меню частоты 
bit                 hertzType;              // флаг типа меню частоты
bit                 compareFlag;            // флаг меню Р сравнения
char          xdata compareFlagEnter =   0; // нажат ВВОД для Р сравнения
char          xdata compareFlagCancel =  0; // нажата ОТМЕНА для Р сравнения  
char          xdata moreLess =        0x30; // значение Р сравнения и допускового контроля
char          xdata moreLessFlag =       0; // флаг для подсчета количества введенных знаков
bit                 moreFlag =           0; // если 1 то при вычитании moreLess -= 2
bit                 lessFlag =           0; // если 1 то при прибавлении moreLess +=2
char          xdata wattFlag =           0; // флаг переключения размерности Р сравн
bit                 commaFlag =          0; // проверка нажатия кнопки ЗПТ для ввода Р сравн и допускового контроля
unsigned char xdata pCompare[10] =       0; // запоминает Р сравн
float         xdata pCompareFl =       1.0;

//float         xdata pCompareFlTemp =   1.0; // для сохранения предыдущего состояния переменной в случае отмены.
                                              // ДОРАБОТАТЬ, ЗНАЧЕНИЕ НЕ СОХРАНЯЕТСЯ!!!
                                              
bit                 controlFlag =        0; // флаг меню допускового контроля
char          xdata controlFlagEnter =   0; // нажат ВВОД для допускового контроля
char          xdata controlFlagCancel =  0; // нажата ОТМЕНА для допускового контроля
unsigned char xdata pMin[10];               // запоминает Р min
unsigned char xdata pMax[10];               // запоминает Р max
float         xdata pMinFl =             0; // записывает массив в float
float         xdata pMaxFl =             0; // записывает массив в float
bit                 pMinFlag =           0; // устанавливаем флаг когда изменяем Р min
bit                 pMaxFlag =           0; // устанавливаем флаг когда изменяем Р max
unsigned char xdata zeroCoef1 =         50; // коэффициент коррекции нуля 50 - 200
unsigned char xdata zeroCoef2 =         30; // коэффициент коррекции нуля 50 - 200
unsigned char xdata zeroCoef3 =         30; // коэффициент коррекции нуля 50 - 200
unsigned char xdata zeroCoef4 =        100; // коэффициент коррекции нуля 50 - 200
unsigned long xdata zero;                   // значение после коррекции нуля
unsigned char xdata calibrCoef1 =       50; // коэффициент калибровки 50 - 200
unsigned char xdata calibrCoef2 =       30; // коэффициент калибровки 50 - 200
unsigned char xdata calibrCoef3 =       30; // коэффициент калибровки 50 - 200
unsigned char xdata calibrCoef4 =      100; // коэффициент калибровки 50 - 200
unsigned long xdata calibr;                 // значение после калибровки К преобразования
float         xdata calibrFl;               // значение после калибровки К преобразования
unsigned int  xdata PPK1CalibrPower;        // эталон калибровочного коэффициента для ППК1 мощьность Р
unsigned long xdata PPK23CalibrPower;       // эталон калибровочного коэффициента для ППК1 - 2 мощьность Р
unsigned long xdata PPK4CalibrPower;        // эталон калибровочного коэффициента для ППК4 мощьность Р
float         xdata PPK1CalibrStandart;     // эталон для проверки вхождения в диапазон (0,5 - 1,5)
float         xdata PPK2CalibrStandart;     // эталон для проверки вхождения в диапазон (0,5 - 1,5)
float         xdata PPK3CalibrStandart;     // эталон для проверки вхождения в диапазон (0,5 - 1,5)
float         xdata PPK4CalibrStandart;     // эталон для проверки вхождения в диапазон (0,5 - 1,5)
unsigned char xdata uartData[10];           // данные о номере ППК приходящие на УАРТ по запросу   
unsigned char xdata ppkNumberCh;            // номер ППК char   
float         xdata measurementResult =  0; // результат основных измерений
bit                 averagingFlag =      0; // флаг устреднения
bit                 averaging4 =         0; // усреднение по 4-ем
bit                 averaging8 =         0; // усреднение по 8-ми
char          xdata averagingMove =      1; // для перемещения по меню усреднения
float         idata hertzRate =          1; // поправочный коэффициент для коррекции принимает 6(диаппазонов) * 4(ППК) = 24 значения
float         idata dynamicRate =        1; //  динамический поправочный коэффициент 
                                            //для коррекции принимает 4(диаппазонов) * 4(ППК) = 16 значения
char          idata stop =               0; // устанавливается в 1 и экран замирает при нажатии кнопки СТОП, в 0 при повторном нажатии
char          idata pc =                 0; // бит для вывода данных на ПК
//bit key = 0;
xdata union
{
    unsigned long bytes;
    unsigned char byteArr[4];
} byteUnion;
/* __________VARIABLES BLOCK END__________ */

Прерывания

/* __________INTERUPTS BLOCK__________ */
void keyboard_interrupt() interrupt 7 using 1
{
	IEN1 &= ~(1<<0);		  //запрещаем прерывания клавиатуры
	keyFlag = 0;
keyPressed = KBF;         /* save pressed key */
	keyFlag = 1;              /* set the software flag */
	KBF = 0x00;               /* clear keyboard flags */	
	delay(50000);			  // 50 mc
	IEN1 |= 0x01;			  //разрешаем прерывания клавиатуры
}

void serial_IT(void) interrupt 4
{
    if (RI == 1)
    {
        uartDataRecv = SBUF;
        uartData[uartRecvCount] = uartDataRecv;
		++uartRecvCount;
    }
    RI = 0;    
}
/* __________INTERUPTS BLOCK END__________ */  


ПРОДОЛЖЕНИЕ СЛЕДУЕТ...
Теги:
Хабы:
+16
Комментарии 21
Комментарии Комментарии 21

Публикации

Истории

Работа

Программист С
43 вакансии

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн