8.8.2. Пример кода
Приведенный код, который используется, чтобы управлять усилителем, состоит из кода инициализации и цикла опроса. Цикл опроса непрерывно проверяет изменение в состоянии переключателей на лицевой панели блока (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;
}
//******************************************************************
//******************************************************************
- Встраиваемые системы Проектирование приложений на микроконтроллерах семейства 68hc12/hcs12 с применением языка с с. Ф. Баррет
- Предисловие
- Структура книги
- Учебные системы
- Целевая аудитория
- Благодарности
- Глава 1 первое знакомство со встраиваемыми системами
- 1.1. Что такое встраиваемая система?
- 1.2. Особенности встраиваемых систем
- 1.2.1. Работа в реальном времени
- 1.2.2. Миниатюризация размеров и процесс тестирования
- 1.2.3. Минимизация энергии потребления
- 1.2.4. Интерфейс пользователя и интерфейс сопряжения с объектом
- 1.2.5. Многозадачность
- 1.2.6. Минимизация стоимости
- 1.2.7. Ограничение объема памяти
- 1.2.8. Программно–аппаратный дуализм
- 1.3. Введение в микроконтроллеры семейства 68hc12 и hcs12
- 1.4 Микроконтроллеры hcs12
- 1.4.1. Семейство hcs12
- 1.4.2. Обозначения мк
- 1.4.3. Модельный ряд hcs12
- 1.5. Заключение по главе 1
- 1.6. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 2 программирование встраиваемых систем и структурное проектирование
- 2.1. Почему мы программируем микроконтроллеры на Си?
- 2.2. Преимущества программирования на языке ассемблер
- 2.3. Преимущества языков высокого уровня
- 2.3.1. Выбираем язык высокого уровня для программирования встраиваемых систем
- 2.3.2. Краткая история языка Си
- 2.4. Оптимальная стратегия — программирование на Си и на ассемблере
- 2.5. Структурное проектирование
- 2.5.1. Основные положения метода структурного проектирования
- 2.5.2. Документирование программ
- 2.5.3. Как язык Си соотносится со структурным проектированием
- 2.6. Рабочие тетради
- 2.6.1. Порядок ведения записей
- 2.6.2. Содержание записей
- 2.7. Блок схемы алгоритмов
- 2.8. Пример применения
- 2.9. Заключение по главе 2
- 2.10 Что еще почитать?
- 2.11 Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 3 основы программирования микроконтроллеров на си
- 3.1. Введение в программирование на Си
- 3.1.1. Глобальные и локальные переменные
- 3.2. Типы данных в Си
- 3.3. Операторы языка Си
- 3.4. Функции
- 3.4.1. Что такое функция?
- 3.4.2. Основная программа
- 3.4.3. Прототипы функций
- 3.4.4. Описание функций
- 3.4.5. Вызов функций, передача параметров, возврат полученных значений
- 3.5. Файлы заголовков
- 3.6. Директивы компилятора
- 3.6.1. Директивы условной компиляции
- 3.7. Конструкции программирования
- 3.8. Операторы для организации программных циклов
- 3.8.1. Оператор for
- 3.8.2. Оператор while
- 3.8.3. Оператор do-while
- 3.9. Операторы принятия решения
- 3.9.1. Оператор if
- 3.9.2. Оператор if-else
- 3.9.3. Оператор if-else if-else
- 3.9.4. Оператор switch
- 3.10. Массивы
- 3.11. Указатели
- 3.12. Структуры
- 3.13. Процесс программирования и отладки микропроцессорной системы
- 3.13.1. Технология создания программного кода
- 3.13.2. Режим отладки bdm
- 3.13.3. Аппаратные и программные средства отладчика p&e от компании pemicro
- 3.13.4. Эмуляторы
- 3.13.5. Логические анализаторы
- 3.14. Особенности компилятора и ассемблера
- 3.15. Заключение по главе 3
- 3.16. Что еще почитать?
- 3.17. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 4 микроконтроллеры 68hc12 и hcs12: архитектура и программирование
- 4.1. Аппаратные средства микроконтроллеров семейства 68hc12
- 4.2. Аппаратные средства мк семейства hcs12
- 4.3. Режимы работы мк семейства 68hc12/hcs12
- 4.3.1. Рабочие режимы
- 4.3.2. Режимы работы отладочной платы m68evb912b32
- 4.4. Назначение выводов мк
- 4.5. Регистры специальных функций мк
- 4.5.1. Виртуальный адрес блока регистров
- 4.6. Порты ввода/вывода
- 4.6.1. Спецификация портов ввода/вывода
- Регистры управления портами
- Вопросы для самопроверки
- Пример применения
- 4.7. Подсистема памяти мк b32
- Пример применения
- 4.7.1. Карта памяти мк b32
- 4.7.2. Изменение адресов в карте памяти мк
- 4.8. Подсистема памяти мк dp256
- Вопросы для самопроверки
- 4.9. Состояния сброса и прерывания мк
- 4.9.1. Реакция мк на внешние события
- 4.10. Состояния сброса и прерывания в мк 68hc12
- 4.10.1. Состояние сброса мк
- Регистры сторожевого таймера и монитора тактирования
- 4.10.2. Прерывания
- Немаскируемые прерывания
- Маскируемые прерывания
- Вопросы для самопроверки
- 3. Каково различие между прерываниями по входам
- 4. Как организовать подсистему прерывания с несколькими внешними запросами для мк семейства 68hc12/hcs12, используя лишь один вход внешнего прерывания
- 4.10.3. Вектора исключений
- 4.10.4. Система приоритетов для исключений
- 1. Внешний сброс по входу
- 5. Немаскируемое прерывание по входу
- Вопросы для самопроверки
- 4. Какие действия должен предпринять программист, чтобы после начального запуска мк присвоить входу
- 4.10.5. Регистры подсистемы прерывания
- 4.11. Процесс перехода к подпрограмме прерывания
- Вопросы для самопроверки
- 4.12. Оформление подпрограммы прерывания на Си
- 4.13. Система тактирования
- 4.13.1.Система тактирования отладочной платы mc68hc912b32evb
- 4.14. Подсистема реального времени — модуль таймера
- 4.14.1. Структура модуля таймера
- 4.14.2. Счетчик временной базы
- Особенности счетчика временной базы
- Флаг переполнения счетчика
- Определение длительности временных интервалов
- Сброс счетчика временной базы
- Вопросы для самопроверки
- 4.14.3. Регистры для управления счетчиком временной базы
- Регистр управления модулем таймера
- Регистр счетчика временной базы
- Регистр масок таймера 2
- 4.14.4. Каналы захвата/сравнения
- Режим входного захвата
- Вопросы для самопроверки
- Режим выходного сравнения
- Канал 7 в режиме выходного сравнения
- Регистры для управления каналами захвата/сравнения
- Регистры управления таймером 3 и 4
- Регистр масок таймера 1
- Регистр масок таймера 2
- Регистр флагов таймера 1
- Регистр флагов таймера 2
- Регистры данных каналов захвата/сравнения
- Вопросы для самопроверки
- Примеры работы с таймером
- Измерение частоты и периода логического сигнала
- Генерация импульсной последовательности
- Генерация импульсной последовательности с использованием прерывания
- 4.14.5. Счетчик событий
- Режимы работы счетчика
- Регистры управления счетчиком событий
- Регистр управления счетчиком событий
- Регистр флагов счетчика событий
- Регистр текущего состояния счетчика событий
- Пример использования счетчика событий
- 4.15. Модуль меток реального времени
- Пример использования модуля меток реального времени
- 4.16. Модуль таймера ect в составе мк мc68hc12be32 и hcs12
- 4.16.1. Небуферированные каналы входного захвата
- 4.16.2. Буферированные каналы входного захвата
- 4.16.3. Особенности счетчиков событий
- 4.16.4. Регистры управления модуля est
- Регистр управления порядком перезаписи
- Регистр управления режимом входного захвата
- Регистр управления счетчиком задержки
- Регистр управления 16-разрядным вычитающим счетчиком
- Регистр коэффициента счета вычитающего счетчика
- Регистр флагов вычитающего счетчика
- 4.17. Обмен информацией в последовательном коде: многофункциональный последовательный интерфейс
- 4.17.1. Термины последовательного обмена
- Вопросы для самопроверки
- 4.18. Контроллер асинхронного обмена sci
- Вопросы для самопроверки
- 4.18.1. Передатчик контроллера sci
- 4.18.2. Приемник контроллера sci
- 4.18.3. Регистры контроллера sci
- Регистры скорости обмена sCxBdh и sCxBdl
- Регистры управления sCxCr1 и sCxCr2
- Регистры состояния sCxSr1 и sCxSr2
- Регистры данных sCxDrh и sCxDrl
- Вопросы для самопроверки
- 4.18.4. Алгоритмы программного обслуживания контроллера sci
- 4.18.5. Пример программирования контроллера sci
- 4.19. Синхронный последовательный интерфейс spi
- 4.19.1 Концепция интерфейса spiФункциональная схема обмена между двумя контроллерами spi
- 4.19.2. Алгоритмы работы контроллера spi
- Вопросы для самопроверки
- 4.19.3. Регистры контроллера spi
- Регистр скорости обмена sPxBr
- Регистры управления sPxCr1 и sPxCr2
- Регистр данных spCxDr
- Регистр данных порта s
- Регистр направления передачи порта s
- Вопросы для самопроверки
- 4.19.4. Алгоритмы программного обслуживания контроллера spi
- 4.19.5 Периферийные ис с интерфейсом spi
- 4.20. Введение в теорию аналого-цифрового преобразования
- 4.20.1. Частота дискретизации сигнала
- 4.20.2. Представление аналоговой величины в цифровом коде
- 4.20.3.Квантование по уровню и разрешающая способность
- 4.20.4 Скорость потока данных оцифровки
- Вопросы для самопроверки
- 4.21. Принцип действия ацп
- 4.21.1. Ацп последовательного приближения
- Вопросы для самопроверки
- 4.22. Подсистема аналого-цифрового преобразования мк 68hc12
- 4.22.1 Структура и порядок функционирования
- 4.22.2. Регистры управления модуля atd
- Группа регистров управления
- Регистры управления atdctl0 и atdctl1
- Регистр управления atdctl2
- Регистр управления atdctl3
- Регистр управления atdctl4Формат регистра atdctl4
- Регистр управления atdctl5
- Вопросы для самопроверки
- Регистр состояния atdstat
- Регистр данных порта portad
- Регистры результата adr0h…adr7h
- Вопросы для самопроверки
- Тестовый регистр atdtest
- 4.22.3. Пример программирования модуля atd
- Цифровой вольтметр
- 4.22.4. Обслуживание прерываний от модуля atd
- 4.23. Особенности модуля atd в составе мк семейства hcs12
- 4.23.1. Выбор разрядности ацп
- 4.23.2. Представление результата измерения
- 4.23.3. Запуск измерительной последовательности от внешнего сигнала
- 4.23.4. Программируемое число преобразований в измерительной последовательности
- 4.23.5. Увеличение числа аналоговых входов
- 4.23.6. Регистры модуля atd hcs12
- Регистр состояния atdstat0
- Регистр состояния atdstat1
- Регистр разрешения цифрового входа порта atddien
- 4.24. Подсистема широтно-импульсной модуляции
- 4.24.1. Структура модуля pwm
- 4.24.2. Режимы центрированной и фронтовой шим
- 4.24.3. Система тактирования
- 4.24.4. Регистры модуля pwm
- Регистр конфигурации pwclk
- Регистр конфигурации pwpol
- Регистр разрешения работы каналов pwen
- Регистр дополнительного делителя pwpres
- Регистры делителей pwscnt0/pwscnt1 и pwscal0/pwscal0
- Регистры счетчика каналов pwcnTx
- Регистры периода каналов pwpeRx
- Регистры коэффициента заполнения каналов pwdtYxФормат регистров коэффициента заполнения pwdtYx
- Регистры коэффициента заполнения каналов pwdtYx
- Регистр управления pwctl
- Регистр специальных режимов pwtst
- Регистры работы с портом p
- 4.24.5. Примеры программирования модуля pwm
- Инициализация модуля pwm, пример 1
- Инициализация модуля pwm, пример 2
- 4.25. Ограничение энергии потребления
- 4.25.1. Как остановить мк 68hc12
- 4.25.2. Как вывести мк 68hc12 из состояния пониженного энергопотребления
- 4.26. Советы по использованию платы отладки mc68evb912b32
- 4.27. Заключение по главе 4
- 4.28. Что еще почитать?
- 4.29. Вопросы и задания Основные
- Исследовательские
- Глава 5 основы сопряжения мк с устройствами ввода/вывода
- 5.1. Электрические характеристики мк 68hc12
- 5.1.1. Нагрузочные характеристики
- 5.1.2. Что произойдет, если Вы должным образом не учтете электрические характеристики периферийных ис?
- 5.1.3. Входные и выходные характеристики логических элементов
- 5.2. Устройства дискретного ввода: кнопки, переключатели, клавиатуры
- 5.2.1. Кнопки и переключатели
- 5.2.2. Dip переключатели
- 5.2.3. Клавиатуры
- 5.3. Устройства индикации: светодиоды, семисегментные индикаторы, индикаторы логического выхода с тремя состояниями
- 5.3.1. Светодиоды
- 5.3.2. Семисегментные индикаторы
- 5.3.3. Индикаторы для логического выхода с тремя состояниями
- 5.4. Программное обслуживание дискретных входов и выходов
- 5.5. Подавление механического дребезга контактов переключателей
- 5.5.1. Аппаратная защита от механического дребезга контактов
- 5.5.2. Программная защита от механического дребезга контактов
- 5.5.3. Пример программной защиты
- 5.6. Жидкокристаллические индикаторы
- 5.6.1. Краткие сведения о жидкокристаллических индикаторах
- 5.6.2. Сопряжение мк с символьным жк индикатором
- 5.6.3 Сопряжение мк с графическим жк дисплеем
- 5.7. Управление электрическим двигателем
- 5.7.1. Силовые полупроводниковые ключи
- 5.7.2. Оптоэлектронная потенциальная развязка
- 5.7.3. Инвертор напряжения
- 5.8. Кодовый замок
- 5.8.1. Схема подключения периферийных устройств
- 5.8.2. Программа управления
- 5.9. Интерфейс мк с аналоговыми датчиками
- 5.10. Интерфейс rs-232
- 5.11. Заключение по главе 5
- 5.12. Что еще почитать?
- 5.13. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 6 добро пожаловать в реальный мир!
- 6.1. Ужасные истории об ошибках проектирования
- 6.1.1. Случай квадратичного генератора
- 6.1.2. Случай таймера для лазерного излучения
- 6.2. Правила обращения с микросхемой 68нс12 и рекомендации по проектированию
- 6.2.1. Рекомендации по обращению со cmos
- 6.2.2. Рекомендации по проектированию на cmos
- 6.3. Исследование помех
- 6.3.1. Что такое помехи
- 6.3.2. Электромагнитная совместимость
- 6.3.3. Спецификации системы помех — не будем крепки задним умом!
- 6.3.4. Методы снижения помех
- 6.4. Защитное программирование
- 6.5. Методики испытаний на наличие помех
- 6.5.1. Обнаружение помех
- 6.5.2. Испытание на чувствительность к помехам
- 6.5.3. Испытания на электромагнитную совместимость
- 6.6. Управление энергопотреблением
- 6.6.1. Параметры потребляемой мощности для микроконтроллера 68hc12
- 6.6.2. Типы батарей
- 6.6.3. Емкость батарей
- 6.6.4. Стабилизация напряжения
- 6.6.5. Схемы супервизора для микропроцессора
- 6.6.6. Меры энергосбережения
- 6.7. Заключение по главе 6
- 6.8. Что еще прочитать?
- 6.9. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 7 примеры встроенных систем управления
- 7.1. Система привода робота, движущегося вдоль стенок лабиринта
- 7.1.1. Описание проекта
- 7.1.2. Подсистемы 68hc12, используемые в проекте
- 7.1.3. Компоненты системы
- 7.1.4. Структура программы и блок-схема алгоритма
- 7.1.5. Программный код
- 7.2. Лазерный проектор
- 7.2.1. Описание проекта
- 7.2.2. Подсистемы 68hc12 используемые в проекте
- 7.2.3. Описание некоторых компонентов системы
- 7.2.4. Аппаратные средства
- 7.2.5. Структура программы и блок-схема алгоритма
- 7.2.6. Программный код
- 7.2.7. Испытания устройства
- 7.2.8. Заключительные испытания системы управления
- 7.3. Цифровой вольтметр
- 7.3.1. Описание проекта
- 7.3.2. Системы 68hc12 используемые в проекте
- 7.3.3. Расчет интерфейса модуля atd
- 7.3.4. Структура программы и блок-схема алгоритма
- 7.3.5. Программа управления
- 7.3.6. Измерение неэлектрических величин
- 7.4. Стабилизация скорости вращения двигателя с использованием оптического тахометра
- 7.4.1. Описание проекта
- 7.4.2. Немного теории
- 7.4.3. Анализ
- 7.4.4. Структура программы и блок-схема алгоритма
- 7.4.5. Программный код
- 7.4.6. Испытания
- 7.5. Парящий робот
- 7.5.1. Описание проекта
- 7.5.2. Системы hcs12 используемые в проекте
- 7.5.3. Теоретическое обсуждение
- 7.5.4. Структура программы и блок-схема алгоритма
- 7.5.5. Программный код
- 7.5.6. Некоторые комментарии
- 7.6. Система защиты компьютера, основанная на нечеткой логике
- 7.6.1. Описание проекта
- 7.6.2. Использование системы hcs12
- 7.6.3. Основы теории
- 7.6.4. Структура программы и блок-схема алгоритма
- 7.6.5. Описание системы
- 7.6.6. Обсуждение проекта
- 7.6.7. Программный код
- 7.6.8. Некоторые комментарии
- 7.7. Электронная версия игры в «15»
- 7.7.1. Описание проекта
- 7.7.2. Системы hcs12 используемые в проекте
- 7.7.3. Основы теории
- 7.7.4. Схемное решение, структура программы и блок-схема алгоритма
- 7.7.5. О компонентах системы
- 7.7.6. Программный код
- 7.7.7. Некоторые комментарии
- 7.8. Программирование резидентного Flash пзу микроконтроллера b32 в составе платы отладки mc68hc912b32evb
- 7.9. Заключение по главе 7
- 7.10. Что еще прочитать?
- 7.11. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 8 операционные системы реального времени
- 8.1. Рассказ: официант — «живая» операционная система реального времени
- 8.2. Что является целью осрв?
- Вопросы для самопроверки
- 8.3. Обзор концепций
- 8.3.1. Требования к динамическому распределению ram
- Вопросы для самопроверки
- 8.3.2. Динамическое распределение памяти
- 8.3.3. Структуры данных
- 8.4. Основные понятия
- 8.4.1. Что такое задача?
- 8.4.2. Управление задачами
- 8.4.3. Компоненты многозадачных систем
- 8.5. Типы операционных систем реального времени
- 8.5.1. Системы с циклическим опросом
- 8.5.2. Циклический опрос с прерываниями
- 8.5.3. Карусельные системы
- 8.5.4. Смешанные системы
- 8.5.5. Системы с управлением по прерыванию
- 8.5.6. Кооперативная многозадачность
- 8.5.7. Многозадачные системы с преимущественным приоритетом
- 8.6. Проблемы осрв
- 8.6.1. Конкуренция Другой рассказ
- 8.6.2. Повторная входимость
- 8.6.3. Межзадачные связи
- 8.6.4. Безопасность, проверка и безотказная работа
- 8.6.5. Главный вопрос
- 8.7. Выполнение операционной системы реального времени
- 8.8. Пример применения: осрв циклического опроса
- 8.8.1. Краткий обзор проекта
- 8.8.2. Пример кода
- 8.8.3. Испытание контроллера усилителя
- 8.9. Другая прикладная программа: цикл опроса с прерываниями
- 8.10. Сложное прикладное устройство: имитатор осрв
- 8.10.1. Краткий обзор проекта
- 8.10.2. Типовой код
- 8.11.Заключение по главе 8
- 8.12. Что еще почитать?
- 8.13. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 9 распределенные сети с интерфейсом msCan
- 9.1. Компьютерные сети
- 9.2. Промышленные сети
- 9.3. Сети с протоколом can
- 9.3.1. Протокол can
- 9.3.2. Модуль контроллера последовательного обмена msCan12
- Подсистема прерывания контроллера msCan12.
- 9.3.3. Проблемы синхронизации
- 9.3.4. Конфигурирование модуля msCan12 для работы в сети
- 9.4. Различия между контроллерами msCan в составе 68hc12 и hcs12
- 9.5. Пример программирования контроллера msCan Схема включения аппаратных средств для двух отладочных плат Axiom
- 9.6. Контроллер последовательного обмена bdlc
- 9.7. Заключение по главе 9
- 9.8. Что еще почитать?
- 9.9. Вопросы и задания Основные
- Более сложные
- Исследовательские