Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовой - Регулятор мощности / Программа с рамкой

.doc
Скачиваний:
16
Добавлен:
02.05.2014
Размер:
165.38 Кб
Скачать

Приложение 4 Программа микроконтроллера

0using 0

org 002Fh;

begin: ;начало программы - инициализация

setb VS_CON; выключил тиристор

clr F_FREEBUT;

mov P1,#0FFh;

mov P3,#0FFh;

mov IE,#00000011b; Разр. прерывания от таймера T0 и внешнее INT0, пока общий запрет

mov TCON,#00000000b ; таймеры остановлены, INT0 по нижнему уровню

mov TMOD,#00010001b ; у таймеров 16-битный режим, внутренняя синхронизация

; управление от бита TR

setb PT0; более высокий приоритет прерывания таймера T0

mov POW_TEK,#00;

mov T_OFF_TEK,#00;

mov UZ,#00;

mov SPEED_Z,#00;

; чтение из EEPROM

clr C;

read_1: mov A,#PADDR; загрузка программируемого адреса 00

mov ADDR,#00; чтение байта с нулевым адресом

call read_random; вызов подпрограммы чтения

jc read_1; если ошибка, то сначала

mov POW_ZAD,A; сохранение считанного байта

clr C;

read_2: mov A,#PADDR; загрузка программируемого адреса 00

mov ADDR,#01; чтение байта с адресом 01

call read_random; вызов подпрограммы чтения

jc read_2; если ошибка, то сначала

mov T_OFF_ZAD,A; сохранение считанного байта

clr C;

read_3:mov A,#PADDR; загрузка программируемого адреса 00

mov ADDR,#02; чтение байта с адресом 02

call read_random; вызов подпрограммы чтения

jc read_3; если ошибка, то сначала

mov F_REG,A; сохранение считанного байта

clr C;

;-----------------------------------------------------------------

clr TR0; остановил таймер

mov DPTR,#TAB_DELAY;

mov A,#00h;

movc A,@A+DPTR;

mov TH0,A; загрузка старшего байта счетчика

mov A,#00h;

inc DPTR;

movc A,@A+DPTR;

mov TL0,A; загрузка таймера задержки тиристора

;общее разрешение прерывания только после чтения FLASH-памяти

;-----------------------------------------------------------------

;фрагмент считывания данных из EEPROM памяти

;-----------------------------------------------------------------

setb EA; после подготовки к работе разрешить прерывания

MAIN:

jnb F_S_M,MAIN;

; сохранение в EEPROM

write_1:

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата


clr F_S_M;

mov A,#PADDR; загрузка программируемого адреса 00

mov ADDR,#00; установка адреса байта

mov ZDATA,POW_ZAD; загрузка байта данных

call write_byte; вызов подпрограммы записи байта

jc write_1; если ошибка, то сначала

call DELAY_WR; задержка записи

write_2:

mov A,#PADDR; загрузка программируемого адреса 00

mov ADDR,#01; устаногвка адреса байта

mov ZDATA,T_OFF_ZAD; загрузка байта данных

call write_byte; вызов подпрограммы записи байта

jc write_2; если ошибка, то сначала

call DELAY_WR; задержка записи

write_3:

mov A,#PADDR; загрузка программируемого адреса 00

mov ADDR,#02; устаногвка адреса байта

mov ZDATA,F_REG; загрузка байта данных

call write_byte;вызов подпрограммы записи байта

jc write_3; если ошибка, то сначала

call DELAY_WR; задержка записи

jmp MAIN;

;-----------------------------------------------------------------

; Подпрограмма задержки записи

; не менее 10 мс (100*100мкс)

DELAY_WR: djnz COUNT_I,$;

mov COUNT_I,#100;

djnz COUNT_J,DELAY_WR;

mov COUNT_J,#100;

ret;

;-----------------------------------------------------------------

;подпрограмма обработки прерывания перехода нуля

INT_0: push ACC;

push PSW; сохранили состояния

mov A,POW_TEK; в А текущий уровень мощности

JZ ZERO_P; если уровень равен нулю то не включать таймер

setb TR0; запуск таймера

;-----------------------------------------------------------------

;опрос кнопок

;-----------------------------------------------------------------

ZERO_P: setb DS1;

setb DS2; выключили индикаторы

setb KEY_READ; установил в 1 для чтения

mov P1,#11111011b; вкл Р1.2

mov REG_P1,#11111011b; вспомогательный регистр

mov CODE_KEY,#00h;

KR1: clr C;

