- •Введение.
- •Описание схемы преобразователя.
- •Функциональная схема системы.
- •4. Описание основных функциональных блоков системы и выбор элементной базы.
- •5. Разработка подсистемы защит
- •6. Алгоритм работы системы управления.
- •7. Текст программы с пояснениями.
- •8. Результаты проверки работоспособности системы управления.
- •9. Печатная плата.
- •Заключение
- •Список используемой литературы:
- •Приложение.
Заключение
В процессе курсового проектирования было разработано устройство, позволяющее управлять работой силового преобразователя мощностью 5 кВА, который осуществляет регулирование и стабилизацию переменного напряжения в диапазоне 250…500 В, а также были предусмотрены:
- ввод значения выходного напряжения;
- индикация выходного напряжения;
- защита схемы от короткого замыкания в нагрузке и превышения максимальной мощности.
Список используемой литературы:
Микушин А. В. Занимательно о микроконтроллерах. – СПб.: БХВ-Петербург, 2006. – 432 с.
Бродин В. Б., Шагурин И. И. Микроконтроллеры. Архитектура, программирование, интерфейс. – М.: Издательство ЭКОМ, 1999. – 400 с.
Александров, К.К. Электротехнические чертежи и схемы / К.К. Александров, Е.Г. Кузьмина. – М.: Энергоатомиздат, 1990. – 288 с.
www.niiem46.ru
www.kingbright.com
www.analog.com
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; // биты разрешения перезаписи
9
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 /*+++++++++++++++ЗАДЕРЖКА+++++++++++++++++*/
16
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 /******************АЦП**********************/
30
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 /*** ИНИЦИАЛИЗАЦИЯ ПРЕРЫВАНИЙ ***/
43
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**********************/
101
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; // бит статуса клавиши ("нажата"/"не нажата")
111
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 }
137
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 }
170
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 /*============ КЛАВИАТУРА ============*/
189
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; // переменная, определяющая моменты индикации во время срабатывания защиты
199
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
237
238 /*___________ЗАЩИТА___________*/
239
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 /*___________ЗАЩИТА___________*/
282
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 /******************РЕГУЛЯТОР**********************/
295
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)