![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Пример кода
Приведенный код, который используется, чтобы управлять усилителем, состоит из кода инициализации и цикла опроса. Цикл опроса непрерывно проверяет изменение в состоянии переключателей на лицевой панели блока (PORTB) или дистанционном управлении (PORTA). Алгоритм управления UML приведен на рис. 8.19.
Рис. 8.19. Алгоритм программы UML для усилителя //file name: ampl2.с //function: program provides control of amplifier //target controller: Motorola 68HC912B32 evaluation board (EVB) // - 32K Flash EEPROM available at $8000 // - Compiler options: // - Program Memory: 0x8000 // - DataMemory: 0x0800 // - Stack Pointer: 0x09FF // // Эта программа обеспечивает управление звуковым усилителем. // Усилитель может принимать звуковой сигнал от ряда // источников. Пользователь может выбирать источник сигнала // для усиления с помощью переключателей на лицевой панели // (связанных с портом B), либо переключателей на пульте // дистанционного управления (связанных с портом A). Процессор // управляет светодиодами на передней панели(связанными с портом P) // и показывающими активный источник сигнала и включает реле(связанные // с портом T), подсоединяющие один из источников сигнала к усилителю // // Функции портов ввода // // Порт А, входной - вводит сигналы от пульта дистанционного управления, // требует импульсов высокого логического уровня длительностью в 100 мс // PA7 выкл. звука от пульта дист. управления высокий - импульс 100 мс // PA6 Дополнительный канал (ДК) от пульта дист. управления высокий // импульс 100 мс // PA5 магнитофон # 2 от пульта дист. управления высокий - импульс 100 мс // PA4 магнитофон # 1 от пульта дист. управления высокий - импульс 100 мс // PA3 тюнер от пульта дист. управления высокий - импульс 100 мс // PA2 CD от пульта дист. управления высокий - импульс 100 мс // PA1 пианино от пульта дист. управления высокий - импульс 100 мс // PA0 предусилитель от пульта дист. управления высокий - импульс 100 мс // Порт В входной - от переключателей на лицевой панели блока // PB0 предусилитель от переключателя на лицевой панели, вжатый перек- // лючатель = вкл // PB1 пианино от переключателя на лицевой панели, вжатый переключатель = вкл // PB2 CD от переключателя на лицевой панели, вжатый переключатель = вкл // PB3 тюнер от переключателя на лицевой панели, вжатый переключатель = вкл // PB4 магнитофон # 1 от переключателя на лицевой панели, вжатый пе- // реключатель = вкл // PB5 магнитофон # 2 от переключателя на лицевой панели, вжатый пе- // реключатель = вкл // PB6 ДК от переключателя на лицевой панели, вжатый переключатель = вкл // PB7 выкл. звука от переключателя на лицевой панели, вжатый перек- // лючатель = вкл // //Порт P выходной - светодиоды на лицевой панели //PP0 сигнал на силовое реле и на светодиоды и сигнал низкого уровня //для //светодиодов в буфер //PP1 светодиод пианино выходной низкопотенциальный сигнал - 10 мА //PP2 светодиод CD выходной низкопотенциальный сигнал - 10 мА //PP3 светодиод тюнер выходной низкопотенциальный сигнал - 10 мА //PP4 светодиод магнитофон # 1 выходной низкопотенциальный сигнал - 10 мА //PP5 светодиод магнитофон # 2 выходной низкопотенциальный сигнал - 10 мА //PP6 светодиод ДК выходной низкопотенциальный сигнал - 10 мА //PP7 светодиод выкл. звука, сигнал на силовое реле // //Порт T выходной - драйверы реле //PT0 реле RESET выход на реле RESET высокий уровень - импульс 5 мс //PT1 реле пианино выход на реле пианино высокий уровень - импульс 5 мс //PT2 реле CD выход на реле CD высокий уровень - импульс 5 мс //PT3 реле тюнера выход на реле тюнера высокий уровень - импульс 5 мс //PT4 реле магнитофон # 1 выход на реле магнитофон # 1 высокий уро- //вень - импульс 5 мс //PT4 реле магнитофон # 2 выход на реле магнитофон # 2 высокий уро- //вень - импульс 5 мс //PT6 реле ДК выход на реле ДК высокий уровень //- импульс 5 мс //PT7 высокий уровень - импульс 10 мс для подачи питания на оптроны //светодиодов и усилитель //Подача питания (от сети или от источника 5 В): //Конфигурация портов: //1. Порт A: конфигурирован как входной, отжатый переключатель - запрет //2. Порт B: конфигурирован как входной, отжатый переключатель - разрешение //3. Порт P: конфигурирован как выходной, все линии в 1 //4. Порт T: конфигурирован как выходной, все линии в 0 //5. Установка " RELAY-RESET" (PTO) импульсом высокого состояния 5 мс //6. Установка " RELAY-CD" (PT2) импульсом высокого состояния 5 мс //7. Установка " WHICH-INPUT" позиция сохранения = " CD" //8. Цикл PP1-РР6 (устанавливаются в низкое состояние) светодиоды // показывают, что контроллер работает //9. Переход к последовательности " PREAMP ON" // //Логика работы: //Последовательность " PREAMP ON" //1. Ожидание установки " S-PREAMP-PWR" (PB0) или " R-PREAMP-PWR" (РАО) //2. Установка " LED-MUTE-RELAY" (PP7) //3. Установка " LED-PWR-RELAY" (PP0) //4. Считывание позиции в " WHICH-INPUT" //5. Установка " LED-xxxxx" = позиция " WHICH-INPUT" //6. Установка PT7(1) импульсом 10 мс //7. DE-Assert " LED-MUTE-RELAY" (PP7) через ~3 с. //8. переход к режиму " SCAN" // //Последовательность " SCAN" //1.Ожидание входного сигнала от (PB0-PB7) или от (PA0-PA7) //2. IF = " x-PREAMP-PWR" - переход к последовательности " PREAMP OFF" //3. IF = " x-MUTE" GOTO - переход к последовательности " MUTE" //4. IF = любой входной сигнал от (PB1-PB6) или (PA1-PA6)- переход к " CHANGE" // последовательность " INPUT" // // последовательность " CHANGE INPUT": //1. Включить " LED-MUTE-RELAY" (PP7) //2. Включить " RELAY-RESET" (PT0) импульсом высокого уровня 5 мс //3. Включить " RELAY-xxxxx" (PT1-PT6) (в соответствии с выбором // " WHICH-INPUT" импульсом высокого уровня 5 мс) //4. Включить " LED-xxxxx" (PP1-PP6) (в соответствии с выбором // " WHICH-INPUT") //5. Очистить Old/Input сохранить новое значение " WHICH-INPUT" //6. DE-переключение " MUTE-RELAY" (PP7) примерно через 3 с. //7. Перейти к последовательности " SCAN" // // последовательность " MUTE": //1. Переключить " LED-MUTE-RELAY" (PP7) //2. Перейти к последовательности " SCAN" // //Последовательность " PREAMP OFF": //1. Включить " LED-MUTE-RELAY" (PP7) //2. DE-переключение " LED-PWR-RELAY" (PP0) //3. DE-переключение всех светодиодов (PP1-РР6) //4. Включить PT7(1) импульсом 10 мс //5. DE-переключение " LED-MUTE-RELAY" (PP7) примерно через 3 с. //6. Перейти к последовательности " PREAMP ON" // //авторы: Steven Barrett и Daniel Pack //Дата разработки: 19 июня 2004 //Последняя редакция: 20 июня 2004 //*******************************************************************
//******************************************************************* //включенные файлы #include < 912b32.h> //B32 EVB header file #include " func_def.h" //функции-прототипы, глобальные переменные
//main program******************************************************* // глобальные переменные int which_input; //вход усилителя int keep_going; //ввод переменных int mute; //флаг управления выключением звука unsigned char old_PORTB = 0xff; //текущие значения PORTB unsigned char old_PORTA = 0x00; //текущие значения PORTA unsigned char new_PORTB, new_PORTA; //новые значения PORTA, PORTB
void main(void) { asm(".area vectors(abs)\n" ".org 0xFFF8\n" //инициализация вектора сброса для 68HC12 B32 ".word 0x8000, 0x8000, 0x8000, 0x8000\n" ".text"); initialize_task(); //главный цикл while(1) { //ожидается сигнал на включение питания if ((PORTB==0xFE)||(PORTA==0X01)) //PORTB переключается в низкое, PORTA - в // высокое состояние { //вы забыли включить питание! Запрос на операцию включения keep_going = 1; //цикл считывания переменных PORTP=0x7E; //включение LED-MUTE-RELAY PP7(0) //LED-PWR-RELAY PP0(0) (0111_1110) which_input_task(); activate_power_relay_task(); delay_3s(); //задержка 3 с. PORTP = 0x80; // DE-переключение PD7(1) - включение звука while(keep_going) //прохождение меню - главный цикл опроса { process_PORTB_input_task(); process_PORTA_input_task(); } }//end if - ожидание включения питания - питание не подано! }//end while(1) }//конец главного цикла
//******************************************************************* // определение функций //*******************************************************************
initialize_task: начальные установки усилителя //******************************************************************* void initialize_task(void) { mute = on; //turn mute on initialize_timer(); // инициализация таймера initialize_ports(); // инициализация портов initialize_pins(); // инициализация состояния отдельных выводов which_input = 2; //по умолчанию включается вход CD(2) //включение светодиодов на лицевой панели PORTP = 0x81; //включение всех светодиодов PD1-PD6 низким активным // уровнем (1000_0001) delay_3s(); //задержка 3 с PORTP = 0xff; //выключение светодиодов }
//******************************************************************* //which_input_task: опрос входов, установка текущего состояния //******************************************************************* void which_input_task(void) { switch(which_input) { // подсвечивается светодиод для используемого // входа (по умолчанию вход 2 - CD) case 1: //Пианино phono_task(); break; case 2: //CD CD_task(); break; case 3: //Тюнер tuner_task(); break; case 4: //Магнитофон 1 tape1_task(); break; case 5: //Магнитофон 2 tape2_task(); break; case 6: //Дополнительный канал (ДК) aux_task(); break; default:; }//конец switch }
//******************************************************************* //phono_task: конфигурируется вход от Радио //******************************************************************* void phono_task(void) { PORTT |= 0x02; //устанавливается PT1(1) (0000_0010) delay_5ms(); PORTT & = ~0x02; // выключается PT1(0) PORTP = 0x7E; //гасятся все светодиоды PORTP & = ~0x02; //включается светодиод 1 (0) }
//****************************************************************** //CD_task: конфигурируется вход от CD //****************************************************************** void CD_task(void) { //CD PORTT |= 0x04; // устанавливается PT2(1) (0000_0100) delay_5ms(); PORTT & = ~0x04; // выключается PT2(0) PORTP |= 0x7E; //гасятся все светодиоды PORTP & = ~0x04; // включается светодиод 2 (0) }
//****************************************************************** //tuner_task: конфигурируется вход от тюнера //****************************************************************** void tuner_task(void) { //TUNER PORTT |= 0x08; // устанавливается PT3(1) (0000_1000) delay_5ms(); PORTT & = 0x08; // выключается PT3(0 PORTP |= 0x7E; //гасятся все светодиоды PORTP & = ~0x08; // включается светодиод 3 (0) }
//****************************************************************** //tape1_task: конфигурируется вход от магнитофона 1 //****************************************************************** void tape1_task(void) { //TAPE#1 PORTT |= 0x10; //assert PT4(1) (0001_0000) delay_5ms(); PORTT & = ~0x10; // выключается PT4(0) PORTP |= 0x7E; //гасятся все светодиоды PORTP & = ~0x10; // включается светодиод 4 (0) }
//****************************************************************** //tape2_task: конфигурируется вход от магнитофона 2 //****************************************************************** void tape2_task(void) { //TAPE#2 PORTT |= 0x20; // устанавливается PT5(1) (0010_0000) delay_5ms(); PORTT & = ~0x20; // выключается PT5(0) PORTP |= 0x7E; //гасятся все светодиоды PORTP & = ~0x20; // включается светодиод 5 (0) }
//****************************************************************** //aux_task: конфигурируется вход от дополнительного канала //****************************************************************** void aux_task(void) { //ДК PORTT |= 0x40; // устанавливается PT6(1) (0100_0000) delay_5ms(); PORTT & = ~0x40; // выключается PT6(0) PORTP |= 0x7E; //гасятся все светодиоды PORTP & = ~0x40; // включается светодиод 6(0) }
//****************************************************************** //activate_power_relay_task(): включается реле силового питания //****************************************************************** void activate_power_relay_task(void) { PORTT |= 0x80; // устанавливается PT7(1) импульсом 10 мс delay_5ms(); delay_5ms(); PORTT & = ~0x80; // выключается PT7 }
//****************************************************************** //process_PORTB_input_task(): определяется выбранный вход от PORTB //****************************************************************** void process_PORTB_input_task(void) { new_PORTB = PORTB; //read PORTB if (new_PORTB! = old_PORTB) { //считывание состояния порта PORTB switch(new_PORTB) { //PORTB устанавливается на низкий уровень case 0xFE: //PB0 " S-PREAMP-PWR" (1111_1110) if (process_valid_input_PORTB(new_PORTB)) { preamp_off(); keep_going=0; } break; case 0xFD: //PB1 " S-PHONO" (1111_1101) if (which_input! =1) { if (process_valid_input_PORTB(new_PORTB) { which_input = 1; change_input(); } } break; case 0xFB: //PB2 " S-CD" (1111_1011) if (which_input! =2) { if (process_valid_input_PORTB(new_PORTB)) { which_input = 2; change_input(); } } break; case 0xF7: //PB3 " S-TUNER" (1111_0111) if (which_input! = 3) { if (process_valid_input_PORTB(new_PORTB)) { which_input = 3; change_input(); } } break; case 0xEF: //PB4 " S-TAPE#1" (1110_1111) if (which_input! = 4) { if (process_valid_input_PORTB(new_PORTB)) { which_input = 4; change_input(); } } break; case 0xDF: //PB5 " S-TAPE#2" (1101_1111) if (which_input! = 5) { if (process_valid_input_PORTB(new_PORTB)) { which_input = 5; change_input(); } } break; case 0xBF: //PB6 " S-AUX" (1011_1111) if (which_input! = 6) { if (process_valid_input_PORTB(new_PORTB)) { which_input = 6; change_input(); } } break; case 0x7F: //PB7 " S-MUTE" (0111_1111) if (process_valid_input_PORTB(new_PORTB)) { mute_toggle(); } break; default:; //all other cases } //конец switch(new_PORTB) } //конец if new_PORTB old_PORTB=new_PORTB; //update PORTB }
//****************************************************************** //process_PORTA_input_task(): определяется выбранный вход от PORTA //****************************************************************** void process_PORTA_input_task(void) { new_PORTA = PORTA; //Читать PORTA if (new_PORTA! = old_PORTA) { //выбор входа по состоянию порта PORTA switch (new_PORTA) { //PORTA переводится в высокое состояние case 0x01: //РАО " R-PREAMP-PWR" (0000_0001) if (process_valid_input_PORTA(new_PORTA)) { preamp_off(); keep_going=0; } break; case 0x02: //PA1 R-PHONO" (0000_0010) if (which_input! = 1) { if (process_valid_input_PORTA(new_PORTA)) { which_input = 1; change_input(); } } break; case 0x04: //PA2 " R-CD" (0000_0100) if (which_input! = 2) { if (process_valid_input_PORTA(new_PORTA)) { which_input = 2; change_input(); } } break; case 0x08: //РАЗ " R-TUNER" (0000_1000) if (which_input! = 3) { if (process_valid_input_PORTA(new_PORTA)) { which_input = 3; change_input(); } } break; case 0x10: //PA4 " R-TAPE#1" (0001_0000) if (which_input! = 4) { if (process_valid_input_PORTA(new_PORTA)) { which_input = 4; change_input(); } } break; case 0x20: //PA5 " R-TAPE#2M (0010_0000) if (which_input! = 5) { if (process_valid_input_PORTA(new_PORTA)) { which_input = 5; change_input(); } } break; case 0x40: //PA6 " R-ДОПОЛНИТЕЛЬНЫЙ КАНАЛ" (0100_0000) if (which_input! = 6) { if (process_valid_input_PORTA(new_PORTA)) { which_input = 6; change_input(); } } break; case 0x80: //PA7 " R-MUTE" (1000_0000) if (process_valid_input_PORTA(new_PORTA)) { mute_toggle(); } break; default:; //all other cases } //конец switch(new_PORTA) }//конец if new_PORTA old_PORTA = new_PORTA; //изменяется состояние PORTA }
//****************************************************************** //initialize_timer: установка частоты таймера обслуживающего счетчик //****************************************************************** void initialize_timer(void) { TMSK2 = 0x05; //установка на 250 КГц TSCR = 0x80; //разрешение работы таймера }
//****************************************************************** //initialize_ports: начальная конфигурация портов //****************************************************************** void initialize_ports(void) { DDRA=0x00; //конфигурация PORTA в качестве входного PORTA=0x00; //запрет на подключение подтягивающих резисторов в PORTA DDRB=0x00; //конфигурация PORTB в качестве входного PORTB=0xff; //разрешение подключения подтягивающих резисторов в PORTB DDRT=0xff; // конфигурация PORTT в качестве выходного PORTT=0x00; // установка на низкий уровень DDRP=0xff; // конфигурация PORTD в качестве выходного PORTP=0xff // установка на высокий уровень } //******************************************************************
//****************************************************************** //initialize_pins: установка отдельных выводов //****************************************************************** void initialize_pins(void) { PORTT=0x01; //сброс реле PT0(1) 5 мс импульс с // активным уровнем (0000_0001) //delay_5ms(): PORTT=0x00; }
//****************************************************************** //delay_5ms: Задержка на 5 мс сформированная из базе частоты таймера //в 250 кГц //****************************************************************** void delay_5ms(void) { int i; for(i=0; i< 1250; i++) asm(" nop"); //требуется только один импульс таймера }
//****************************************************************** //delay_3s: Задержка на 3 с //****************************************************************** void delay_3s(void) { int i; for(i=0; i< 600; i++) delay_5ms(); }
//****************************************************************** //change_input: изменение активного входа //****************************************************************** void change_input(void) { PORTP & = ~0x80; //установка LED-MUTE-RELAY PP7(0) 1000_0000 PORTT |= 0x01; //установка сброса реле PT0(l) 5 мс delay_5ms(); PORTT & = ~0x01; //turn off PT0 switch(which_input) { case 1: //PHONO phono_task(); break; case 2: //CD CD_task(); break; case 3: //TUNER tuner_task(); break; case 4: //TAPE#1 tape1_task(); break; case 5: //TAPE#2 tape2_task(); break; case 6: //AUX aux_task(); break; default:; //все другие входы }//конец switch delay _3s(); PORTP |= 0x80; //сброс LED-MUTE-RELAY PP7(1) }
//****************************************************************** //mute_toggle: включение и выключение звука //****************************************************************** void mute_toggle(void) { if (mute == off) { PORTP & = ~0x80; //установка LED-MUTE-RELAY PP7(0) mute = on; } else { PORTP |= 0x80; // сброс LED-MUTE-RELAY PP7(1) mute = off; } }//end mute_toggle
//****************************************************************** //preamp_off: turn amplifier off //****************************************************************** void preamp_off(void) { PORTP & = ~0x80; //установка LED-MUTE-RELAY PP7(0) PORTP |= 0x01; //сброс LED-PWR-RELAY PP0(1) PORTP |= 0x7e; //сброс светодиодов PP1-PP6(1)(0111_1110) //установка PT7 импульсом 10 мс PORTT |= 0x80; //установка PT7(1) импульсом 10 мс delay_5ms(); delay_5ms(); PORTT & = ~0x80; //сброс PT7 delay_3s(); PORTP = 0x80; //сброс PP7(1) LED-MUTE-RELAY keep_going=0; }
//****************************************************************** //process_valid_input_PORTA: проверка состояния пульта дистанционного //управления, длительностью не менее 50 мс //****************************************************************** int process_valid_input_PORTA(unsigned char portx) { int valid_input; //установить флаг ошибочного входа unsigned int current_count; valid_input = TRUE; current_count = TCNT; // задать текущее состояние while (TCNT < (current_count+12500)) { //отследить активный вход за 50 мс if (portx==PORTA) valid_input = TRUE; else valid_input = FALSE; if (! valid_input) break; //цикл while }//end while return valid_input; }
//****************************************************************** //process_valid_input_PORTB: проверка состояния переключателей на //лицевой панели, длительностью не менее 50 мс //****************************************************************** int process_valid_input_PORTB(unsigned char portx) { int valid_input; //установить флаг ошибочного входа unsigned int current_count; valid_input = TRUE; current_count = TCNT; // задать текущее состояние while (TCNT < (current_count+12500)){ //отследить активный вход за 50 мс if (portx==PORTB) valid_input = TRUE; else valid_input = FALSE; if (! valid_input) break; //цикл while }//конец while return valid_input; } //****************************************************************** //******************************************************************
|