jb KEY_READ,KR2;

setb C; если KEY_READ=0 (т.е. кнопка нажата)

KR2: mov A,CODE_KEY;

rlc A;

mov CODE_KEY,A; сохранение результата опроса кнопок

mov A,REG_P1;

setb C;

rrc A;

mov REG_P1,A;

mov P1,A;

jc KR1;

END_KR:

;-----------------------------------------------------------------

; работа с индикацией

; вывод на семисегментный индикатор и светодиод

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

; вывод результатов фрагмента LF

;-----------------------------------------------------------------

jb F_D_INICATOR,C_DS1;

C_DS2: mov A,REG_ML_IND; вывод на младший индикатор

mov P1,A

clr DS2;

jmp C_END;

C_DS1: mov A,REG_ST_IND; вывод на старший индикатор

mov P1,A

clr DS1;

C_END: cpl F_D_INICATOR;

;-----------------------------------------------------------------

; фрагмент обработки нажатых кнопок

LA: mov A,CODE_KEY;

jnz LA2; если нет нажатия то переход на соотв. фрагмент

jmp LB;

LA2: clr F_TIME_OUT; сброс флага окончания времени таймера

mov T_NPRESS_KEY,#00; сброс таймера ненажатия

cjne A,CODE_F_KEY,LA1; код кнопок равен предыдущему?

LA4: inc T_PRESS_KEY; если равен, то увеличить таймер нажатия кнопки

jmp LA3;

LA1: mov T_PRESS_KEY,#00; если не равен, то сбросить таймер нажатия кнопки

LA3: mov CODE_F_KEY,A; предыдущему коду значение последнего

cjne A,#S3,LA5;

LA6: jnb F_FREEBUT,LA7;

mov T_PRESS_KEY,#00;

jmp LM;

LA7: mov A,T_PRESS_KEY; если нажата S3, то проверить длительность нажатия

clr C;

cjne A,#200,LA81;

LA81: jnc LA10;

jmp LC; переход на LC если таймер нажатия кнопки < 200, то дальше LC

LA10: mov T_PRESS_KEY,#00; сброс таймера нажатия

cpl F_PR_TIMER; инверсия флага программирования таймера

setb F_FREEBUT;

jmp LM;

LA5: mov A,T_PRESS_KEY;

clr C;

cjne A,#ANTIDREBEZG,LA12; сравнение таймера нажатия больше 100 мс или нет

LA12: jnc LA121;

jmp LC;

LA121: mov T_PRESS_KEY,#00; обнуление таймера для задания темпа нарастания

mov A,CODE_KEY;

cjne A,#S2,LD; если не S2, то проверка кнопки S1

LA14: jb F_PR_TIMER,LA16;

LA9: mov A,POW_ZAD;

jz LM; проверка нулевого уровня задания мощности

LA11: dec A; уменьшение мощности

mov POW_ZAD,A;

jmp LM;

LA16: mov A,T_OFF_ZAD;

jz LM; проверка нулевого уровня задания времени

LA13: dec A; уменьшение мощности

mov T_OFF_ZAD,A;

jmp LM;

;-----------------------------------------------------------------

; фрагмент обработки нажатия кнопки S1

LD: mov A,CODE_KEY;

cjne A,#S1,LC; если не равно S1, значит нажата комбинация кнопок

LD2: jb F_PR_TIMER,LD4;

LD1: mov A,POW_ZAD;

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

clr C;

cjne A,#100,LD3; проверка ограничения по максимуму 100

jmp LM; если максимум достигнут то дальше

LD3: jnc LD6;

LD5: inc POW_ZAD; если максимум не достигнут то увеличить мощность

jmp LM;

LD6: mov POW_ZAD,#100; недопустить превышение 100

jmp LM;

LD4: mov A,T_OFF_ZAD;

clr C;

cjne A,#100,LD7; проверка ограничения по максимуму 100

jmp LM; если максимум достигнут то дальше

LD7: jnc LD8;

LD9: inc T_OFF_ZAD; если максимум не достигнут то увеличить время таймера

jmp LM;

LD8: mov T_OFF_ZAD,#100; недопустить превышение 100

LM: setb F_V_D; установить флаг, указывающий на изменение данных

jmp LC; переход на метку LC

; конец фрагмента

;-----------------------------------------------------------------

; фрагмент контроля при отсутствии нажатых кнопок

LB: mov A,CODE_F_KEY;

cjne A,#S3,LB1; если не S3, то просто очистить CODE_F_KEY

