Результаты проверки работоспособности системы управления.
Рис.15. Импульсы управления ключами в Keil uVision3.
Как видно из рисунка импульсы генерируются с частотой 10 кГц (ширина импульса 50 мкс)
Рис.16. Прямая передача ( ).
Рис.17. Максимальная отбавка ( ).
Рис.18. Максимальная добавка ( ).
Рис.19. Импульсы при прямой передаче в Proteus.
Рис.20. Схема замкнутой системы в Proteus (без индикации и ввода вых. напряжения).
Рис.21. Стабилизация номинального напряжения при максимальном напряжении сети.
Рис.22. Стабилизированное номинальное напряжение.
Рис.23. Стабилизация номинального напряжения при минимальном напряжении сети.
Проверка работоспособности встроенного АЦП:
запуск результат
Рис.24. Схема индикации и ввода выходного напряжения.
При срабатывании защиты от короткого замыкания или превышения максимальной мощности дисплей отображает сигнал ошибки «Err» :
Рис.25. Сигнал аварии.
После нажатия на клавишу «сброс» стабилизатор работает на последнее допустимое введенное значение. После ввода цифровой клавиши две последующие в состоянии «_»:
Рис.26.Ввод первой цифры.
После ввода второй цифровой клавиши:
Рис.27. Ввод второй цифры.
После ввода третьей цифры:
Рис.28. Ввод третьей цифры.
Напряжение величиной 500 Вольт в рамках допустимого, значит после нажатия на клавишу «ввод» это значение преобразуется и «попадет» в регулятор, который сравнит его с сигналом обратной связи и выдаст нужный сигнал управления.
Печатная плата.
Размеры платы 90х70мм.
Рис.29. Размеры печатной платы.
Рис.30. Вехний слой проводников.
Рис.31. Нижний слой проводников.
Рис.32. Карта сверления отверстий.
Рис.33. 3D модель (вид сверху).
Рис.34. 3D модель (вид снизу).
Заключение
В процессе курсового проектирования было разработано устройство, позволяющее управлять работой силового преобразователя мощностью 5 кВА, который осуществляет регулирование и стабилизацию переменного напряжения в диапазоне 250…500 В, а также были предусмотрены:
- ввод значения выходного напряжения;
- индикация выходного напряжения;
- защита схемы от короткого замыкания в нагрузке и превышения максимальной мощности.
Список используемой литературы:
1. Микушин А. В. Занимательно о микроконтроллерах. – СПб.: БХВ-Петербург, 2006. – 432 с.
2. Бродин В. Б., Шагурин И. И. Микроконтроллеры. Архитектура, программирование, интерфейс. – М.: Издательство ЭКОМ, 1999. – 400 с.
3. Александров, К.К. Электротехнические чертежи и схемы / К.К. Александров, Е.Г. Кузьмина. – М.: Энергоатомиздат, 1990. – 288 с.
4. www.niiem46.ru
5. www.kingbright.com
6. www.analog.com
7. www.atmel.com
ПРИЛОЖЕНИЕ.
Листинг результата трансляции программы.
C51 COMPILER V8.05a ADC 12/28/2013 23:16:09 PAGE 1
C51 COMPILER V8.05a, COMPILATION OF MODULE ADC
OBJECT MODULE PLACED IN ADC.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE ADC.c BROWSE DEBUG OBJECTEXTEND
line level source
1 #include <t89c51ac2.h>
2 /*===============ОПРЕДЕЛЕНИЕ ПЕРЕМЕННЫХ=====================*/
3 unsigned char Xy, Xoc, Xz; // сигналы управления, обратной связи и задания
4 signed Xpacc; // сигнал ошибки
5 unsigned T_acp, T_indic, T_kbrd; // переменные контроля времени событий
6 unsigned char T_ind; // переменная, определяющая моменты индикации во время срабатывания за
-щиты
7 unsigned int Uz; // сигнал задания (Вольт)
8 perezapis; // биты разрешения перезаписи
10 /*++++++++++++++ЗАДЕРЖКА+++++++++++++++++*/
11 void DELAY(unsigned pause)
12 { unsigned int i; // при pause=454 задержка=454*2,2= 1 милисек.
13 1 for (i=pause;i>0;i--);
14 1 }
15 /*+++++++++++++++ЗАДЕРЖКА+++++++++++++++++*/
17 /******************АЦП**********************/
18 void SCAN_ADC()
19 { ADCON = 0x28; // Запуск АЦП, проверка окончания оцифровки
20 1 do { ACC=ADCON & 0x10; } // и сохранение результата в переменной
21 1 while(ACC==0); //перевод: 380=1,62В=165;
22 1 Xoc = ADDH; // 250=1,2В=122; 500=2В=204 ;
23 1 }
24 void INIT_ADC() //ИНИЦИАЛИЗАЦИЯ АЦП
25 {
26 1 ADCF = 0x00; // Выбор канала (Р1.0)
27 1 ADCLK = 1; // Установка частоты оцифровки
28 1 }
29 /******************АЦП**********************/
31 /*** ИНИЦИАЛИЗАЦИЯ ПРЕРЫВАНИЙ ***/
32 void INIT_interrupt()
33 {
34 1 EA = 1; // разрешение всех прерываний
35 1 EC = 1; // разрещение прерывания от РСА
36 1 EX0=1; // разрешение прерывания от входа INT0
37 1 EX1=1; // разрешение прерывания от входа INT1
38 1 IPH0=5; // Задание приоритетов
39 1 IPL0 = 0x45; // максимальный приоритет (3) для входов INT0, INT1
40 1 // меньше (1) для таймера РСА
41 1 }
42 /*** ИНИЦИАЛИЗАЦИЯ ПРЕРЫВАНИЙ ***/
44 /*=================PCA=====================*/
45 void INIT_PCA () //ИНИЦИАЛИЗАЦИЯ PCA
46 {
47 1 CL = 0x14; // загрузка начальных значений
48 1 CH = 0xFF; // в PCA таймер-счетчик
49 1 CF = 0; // сброс флага переполнения
50 1
51 1 CCAP0H = 0xFF; //загрузка значений в
52 1 CCAP0L = 0x15; //первый модуль ключ "К1"
-
-
C51 COMPILER V8.05a ADC 12/28/2013 23:16:09 PAGE 2
53 1
54 1 CCAP1H = 0xFF;
55 1 CCAP1L = 136; //второй модуль ключ "К3"
56 1 P1_5=0;
57 1 CCAP2H = 0xFF; //третий модуль (инверсия второго) ключ "К4"
58 1 CCAP2L = 136;
59 1 P1_6=0;
60 1 CCAP3H = 0xFF; //четвертый модуль (инверсия первого) ключ "К2"
61 1 CCAP3L = 0x15;
62 1
63 1 CCAPM0 = 0x4C; // выбор режима скоростного вывода-
64 1 CCAPM1 = 0x4C; // инверсия порта при совпадении значения
65 1 CCAPM2 = 0x4C; // соответствующего модуля с значением
66 1 CCAPM3 = 0x4C; // младшего регистра таймера-счетчика PCA
67 1
68 1 CMOD = 1; // Установка частоты РСА: Fosc/12
69 1 // разрешение прерывания от переполнения счетчика PCA
70 1 }
71 void PCA() interrupt 6
72 {CR=0; // остановка таймера PCA
73 1 CL=0x14; // загрузка в младший регистр счетчика
74 1 CH = 0xFF; // загрузка в старший регистр счетчика
75 1 CF = 0; // сброс флага переполнения
76 1 if(perezapis==1) // проверка необходимости перезаписи модулей
77 1 { perezapis=0;
78 2 P1=0xFF;
79 2 CL = 0x14;
80 2 CH = 0xFF;
81 2 CF = 0;
82 2 CCAP0H = 0xFF;
83 2 CCAP0L = 0x15;
-
-
84 2 CCAP1H = 0xFF;
85 2 CCAP1L = Xy;
86 2 P1_5=0; //после перезаписи модулей
87 2 CCAP2H = 0xFF; //начать выдачу импульсов
88 2 CCAP2L = Xy; //в прежнем режиме
89 2 P1_6=0;
90 2 CCAP3H = 0xFF;
91 2 CCAP3L = 0x15;
92 2 CCAPM0 = 0x4C; CCAPM1 = 0x4C; CCAPM2 = 0x4C; CCAPM3 = 0x4C;
93 2 CMOD = 1;
94 2 }
95 1 CR=1; // запуск PCA
96 1 if (T_acp>0) {T_acp--;} // приближение работы с АЦП
97 1 if (T_kbrd>0) {T_kbrd--;} // с клавиатурой
98 1 if (T_indic>0) {T_indic--;} // с индикатором
99 1 }
100 /******************PCA**********************/
102 /*============== КЛАВИАТУРА ================*/
103 #define ne_najata 0
104 #define najata 1
105 unsigned char key_value; // Значение нажатой клавиши
106 unsigned char digit; // Номер вводимой цифры
107 unsigned char DISPLAY[3]; // Массив со значениями,
108 // которые необходимо вывести на индикацию
109 unsigned char DISPLAY_pred[3]; // Массив, хранящий предыдущее введенное значение
110 bit key_status; // бит статуса клавиши ("нажата"/"не нажата")
112 unsigned char poisk_key_code() // обнаружение нажатой клавиши
C51 COMPILER V8.05a ADC 12/28/2013 23:16:09 PAGE 3
113 { unsigned char str_code;
114 1 P0 = 0x0F; //поиск строки
115 1 if(P0!=0x0F) {
116 2 str_code = ACC; // в аккумуляторе инверсия порта Р0
117 2 P0 = 0xF0; // поиск столбца
118 2 if(P0!=0xF0) { return(ACC+str_code); } // передать код клавиши
119 2 else { return(0); }
120 2 }
121 1 else { return(0); }
122 1 }
123 unsigned char poisk_key_value(unsigned char key_code) //Декодирование кода клавиши в значение клавиши
124 {unsigned char stroka, stolbec,value;
125 1 stroka = key_code & 0x0F;
126 1 stolbec = key_code >> 4;
127 1
128 1 switch (stroka)
129 1 {
130 2 case(8): value=(stolbec>>1)+9; break;
131 2 case(4): value=(stolbec>>1)+6; break;
132 2 case(2): value=(stolbec>>1)+3; break;
133 2 case(1): value=(stolbec>>1); break;
134 2 }
135 1 return(value);
136 1 }
138 void load_key_value() // загрузка значения клавиши в переменную
139 {
140 1 if(key_value<0x0A) // если цифра
141 1 {
142 2 if(digit==0) {
143 3 DISPLAY[0]=10; DISPLAY[1]=10; DISPLAY[2]=10; //при начале вводе заменить цифры символами "_"
144 3
145 3 }
146 2 if(digit<=2) // пока не будет введена 3-я цифра,
147 2 {
148 3 DISPLAY[digit]=key_value; // сохранять введённые значения в массиве.
149 3 digit++;
150 3 }
151 2 }
152 1 else {
153 2 if(key_value==0x0A) // если после ввода любой цифры нажата клавиша "сброс" -
154 2 {
155 3 DISPLAY[0]=DISPLAY_pred[0]; // вернуть в массив
156 3 DISPLAY[1]=DISPLAY_pred[1]; // предыдущие
157 3 DISPLAY[2]=DISPLAY_pred[2]; // значения
158 3 digit=0;
159 3 }
160 2 if(key_value==0x0B && digit>=3) // если после ввода 3-ей цифры нажата клавиша "ввод" -
161 2 {
162 3 // перезаписать массив предыдущих значений,
163 3 Uz = DISPLAY[0]*100 + DISPLAY[1]*10 + DISPLAY[2]; // вычислить введённое значение задания
164 3 if (Uz>500 || Uz<250){DISPLAY[0]=3; DISPLAY[1]=8; DISPLAY[2]=0;}
165 3 else {DISPLAY_pred[0]=DISPLAY[0]; DISPLAY_pred[1]=DISPLAY[1]; DISPLAY_pred[2]=DISPLAY[2];}
166 3 digit=0;
167 3 }
168 2 }
169 1 }
171 scan_kbrd() // ОПРОС КЛАВИАТУРЫ
172 {
173 1 unsigned char key_code;
174 1 key_code=poisk_key_code(); //переменная кода клавиши
C51 COMPILER V8.05a ADC 12/28/2013 23:16:09 PAGE 4
175 1
176 1 if(key_code!=0)
177 1 {
178 2 if(key_status==ne_najata)
179 2 {
180 3 key_value=poisk_key_value(key_code);
181 3 load_key_value();
182 3 key_status=najata;
183 3 }
184 2 }
185 1 if(key_code==0) {key_status=ne_najata;}
186 1
187 1 }
188 /*============ КЛАВИАТУРА ============*/
190 /*------------ИНДИКАТОР------------*/
191 sbit OUT100 = P3^7; // биты
192 sbit OUT10 = P3^6; // выбора
193 sbit OUT1 = P3^5; // номера цифры
194 // коды семисегментного индикатора, соответствующие символам "0-9", "_", "Е", "r"
195 code char indicator_code[13]={ 0x80, 0xF2, 0x48, 0x60, 0x32,
196 0x24, 0x04, 0xF1, 0x00, 0x20, 0xEF, 0x0D, 0x5F };
197 unsigned char razrad; // переменная, определяющая номер выводимого на индикацию разряда
198 unsigned char T_ind; // переменная, определяющая моменты индикации во время срабатывания защиты
200 void print()
201 {
202 1 unsigned char simbol;
203 1 /* gfed cba
204 1 ----------
205 1 0 | 1000 0001
206 1 1 | 1111 0011
207 1 2 | 0100 1001 таблица
208 1 3 | 0110 0001 соответствия 0 OUT100
209 1 4 | 0011 0011 кодов 1 OU10
210 1 5 | 0010 0101 7-сегментного 2 OUT1
211 1 6 | 0000 0101 индикатора
212 1 7 | 1111 0001 отображаемым символам
213 1 8 | 0000 0001
214 1 9 | 0010 0001
215 1 _ | 1110 1111
216 1 E | 0000 1101
217 1 r | 0101 1111
218 1 */
219 1 simbol=DISPLAY[razrad-1];
220 1 P2=0xFF; // гашение символа
221 1 OUT100=1; // отключение
222 1 OUT10=1; // всех разрядов
223 1 OUT1=1;
224 1
225 1 P2 = indicator_code[simbol]; // выдача символа на порт
226 1 // подключение необходимого разряда
227 1 switch(razrad)
228 1 {
229 2 case(3): OUT1=0; break;
230 2 case(2): OUT10=0; break;
231 2 case(1): OUT100=0; break;
232 2 }
233 1 razrad++;
234 1 if(razrad>3) razrad=0;
235 1 }
236 /*------------ИНДИКАТОР------------*/
C51 COMPILER V8.05a ADC 12/28/2013 23:16:09 PAGE 5
238 /*___________ЗАЩИТА___________*/
240 void K_Z () interrupt 0 // обработка прерывания от входа INT0 (короткое замыкание)
241 {
242 1 unsigned char key_code;
243 1 CR=0; // Остановка таймера РСА
244 1 P1=0; // Снятие импульсов управления
245 1
246 1 // Запись в массив индикации выхода кодов символов "Err"
247 1 DISPLAY[0]=11; DISPLAY[1]=12; DISPLAY[2]=12;
248 1
249 1 do { key_code=poisk_key_code(); // Опрос клавиатуры и
250 2 T_ind--;
251 2 if(T_ind==0)
252 2 {
253 3 print(); // индикация
254 3 T_ind=100;
255 3 }
256 2 }
257 1 while(key_code!=0x28); // пока не будет нажата клавиша "Сброс"
258 1 INIT_PCA(); // инициализация РСА
259 1 CR=1; // Запуск таймера РСА
260 1 }
261 void MAX_POWER() interrupt 2 //обработка прерывания от входа INT1 (превышение максимальной мощности)
262 {
263 1 unsigned char key_code;
264 1 CR=0;
265 1 P1=0;
266 1
267 1 DISPLAY[0]=11; DISPLAY[1]=12; DISPLAY[2]=12;
268 1
269 1 do { key_code=poisk_key_code();
270 2 T_ind--;
271 2 if(T_ind==0)
272 2 {
273 3 print();
274 3 T_ind=100;
275 3 }
276 2 }
277 1 while(key_code!=0x28);
278 1 INIT_PCA();
279 1 CR=1;
280 1 }
281 /*___________ЗАЩИТА___________*/
283 /******************РЕГУЛЯТОР**********************/
284 void regulyator ()
285 {
286 1 Xz=33*(Uz+39)/100+27; // привидение напряжения задания к аналогичным значениям АЦП (122...204)
-
287 1 Xpacc=Xz-Xoc; // переменная рассогласования (ошибка)
288 1 if (Xpacc!=0) // проверка ошибки
289 1 {if (Xz > Xoc)
290 2 {Xy = Xy - 1; perezapis=1;} // добавка напряжения
291 2 else {Xy = Xy +1; perezapis=1;} // отбавка напряжения
292 2 }
293 1 }
294 /******************РЕГУЛЯТОР**********************/
296 /*****ОСНОВНАЯ ПРОГРАММА****/
297 void main ()
C51 COMPILER V8.05a ADC 12/28/2013 23:16:09 PAGE 6
298 {
299 1 Uz=380; // cтартовый сигнал задания
300 1
301 1 DISPLAY[0]=3; // запись в массив индикации
302 1 DISPLAY[1]=8; // значений, соответствующих номинальному заданию (380)
303 1 DISPLAY[2]=0;
304 1 Xoc=165; // cтартовый сигнал обратной связи, соответствующий 380 В
305 1 // (нач. условие для регулятора)
306 1
307 1 Xy=136; // стартовый сигнал управления, соответствующий
308 1 // режиму прямой передачи (Пределы при номинальном входном: 66...206)
309 1 INIT_ADC();
310 1 INIT_PCA();
311 1 INIT_interrupt();
312 1 CR = 1;
313 1 DELAY(65000); // задержка перед началом опроса выходного
314 1 DELAY(65000); // напряжения (после установления переходного процесса)
315 1 T_acp=2300;
316 1 T_kbrd=385;
317 1 T_indic=100;
318 1
319 1 while (1) // цикл основной программы
320 1 {
321 2 if (T_acp==0) {
322 3 SCAN_ADC();
323 3 regulyator ();
324 3 T_acp=2300; // опрос АЦП раз в 120 мс (чуть больше постоянной времени внешнего датчика напряжения)
325 3 }
326 2 if (T_kbrd==0) {
327 3 scan_kbrd(); // опрос клавиатуры
328 3 T_kbrd=385; // раз в период (20 мс)
329 3 }
330 2 if (T_indic==0) {
331 3 print(); // вывод на индикацию выходного напряжения
332 3 T_indic=100; // для каждого разряда с частотой 200 Гц
333 3 }
334 2 }
335 1 }
336 /*********КОНЕЦ*************/
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 868 ----
CONSTANT SIZE = 13 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 25 ----
IDATA SIZE = ---- ----
BIT SIZE = 1 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)