LB2: mov A,T_PRESS_KEY;

clr C;

cjne A,#ANTIDREBEZG,LB3; время удержания равно ANTIDREBEZG?

jmp LB6;

LB3: jc LB1;

LB6: jb F_FREEBUT,LB1;

LB61: cpl F_MODE; изменить режим

setb F_V_D; данные (режим) изменились

LB1: mov CODE_F_KEY,#00;

mov T_PRESS_KEY,#00; сбросить счетчик совпадения кода кнопок

clr F_FREEBUT; сбросить флаг освобождения кнопок

jb F_V_D,LB8; если данные изменялись перейти на LA8

jmp LC; иначе на LC

LB8: mov A,T_NPRESS_KEY;

clr C;

cjne A,#200,LB9; время не нажатия равно 200?

jmp LB10;

LB9: jnc LB10; если прошло более 2 секунд переход на LB10

LB11: inc T_NPRESS_KEY; увеличить таймер не нажатия

jmp LC;

LB10: mov T_NPRESS_KEY,#00; сброс таймера ненажатия по окончанию 2 секунд

setb F_S_M; пора сохранять в EEPROM

clr F_V_D; сброс флага,т.к. устанавлен F_S_M

clr F_PR_TIMER; если нет нажатий после двух секунд возвращается

; режим вывода на дисплей мощности, светодиод перестает мигать

;-----------------------------------------------------------------

; фрагмент контроля времени таймера

LC: mov A,T_BLINK;

jz LC2;

LC1: dec T_BLINK;

jmp LE0;

LC2: mov T_BLINK,#50;

cpl F_BLINK; каждые полсекунды инвертировать флаг

jb F_MODE,LC4; если таймер включен, то продолжить фрагмент

jmp LE0;

LC4: jnb F_TIME_OUT,LC6; если время таймера кончилось то выйти из фрагмента

jmp LE0;

;LC3: mov A,T_SEK;

; jz LC6;

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

;LC5: dec T_SEK;

; jmp LE0;

LC6: ;mov T_SEK,#01;

mov A,T_MIN;

jz LC8;

LC7: dec T_MIN;

jmp LE0;

LC8: mov T_MIN,#120;

clr C;

mov A,T_OFF_TEK;

cjne A,T_OFF_ZAD,LC9; сравнение времени таймера с заданным

jmp LC10;

LC9: jnc LC10;

LC11: inc T_OFF_TEK;

jmp LE0;

LC10: setb F_TIME_OUT;

mov T_OFF_TEK,#00; время таймера кончилось, сброс тек. времени

; jmp LE0; для следующего подсчета

;-----------------------------------------------------------------

; фрагмент контроля текущего уровня мощности и загрузки регистров индикации

LE0: jb F_MODE,LE2; если таймер включен то проверить время

LE1: clr C;

mov A,POW_TEK;

cjne A,POW_ZAD,LE7; сравнение уровня текущей мощности с заданным

LE8: jmp LF1

LE7: jnc LE10;

LE9: inc POW_TEK;

jmp LF1;

LE10: dec POW_TEK;

jmp LF1;

LE2: jnb F_TIME_OUT,LE1;

LE4: mov A,POW_TEK;

jz LF4; если мощность равна нулю,то выход

LE5: jmp LE10;

;-----------------------------------------------------------------

LF1: jb F_PR_TIMER,LF6;

LF5: mov R_DISPLAY,POW_TEK;

jmp LF3;

LF6: mov R_DISPLAY,T_OFF_ZAD;

LF3: call BIN_BCD; вызов подпрограммы преобразования десятков и единиц

mov DPTR,#TAB_IND;

mov A,IND_UNIT;

movc A,@A+DPTR;

call LED_CTRL;

mov REG_ML_IND,A;

mov A,IND_DEC;

jz LF32; проверка нуля во втором разряде индикатора

jmp LF31;

LF32: jb F_D_OVER,LF31; проверка флага переполнения индикатора

mov A,#0Ah; загрузка значения пустого индикатора

LF31: movc A,@A+DPTR;

call LED_CTRL;

mov REG_ST_IND,A;

jmp LF7;

LF4: inc SPEED_Z; пп загрузки в регистры индикации значений змейки

mov A,SPEED_Z;

cjne A,#40,Z01;

mov SPEED_Z,#00h;

mov A,#2;

add A,UZ;

mov UZ,A;

Z01: mov A,UZ;

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

cjne A,#16,Z02;

mov UZ,#00h;

Z02: mov A,UZ;

mov DPTR,#T_ZMEYKA;

movc A,@A+DPTR;

clr ACC.7; чтобы горел светодиод "Режим таймера"

mov REG_ST_IND,A;

mov A,UZ;

inc A;

movc A,@A+DPTR;

clr ACC.7; чтобы горел светодиод "Режим таймера"

mov REG_ML_IND,A;

LF7: pop PSW;

pop ACC; возврат состояния перед выходом из прерывания

clr IE0; сброс флага прерывания по уровню

reti; окончание прерывания

;-----------------------------------------------------------------

; подпрограмма обсуживания таймера0 после окончания времени задержки

; включения тиристора - генерация импульса включения 25 микросекунд

INT_TIM0: push ACC;

push PSW ;сохранил состояния

clr TR0 ;остановил таймер

clr VS_CON ;тиристор включил

mov R1,#5d;

djnz R1,$ ;задержка на 10мкс

mov DPTR,#TAB_DELAY;

mov A,POW_TEK;

rl A; ;умножение на два

movc A,@A+DPTR;

mov TH0,A ;загрузка счетчика

inc DPTR;

mov A,POW_TEK

rl A; ;умножение на два

movc A,@A+DPTR;

mov TL0,A ;загрузка таймера задержки тиристора

setb VS_CON ;выключил тиристор

clr TF0;

pop PSW;

pop ACC;

reti; возврат из прерывания

;-----------------------------------------------------------------

; подпрограмма преобразования из двоичного кода в BCD

; преобразуем число в аккумуляторе

;-----------------------------------------------------------------

BIN_BCD:clr F_D_OVER; очистка флага переполнения дисплея

mov A,R_DISPLAY;

mov B,#10d; делим на 10

div AB;

mov IND_UNIT,B; остаток в единицы

mov IND_DEC,A; целое в десятки

mov B,#10d; делим на 10

div AB;

jz BB_END;

setb F_D_OVER;

mov IND_DEC,#00h;

BB_END: ret;

;-----------------------------------------------------------------

write_byte:

; Подпрограмма записи байта в 24C02.

; Требующийся программируемый адрес находится в А.

; Адрес байта находится в регистре ADDR. Записываемые данные в регистре ZDATA.

; Неожидает окончания выполнения операции записи (1мсек. и более)

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

; Возвращает C=1, если шина I2C недоступна, или адресуемое устройство

; не выдает подтверждения.

; Разрушает содержимое A.

call start

jc x49 ; прервать, если шина не доступна

rl a ; переместить программируемый адрес в биты 3:1

orl a, #FADDR ; сложить с фиксированным адресом

clr acc.0 ; установка операции записи

call shout ; переслать адрес устройства

jc x48 ; прервать, если нет подтверждения

mov a, addr ; загрузить адрес байта

call shout ;

jc x48 ; прервать, если нет подтверждения

mov a, zdata ; переслать данные в А

call shout ; отправить данные

jc x48 ; прервать, если нет подтверждения

clr c ; очистить флаг ошибки

x48: call stop

x49: ret

read_current:

; Подпрограмма чтения 24C02 по текущему адресу.

; Требующийся программируемый адрес находится в А. Возвращает данные в A.

; Возвращает C=1, если шина I2C недоступна, или адресуемое устройство

; не выдает подтверждения.

call start

jc x45 ; прервать, если шина не доступна

rl a ; переместить программируемый адрес в биты 3:1

orl a, #FADDR ; сложить с фиксированным адресом

setb acc.0 ; установка операции чтения

call shout ; переслать адрес устройства

jc x44 ; прервать, если нет подтверждения

call shin ; принять байт данных

call NAK ; не выдается подтверждения(прервать операцию)

clr c ; очистить флаг ошибки

x44: call stop

x45: ret

read_random:

; Подпрограмма чтения 24C02 по произвольному адресу.

; Требующийся программируемый адрес находится в А.

; Адрес байта находится в регистре ADDR. Возвращает данные в A.

; Возвращает C=1, если шина I2C недоступна, или адресуемое устройство

; не выдает подтверждения.

push b

mov b, a ; сохранение программируемого адреса

; Формирование холостой команды записи с установленным внутренним адресом.

call start

jc x47 ; прервать, если шина не доступна

rl a ; переместить адрес в биты 3:1

orl a, #FADDR ; сложить с фиксированным адресом

clr acc.0 ; установка операции записи

call shout ; переслать адрес устройства

jc x46 ; прервать, если нет подтверждения

mov a, addr ; загрузка адреса байта

call shout ;

jc x46 ; прервать, если нет подтверждения

call stop;

; Вызов подпрограммы чтения байта по текущему адресу.

mov a, b ; загрузка программируемого адреса

call read_current

jmp x47 ; выход

x46: call stop

x47: pop b

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

ret

start:

; Формирование бита START, т.е. переход SDA от 1 к 0 при SCL=1.

; Возвращает при выходе SCL=0, SDA=0.

; Вовращает С=1, если шина не доступна.

setb SDA

setb SCL

; Проверка доступности шины.

jnb SDA, x40 ; Переход, если не 1

jnb SCL, x40 ; Переход, если не 1

nop ;

clr SDA

nop ; формирование 5 мкс задержки

nop ;

nop ;

nop ;

nop ;

clr SCL

clr c ; очистить флаг ошибки

jmp x41

x40: setb c ; установить флаг ошибки

x41: ret

stop:

; Формирование бита STOP, т.е. переход SDA от 0 к 1 при SCL=1.

; При входе в подпрограмму SCL=0. Возвращает при выходе SCL=1, SDA=1.

clr SDA

nop ; подготовка шины

nop

setb SCL

nop ; формирование 5 мкс задержки

nop ;

nop ;

nop ;

nop ;

setb SDA

ret

shout:

; Подпрограмма вывода байта на шину I2C, старший значащий бит первый

; При входе в подпрограмму SCL=0, SDA=0. Возвращает при выходе SCL=0

; Передаваемый байт данных в А.

; Возвращает С=1, показывая о неудачном подтверждении Slave.

; Разрушает содержимое A

push b

mov b, #8 ; счетчик бит

x42: rlc a ; перемещение бита в С

mov SDA, c ; вывод бита

nop ;

setb SCL ; установили SCL

nop ; задержка 4 мкс для высокого SCL

nop ;

nop ;

nop ;

clr SCL ; сброс SCL

djnz b, x42 ; новый бит

setb SDA ; настройка SDA как вход для приема ACK

nop ; задержка SCL в низком уровне

nop ;

setb SCL ; SCL=1 для ACK сигнала Slave

nop ; задержка 4 мкс для высокого SCL

nop ;

nop ;

nop ;

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

mov c, SDA ; ввод ACK бита

clr SCL ; сброс SCL

pop b

ret

shin:

; Подпрограмма ввода байта с шины I2C, старший значащий бит первый

; При входе в подпрограмму SCL=0. Возвращает при выходе SCL=0

; Возвращает принятый байт данных в А.

setb SDA ; настройка SDA как вход

push b

mov b, #8 ; счетчик бит

x43: nop ; установка SCL в 0 и прием данных

nop ;

nop ;

setb SCL ; установили SCL

nop ;

nop ;

mov c, SDA ; ввод бита

rlc a ; перемещение бита в байте

clr SCL ; сброс SCL

djnz b, x43 ; новый бит

pop b

ret

ACK:

; Формирование тактового иммпульса и бита подтверждение (АСК=0)

; При входе в подпрограмму SCL=0. Возвращает при выходе SCL=0, SDA=0

clr SDA ; ACK=0

nop ; задержка перед формированием SCL

nop ;

setb SCL ; установили SCL

nop ; задержка 4 мкс для высокого SCL

nop ;

nop ;

nop ;

clr SCL ; сброс SCL

ret

NAK:

; Формирование тактового иммпульса и неподтверждение (АСК=1)

; При входе в подпрограмму SCL=0, при выходе SCL=0, SDA=1

setb SDA ; NAK бит=1

nop ; задержка перед формированием SCL

nop ;

setb SCL ; установили SCL

nop ; задержка 4 мкс для высокого SCL

nop ;

nop ;

nop ;

clr SCL ; сброс SCL

ret

;-----------------------------------------------------------------

; подпрограмма управления светодиодом,

; в зависимости от управляющих флагов определяет значение АСС.7

;-----------------------------------------------------------------

LED_CTRL:

jnb F_PR_TIMER,L_C_1; если режим прогр. таймера

L_C_2: mov C,F_BLINK; то мигать с периодом 0,5 сек.

jmp L_C_3;

L_C_1: mov C,F_MODE; если таймер не программируется,

cpl C; то состояние светодиода определяется как /F_MODE

L_C_3: mov ACC.7,C;

ret; выход

2201 939 000 000 ПЗ

Лист

Изм

Лист

документа

Подпись

Дата

Соседние файлы в папке Курсовой - Регулятор мощности