Заключение
Поставленная передо мной задача создания и разработки малогабаритного анализатора качества ГСМ выполнена на уровне пробной версии устройства. Выполнены все предъявляемые ПТС требования.Для решения этой задачи были проделаны следующие виды работ:
Изучены отладочная плата Seeeduino и язык программирования Arduino, C, Assembler.
Найден, изучен и проанализирован имеющийся аналог устройство измерения ЭПС и ёмкости конденсатора.
Составлено техническое задание.
Составлены требования к ПС и ПТС, функциональные требования и требования к качеству разрабатываемого устройства.
Разработан алгоритм управляющей части ПТС.
Проведён анализ проделанной работы.
Создаваемое устройство более простое в использовании, надёжное и относительно недорогое. Аппаратная компонента разработанного ПТС реализована на микроконтроллере фирмы AtmelAttiny2313 и графическом ЖК-дисплее. Программная компонента устройства написана на языке Assembler. Объём программы не более 2КБ.
Данное устройство может быть использовано для анализа качества ГСМ и любой другой жидкости при предварительной доработке.
В дальнейшем возможна разработка компьютерного интерфейса.
Благодарю за огромный вклад и помощь своего научного руководителя: Коняева Сергея Ивановича.
Список использованных источников
1. Измеритель емкости и ЭПС конденсаторов / В. Келехсашвили / Журнал «Радио».-2010г,- выпуск 6-7 - стр.19-21.
2. Мактас М.Я. «8 уроков по P-CAD 2001»М.: СОЛОН-Пресс,2003 - стр.1-110.
3. У. Титце, К. Шенк Полупроводниковая схемотехника: справочное руководство» М.: МИР,1982 - стр. 56-65.
4. Описание ЖК-дисплея wh1602J-datasheet.-4c.
Приложение 1
Аналог разрабатываемого устройства спектрометр-анализатор
Известен спектрометр - анализатор веществ фирмы Brimrose [Бюллетень "AOTFSPECTROSCOPY", - фирма Brimrose, March, 1993]. Схема, которая представлена на рисунке.
Рис. 4
Где:
1 - источник широкополосного излучения;
2 - оптическая система доставки широкополосного излучения;
3 - акустооптическая ячейка;
4 - генератор высокой частоты;
5 - светоделительная пластина;
6 - опорный канал узкополосного излучения;
7 - сигнальный канал узкополосного излучения;
8 - фотоприемник опорного канала узкополосного излучения;
9 - фотоприемник сигнального канала узкополосного излучения;
10- анализируемое вещество;
11 - световод;
12 - блок обработки и индикации;
13 - собирающие линзы;
14 - светоделительная пластина;
15 - дифференциальный усилитель.
Этот спектрометр-анализатор работает следующим образом. От источника широкополосного излучения (1) излучение посредством оптической системы доставки широкополосного излучения (2) поступает в акустооптическую ячейку (3), которая выделяет из всего спектра названного излучения узкополосное излучение (излучение в узком спектральном диапазоне). Названный узкий спектральный диапазон формируется с помощью генератора высокой частоты (4) и зависит от частоты подаваемого им сигнала на акустооптическую ячейку (3). Полученное узкополосное оптическое излучение, вышедшее из акустооптической ячейки далее разделяется посредством светоделительной пластинки (14), на два пучка, первый из которых (6), направляется по опорному каналу узкополосного излучения на фотоприемник опорного канала (8), а второй направляется по сигнальному каналу узкополосного излучения (7), через световод (11), на анализируемое вещество (10) и далее возвращается через световод (11) и поступает на фотоприемник сигнального канала узкополосного излучения (9). Фотоприемники (8) и (9) преобразуют оптические сигналы в электрические, которые поступают на входы дифференциального усилителя и сравниваются по величине. Разность этих сигналов интерпретируется как функция поглощения (пропускания) веществом оптического сигнала с заданной длиной волны, которая в свою очередь, жестко связана с частотой генератора поступающей на акустооптическую ячейку. Перестраивая с помощью генератора высокой частоты (4) длину волны выделяемого акустооптической ячейкой узкополосного излучения, получают соответствующую спектральную функцию пропускания, или поглощения, т.е. зависимость изменения амплитуды напряжения на выходе дифференциального усилителя пропорционального изменению оптического сигнала на входе фотоприемника (9) во всем спектральном диапазоне длин оптических волн, в котором проводится измерение спектра поглощения (пропускания) анализируемого вещества.Полученная спектрограмма обрабатывается в электронном блоке обработки и индикации (12) и сравнивается со спектрограммой эталонного образца исследуемого вещества, хранящейся в памяти этого блока.
Приложение 2
Листинг программы
.defsotye = R0;Число сотых долей (1)
.defdesyatye = R1;Число десятых долей (2)
.defedinicy = R2;Число единиц (3)
.defdesyatki = R3;Число десятков (4)
.defsotni = R4;Число сотен тысяч (5)
.deftyshi = R5;Число тысяч (6)
.defdes_tysh= R6;Число десятков тысяч (7)
.defa1 = R7;1-й байт переменной a (младший байт)
.defa2 = R8;2-й байт переменной a
.defa3 = R9;3-й байт переменной a
.defb1 = R10;1-й байт переменной b (младший байт)
.defb2 = R11;2-й байт переменной b
.defb3 = R12;3-й байт переменной b
.defc1 = R13;1-й байт переменной c (младший байт)
.defc2 = R14;2-й байт переменной c
.defc3 = R15;3-й байт переменной c
;--------------------------------------------------------
.defc4 = R16;4-й байт переменной c
.deftemp = R17;Определение главного рабочего регистра
.deftemp2 = R18;Определение второго рабочего регистра
.deflcd= R19;Определение регистра для обращения к LCD
.defz1 = R20;1-й байт переменной z (младший байт)
.defz2 = R21;2-й байт переменной z
.defz3 = R22;3-й байт переменной z
.defz4 = R23;4-й байт переменной z
.defk_del= R24;Регистр поправки коеффициента деления таймера
.deftok_zar= R25;Регистр величины тока заряда
.defautoff= R28;Регистр счётчика автовыключения (он же YL)
.defautoff2= R29;Регистр предела измерения в Фарадах (он же YH)
;--------------------------------------------------------
.equconst1b = 8548;Константа перевода результата в ёмкость для большего тока (32768)
.equconst1m = 9124;Константа перевода результата в ёмкость для малого тока (524288)
.equconst2 = 2051;Константа 100*U1/Ib
.equconst3 = 3967;Константа 100*U2/Ib
.equconst4 = 129;Константа для задания скорости USART (9600 бит/с)
.equESRmax=2001;Порог максимального значения ESR (20,00 Ом)
.equporog1 = 32700;Порог переключения на младший предел (по U2)
.equporog2 = 15001;Порог переключения на малый ток (150 мкФ)
.equporog3 = 2001;Порог переключения предела на малом токе (20 мкФ)
.equd20m = 65535;Значение длительности паузы (~20мс при 20МГц) (тактов-9)/6
.equd3m = 9999;Значение длительности паузы (~3мс при 20МГц) (тактов-9)/6
.equd40u = 235;Значение длительности паузы (~40мкс при 20МГц) (тактов-4)/3
.equd1u=6;Значение длительности паузы (~1мкс при 20МГц) (тактов-4)/3
.equRS = 2;
.equE = 3;
;------------------------Начало программного кода
.cseg
.org0;установка текущего адреса на ноль
;------------------------Переопределение векторов прерываний
start:rjmpinit;Переход на начало программы
rjmpcom_U1;Внешнее прерывание 0
rjmpcom_U2;Внешнее прерывание 1
reti;Таймер/счётчик 1, захват
reti;Таймер/счётчик 1, совпадение, канал А
rjmpovtim1;Таймер/счётчик 1, прерывание по переполнению
reti;Таймер/счётчик 0, прерывание по переполнению
reti;Прерывание USART приём завершён
reti;Прерывание USART регистр данных пуст
reti;Прерывание USART передача завершена
reti;Прерывание по компаратору
reti;Прерывание по изменению на любом контакте
reti;Таймер/счётчик 1, совпадение, канал В
reti;Таймер/счётчик 0, совпадение, канал В
reti;Таймер/счётчик 0, совпадение, канал А
reti;USI готовность к старту
reti;USI переполнение
reti;EEPROM готовность
reti;Переполнение охранного таймера
;-----------------------Модуль инициализации
init:
;-----------------------Инициализация стека
lditemp, RAMEND;Выбор адреса внешнего стека
outSPL, temp;Запись его в регистр стека
;-----------------------Инициализация портов ВВ
lditemp,0b00000100;PA2 на вывод, PA0, PA1 на ввод
outDDRA,temp;
lditemp,0b00000100;Устанавливаем PA2, отключаем резисторы на PA0, PA1
outPORTA,temp;
lditemp,0b11111101;PB0, PB2...PB7 навывод, PB1 наввод
outDDRB,temp;
lditemp,0b00000000;Обнуляем PB1...PB7, устанавливаем PB1 ивключаемрезисторна PB0
outPORTB,temp;
lditemp,0b00110011;PD0, PD1, PD4...PD5 навывод, PD2, PD3, PD6 наввод
outDDRD,temp;
lditemp,0b01111111;Устанавливаем PD0, PD1, PD4...PD5 ивключаемрезисторы PD2, PD3, PD6
outPORTD,temp;
;-----------------------Инициализация таймера Т1
lditemp,0b00000000;Останов таймера, нормальный режим
outTCCR1B,temp;
;-----------------------Инициализация компаратора
lditemp,0b01110000;Настройка компаратора
outACSR,temp;
;-----------------------Определение масок прерываний
lditemp,0b00000000;Выбор режима вызова внешних прерываний PD2 (U1) и PD3 (U2)
outMCUCR,temp;
lditemp,0b00000000;Запрет прерываний по таймеру 1
outTIMSK,temp
lditemp,0b00000000;Запрет внешних прерываний
outGIMSK,temp;
;-----------------------Инициализация LCD (WH1602J)
lcd_init:
rcalldel20m;Вызов подпрограммы задержки (~20мс)
rcalldel20m;Вызов подпрограммы задержки (~20мс)
rcalldel20m;Вызов подпрограммы задержки (~20мс)
;Команда 0010
sbiPORTB,E;Строб вверх
lditemp,0b00101000;Команда (строб вверх + команда)
outPORTB,temp;Запись команды в порт
rcalldel1u;Вызов подпрограммы задержки (~1мкс)
cbiPORTB,E;Строб вниз
rcalldel1u;Вызов подпрограммы задержки (~1мкс)
ldilcd,0b00101000;Команды 0010 и 1000
rcalllcd_com;Вызов подпрограммы отправки команды на LCD
ldilcd,0b00001000;Команды 0000 и 1000
rcalllcd_com;Вызов подпрограммы отправки команды на LCD
ldilcd,0b00000001;Команды 0000 и 0001
rcalllcd_com;Вызов подпрограммы отправки команды на LCD
rcalldel3m;Вызов подпрограммы задержки (~3мс)
ldilcd,0b00000110;Команды 0000 и 0110
rcalllcd_com;Вызов подпрограммы отправки команды на LCD
;-----------------------Начало основной программы
cli;Глобально запрещаем прерывания
clrk_del;Очистка k_del
clrtok_zar;Очистка tok_zar
clrautoff;Очистка autoff
clrautoff2;Очистка autoff2
ldilcd,0b00001100;Включение дисплея и выбор курсора
rcalllcd_com;
;-----------------------Выключение прибора
lditemp,0b01110000;Разрешение перехода в режим Power-Down
outMCUCR,temp;
sbiPORTB,0;Выключение питания
sleep;Переход в режим Power-Down
bat_check1:
clrz1;Очистка z1
clrz2;Очистка z2
lditemp,55;Запись 55 в temp
bat_check2:
dectemp;Уменьшение temp на 1
sbisACSR,ACO;Если на выходе компаратора 1, то пропуск след.команды, иначе далее
rjmpbat_check3;На bat_check3
incz1;Увеличение z1 на 1
rjmpbat_check4;На bat_check4
bat_check3:
incz2;Увеличение z2 на 1
bat_check4:
cpitemp,0;Сравнение temp с 0
brnebat_check2;Если temp<>0, то на bat_check2, иначе далее
cpz1,z2;Сравнение z1 с z2
brlopusk_0;Если z1<z2, то на pusk_0, иначе далее
ldiZL,low(Bat*2);Запись в ZL младшего байта адреса ячейки из таблицы Bat (альтернативная адресация)
ldiZH,high(Bat*2);Запись в ZH старшего байта адреса ячейки из таблицы Bat (альтернативная адресация)
rcalllcd_all;Вызов подпрограммы отображения двух строк на LCD по данным из таблиц
incautoff2;Увеличение autoff2 на 1
;-----------------------Измерение на большом токе заряда
b_tok:
lditemp,0b00000001;Пуск таймера (clk/1)
addtemp,k_del;с коррекцией коеффициента деления таймера
cbiPORTD,0;Включение заряда конденсатора
outTCCR1B,temp;
rjmpcikl;На cikl
;-----------------------Измерение на малом токе заряда
m_tok:
lditemp,0b00000001;Пуск таймера (clk/1)
addtemp,k_del;с коррекцией коеффициента деления таймера
cbiPORTD,4;Включение заряда конденсатора
outTCCR1B,temp;
cikl:
rjmpcikl;Зацикливаем
;-----------------------Умножение (c3+c2+c1)*(XH+XL)=(c4+c3+c2+c1) или (n2-n1)*const1b
ldiXL,low(const1m);Запись младшего байта const1m в XL
ldiXH,high(const1m);Запись старшего байта const1m в XH
rjmpstep6_2;На step6_2
step6_1:
ldiXL,low(const1b);Записьмладшегобайта const1b в XL
ldiXH,high(const1b);Записьстаршегобайта const1b в XH
step6_2:
rcall mul16x16;Вызов подпрограммы перемножения 16-ти битных чисел
;-----------------------Отображение первой строки LCD
rcalllcd_1str;Вызов подпрограммы отображения первой строки LCD
clrautoff;Очистка autoff
;-----------------------Умножение (c3+c2+c1)*(XH+XL)=(c4+c3+c2+c1) или (U2/I)*n1
ldiXL,low(const3);Запись младшего байта const3 в XL
ldiXH,high(const3);Запись старшего байта const3 в XH
rcall mul16x16;Вызов подпрограммы перемножения 16-ти битных чисел
movz1,c1;Копирование результата умножения из c1 в z1
movz2,c2;Копирование результата умножения из c2 в z2
movz3,c3;Копирование результата умножения из c3 в z3
movz4,c4;Копирование результата умножения из c4 в z4
movc1,b1;Копирование 1-го байта n2 из b1 в c1
movc2,b2;Копирование 2-го байта n2 из b2 в c2
movc3,b3;Копирование 3-го байта n2 из b3 в c3
;-----------------------Умножение (c3+c2+c1)*(XH+XL)=(c4+c3+c2+c1) или (U1/I)*n2
ldiXL,low(const2);Запись младшего байта const2 в XL
ldiXH,high(const2);Запись старшего байта const2 в XH
rcall mul16x16;Вызов подпрограммы перемножения 16-ти битных чисел
popa3;Извлечение из стека в a3 (извлечение n2-n1)
popa2;Извлечение из стека в a2
popa1;Извлечение из стека в a1
subc1,z1;Вычитание z1 из c1 ((U1/I)*n2)-((U2/I)*n1)
sbcc2,z2;Вычитание z2 из c2 с учётом переноса
sbcc3,z3;Вычитание z3 из c3 с учётом переноса
sbcc4,z4;Вычитание z4 из c4 с учётом переноса
brplstep8;Если результат положительный, то на step8, иначе далее
ldiZL,low(ESRmn*2);Запись в ZL младшего байта адреса ячейки из таблицы ESRmn (альтернативная адресация)
ldiZH,high(ESRmn*2);Запись в ZH старшего байта адреса ячейки из таблицы ESRmn (альтернативная адресация)
;-----------------------Отображение второй строки LCD
step10:
rcalllcd_2str;Вызов подпрограммы отображения второй строки LCD
;-----------------------Подпрограмма отображение первой строки LCD
lcd_1str:
;-----------------------Отображение ёмкости
ldilcd,0x80;Выбор знакоместа (начало 1й строки)
rcalllcd_com;Вызов подпрограммы отправки команды на LCD
;-----------------------Отображение "12345" или " 2345"
clrtemp;Очистка temp
cpdes_tysh,temp;Если значение десятков тысяч не равно нулю, то переход на lcd_1str_4
brnelcd_1str_4;иначе далее
cptyshi,temp;Если значение тысяч не равно нулю, то переход на lcd_1str_3
brnelcd_1str_3;иначе далее
cpsotni,temp;Если значение сотен не равно нулю, то переход на lcd_1str_2
brnelcd_1str_2;иначе далее
cpdesyatki,temp;Если значение десятков не равно нулю, то переход на lcd_1str_0
brnelcd_1str_0;иначе далее
;-----------------------Отображение " 5,67" или "45,67"
ldilcd,0x20;Отображение " " (ёмкость)
rcalllcd_dat;
rjmplcd_1str_1;На lcd_1str_1
lcd_1str_0:
cpik_del,4;Сравнение k_del с 4
brnelcd_1str_0_1;Если k_del<>4, тона lcd_1str_0_1
ldilcd,0x30;Отображение "0" (ёмкость)
rcalllcd_dat;
ldilcd,0x2C;Отображение "," (ёмкость)
rcalllcd_dat;
lcd_1str_0_1:
ldilcd,0x30;Определение кода для числа десятков (ёмкость)
addlcd,desyatki;
rcalllcd_dat;Отображение числа десятков (ёмкость)
lcd_1str_1:
ldilcd,0x30;Определение кода для числа единиц (ёмкость)
addlcd,edinicy;
rcalllcd_dat;Отображение числа единиц (ёмкость)
cpik_del,4;Сравнение k_del с 4
brnelcd_1str_1_1;Если k_del<>4, то на lcd_1str_1_1
ldilcd,0x30;Определение кода для числа десятых долей (ёмкость)
addlcd,desyatye;
rcalllcd_dat;Отображение числа десятых долей (ёмкость)
ldilcd,0x30;Определение кода для числа сотых долей (ёмкость)
addlcd,sotye;
rcalllcd_dat;Отображение числа сотых долей (ёмкость)
ldilcd,0x20;Отображение " " (ёмкость)
rcalllcd_dat;
rjmpF_lcd;На F_lcd
lcd_1str_1_1:
ldilcd,0x2C;Отображение "," (ёмкость)
rcalllcd_dat;
ldilcd,0x30;Определение кода для числа десятых долей (ёмкость)
addlcd,desyatye;
rcalllcd_dat;Отображение числа десятых долей (ёмкость)
ldilcd,0x30;Определение кода для числа сотых долей (ёмкость)
addlcd,sotye;
rcalllcd_dat;Отображение числа сотых долей (ёмкость)
rjmpuF_lcd;На uF_lcd
;-----------------------Отображение "345,6"
lcd_1str_2:
ldilcd,0x30;Определение кода для числа сотен (ёмкость)
addlcd,sotni;
rcalllcd_dat;Отображение числа сотен (ёмкость)
ldilcd,0x30;Определение кода для числа десятков (ёмкость)
addlcd,desyatki;
rcalllcd_dat;Отображение числа десятков (ёмкость)
ldilcd,0x30;Определение кода для числа единиц (ёмкость)
addlcd,edinicy;
rcalllcd_dat;Отображение числа единиц (ёмкость)
ldilcd,0x2C;Отображение "," (ёмкость)
rcalllcd_dat;
ldilcd,0x30;Определение кода для числа десятых долей (ёмкость)
addlcd,desyatye;
rcalllcd_dat;Отображение числа десятых долей (ёмкость)
rjmpuF_lcd;На uF_lcd
;-----------------------Отображение " 2345" или "12345"
lcd_1str_3:
ldilcd,0x20;Отображение " " (ёмкость)
rcalllcd_dat;
rjmplcd_1str_5;На lcd_1str_5
lcd_1str_4:
ldilcd,0x30;Определение кода для числа десятков тысяч (ёмкость)
addlcd,des_tysh;
rcalllcd_dat;Отображение числа десятков тысяч (ёмкость)
lcd_1str_5:
ldilcd,0x30;Определение кода для числа тысяч (ёмкость)
addlcd,tyshi;
rcalllcd_dat;Отображение числа тысяч (ёмкость)
ldilcd,0x30;Определение кода для числа сотен (ёмкость)
addlcd,sotni;
rcalllcd_dat;Отображение числа сотен (ёмкость)
ldilcd,0x30;Определение кода для числа десятков (ёмкость)
addlcd,desyatki;
rcalllcd_dat;Отображение числа десятков (ёмкость)
ldilcd,0x30;Определение кода для числа единиц (ёмкость)
addlcd,edinicy;
rcalllcd_dat;Отображение числа единиц (ёмкость)
uF_lcd:
ldilcd,0x20;Отображение " " (ёмкость)
rcalllcd_dat;
ldilcd,0x75;Отображение "u" (ёмкость)
rcalllcd_dat;
F_lcd:
ldilcd,0x46;Отображение "F" (ёмкость)
rcalllcd_dat;
ret;Выход из подпрограммы
;-----------------------Подпрограмма отображение второй строки LCD
lcd_2str:
;-----------------------Отображение ESR
ldilcd,0xC0;Выбор знакоместа (начало 2й строки)
rcalllcd_com;
clrtemp;Очистка temp
cpdesyatki,temp;Если значение десятков равно нулю, то переход на lcd_2str_0
breqlcd_2str_0;иначе далее
ldilcd,0x30;Определение кода для числа десятков (ESR)
addlcd,desyatki;
rcalllcd_dat;Отображение числа десятков (ESR)
rjmplcd_2str_1;Переход на lcd_2str_1
lcd_2str_0:
ldilcd,0x20;Отображение " " (ESR)
rcalllcd_dat;
lcd_2str_1:
ldilcd,0x30;Определение кода для числа единиц (ESR)
addlcd,edinicy;
rcalllcd_dat;Отображение числа единиц (ESR)
ldilcd,0x2C;Отображение "," (ESR)
rcalllcd_dat;
ldilcd,0x30;Определение кода для числа десятых долей (ESR)
addlcd,desyatye;
rcalllcd_dat;Отображение числа десятых долей (ESR)
ldilcd,0x30;Определение кода для числа сотых долей (ESR)
addlcd,sotye;
rcalllcd_dat;Отображение числа сотых долей (ESR)
ldilcd,0x20;Отображение " " (ESR)
rcalllcd_dat;
ldilcd,0x4F;Отображение "О" (ESR)
rcalllcd_dat;
ldilcd,0xBC;Отображение "м" (ESR)
rcalllcd_dat;
ret;Выход из подпрограммы
;-----------------------Подпрограмма отображение сообщений на LCD
lcd_mess:
ldiz4,8;Запись 8 в z4
cpitemp,1;Сравнение temp с 1
brnelcd_mess_2str;Если str не равен 1, то на lcd_mess_2str, иначе далее
lcd_mess_1str:
ldilcd,0x80;Выбор знакоместа (начало 1й строки)
rcalllcd_com;
rjmplcd_mess_0;На lcd_mess_0
lcd_mess_2str:
ldilcd,0xC0;Выбор знакоместа (начало 2й строки)
rcalllcd_com;
lcd_mess_0:
lpmlcd,Z+;Запись lcd байта состояния строк из ячейки с адресом из Z
rcalllcd_dat;
decz4;Уменьшение z4 на 1
cpiz4,0;Сравнение z4 с 0
brnelcd_mess_0;Если z4<>0, то на lcd_mess_0, иначе далее
ret;Выход из подпрограммы
;-----------------------Подпрограмма отображения двух строк подряд на LCD по данным из таблиц
lcd_all:
lditemp,1;Отображение 1-й строки
rcalllcd_mess;Вызов подпрограммы отображения сообщений
lditemp,2;Отображение 2-й строки
rcalllcd_mess;Вызов подпрограммы отображения сообщений
ret;Выход из подпрограммы
;-----------------------Подпрограмма вычитания (c3+c2+c1)-(z3+z2+z1)=(c3+c2+c1)
c_minus_z:
subc1,z1;
sbcc2,z2;
sbcc3,z3;
ret;Выход из подпрограммы
;-----------------------Подпрограмма сложения (c3+c2+c1)+(z3+z2+z1)=(c3+c2+c1)
c_plus_z:
addc1,z1;
adcc2,z2;
adcc3,z3;
ret;Выход из подпрограммы
;-----------------------Подпрограмма отправки команды на LCD
lcd_com:
cbiPORTB,RS;Команда
intemp,PORTB
anditemp,0b00000011;Маска 00000011 дляобнулениялишнего
oritemp,0b00001000;Логическое сложение temp с 00001000 (строб вверх + команда)
rcalllcd_out;Вызов подпрограммы lcd_out
ret;Выход из подпрограммы
;-----------------------Подпрограмма отправки данных на LCD
lcd_dat:
sbiPORTB,RS;Данные
intemp,PORTB
anditemp,0b00000011;Маска 00000011 для обнуления лишнего
oritemp,0b00001100;Логическое сложение temp с 00001100 (строб вверх + команда)
rcalllcd_out;Вызов подпрограммы lcd_out
ret;Выход из подпрограммы
;-----------------------Подпрограмма отправки на LCD
lcd_out:
sbiPORTB,E;Строб вверх
pushlcd;Сохранение lcd в стеке
andilcd,0b11110000;Маска 11110000 для обнуления младшего полубайта
orlcd,temp;Логическое сложение lcd с temp (строб вверх + команда)
outPORTB,lcd;Запись команды в порт
cbiPORTB,E;Строб вниз
sbiPORTB,E;Строб вверх
poplcd;Извлечение lcd из стека
swaplcd;Смена полубайт местами
andilcd,0b11110000;Маска 11110000 для обнуления младшего полубайта
orlcd,temp;Логическое сложение lcd с temp (строб вверх + команда)
outPORTB,lcd;Запись команды в порт
rcalldel1u;Вызов подпрограммы задержки (~1мкс)
cbiPORTB,E;Строб вниз
rcalldel40u;Вызов подпрограммы задержки (~40мкс)
rcalldel40u;Вызов подпрограммы задержки (~40мкс)
ret;Выход из подпрограммы
;-----------------------Подпрограмма отображения числовых строк (для отладки)
otlad:
sbicPIND,6;Если PD6=0, то пропуск след.команды
rjmpotlad_2;На otlad_2
rcalldel3m;Вызов подпрограммы задержки (~3мс)
sbicPIND,6;Если PD6=0, то пропуск след.команды
rjmpotlad_2;На otlad_2
rcall lcd_both_str;Вызов подпрограммы отображения двух числовых строк
otlad_1:
rcallknop_off;Вызов подпрограммы ожидания отпускания кнопки
poptemp;Очистка стека (поскольку выход не по ret)
poptemp;Очистка стека
rjmpmain;На main
otlad_2:
ret;Выход из подпрограммы
;-----------------------Подпрограмма ожидания отпускания кнопки
knop_off:
sbisPIND,6;Если PD6=1, то пропуск след.команды
rjmpknop_off;На knop_off
rcalldel3m;Вызов подпрограммы задержки (~3мс)
sbisPIND,6;Если PD6=1, то пропуск след.команды
rjmpknop_off;На knop_off
ret;Выход из подпрограммы
;-----------------------Подпрограмма передачи с 1-го по 7-й байт через USART
usart_1_7:
rcallUSART_ready;Вызов подпрограммы ожидания готовности буфера передачи
lditemp,0x10;Запись 0x10 в temp
ordes_tysh,temp;Логическое сложение des_tysh с temp, результат в des_tysh
outUDR,des_tysh;Передачаиз des_tysh в USART
lditemp,0x20;Запись 0x20 в temp
ortyshi,temp;Логическое сложение tyshi с temp, результат в tyshi
outUDR,tyshi;Передача из tyshi в USART
lditemp,0x30;Запись 0x30 в temp
orsotni,temp;Логическое сложение sotni с temp, результат в sotni
outUDR,sotni;Передача из sotni в USART
lditemp,0x40;Запись 0x40 в temp
ordesyatki,temp;Логическое сложение desyatki с temp, результат в desyatki
outUDR,desyatki;Передача из desyatki в USART
lditemp,0x50;Запись 0x50 в temp
oredinicy,temp;Логическое сложение edinicy с temp, результат в edinicy
outUDR,edinicy;Передачаиз edinicy в USART
lditemp,0x60;Запись 0x60 в temp
ordesyatye,temp;Логическое сложение desyatye с temp, результат в desyatye
outUDR,desyatye;Передача из desyatye в USART
lditemp,0x70;Запись 0x70 в temp
orsotye,temp;Логическое сложение sotye с temp, результат в sotye
outUDR,sotye;Передача из sotye в USART
ret;Выход из подпрограммы
;-----------------------Подпрограмма отображения одной числовой строки
lcd_one_str:
ldilcd,0x4E;Отображение "N"
rcalllcd_dat;
ldilcd,0x3A;Отображение ":"
rcalllcd_dat;
ldilcd,0x30;Определение кода для числа тысяч
addlcd,tyshi;
rcalllcd_dat;Отображение числа тысяч
ldilcd,0x30;Определение кода для числа сотен
addlcd,sotni;
rcalllcd_dat;Отображение числа сотен
ldilcd,0x30;Определение кода для числа десятков
addlcd,desyatki;
rcalllcd_dat;Отображение числа десятков
ldilcd,0x30;Определение кода для числа единиц
addlcd,edinicy;
rcalllcd_dat;Отображение числа единиц
ldilcd,0x30;Определение кода для числа десятых долей
addlcd,desyatye;
rcalllcd_dat;Отображение числа десятых долей
ldilcd,0x30;Определение кода для числа сотых долей
addlcd,sotye;
rcalllcd_dat;Отображение числа сотых долей
ret;Выход из подпрограммы
;-----------------------Подпрограмма отображения двух числовых строк по данным
lcd_both_str:
movc1,a1;Копирование из a1 в c1
movc2,a2;Копирование из a2 в c2
movc3,a3;Копирование из a3 в c3
;-----------------------Отображение смещения от нуля для U1 "1= "
ldilcd,0x80;Выбор знакоместа (начало 1й строки)
rcalllcd_com;
rcalllcd_one_str;Вызов подпрограммы отображения одной числовой строки
movc1,b1;Копирование из b1 в c1
movc2,b2;Копирование из b2 в c2
movc3,b3;Копирование из b3 в c3
;-----------------------Отображение смещения от нуля для U2 "2= "
ldilcd,0xC0;Выбор знакоместа (начало 2й строки)
rcalllcd_com;
rcalllcd_one_str;Вызов подпрограммы отображения одной числовой строки
ret;Выход из подпрограммы
;-----------------------Подпрограмма обработки прерывания по переполнению таймера 1
;Поскольку выход не по reti, то глобально запрещённые прерывания остаются запрещены
ovtim1:
cli;Глобально запрещаем прерывания
lditemp,3;Заносим 3 в temp
cpc3,temp;Сравнение c3 с temp
breqovtim1_0;Если с3=3, то на ovtim1_0, иначе далее
incc3;Увеличение c3 на 1
reti;Выход из подпрограммы обработки прерывания
ovtim1_0:
sbiPORTD,0;Выключение большого тока заряда конденсатора
sbiPORTD,4;Выключение малого тока заряда конденсатора
sbiPORTD,5;Включение разряда конденсатора
lditemp,0b00000000;Останов таймера
outTCCR1B,temp;
poptemp;Очистка стека (поскольку выход по clk_down, а не по reti)
poptemp;Очистка стека
rjmpclk_down;Переход на clk_down
;-----------------------Подпрограмма обработки внешнего прерывания по U1
;Поскольку выход не по reti, то глобально запрещённые прерывания остаются запрещены
com_U1:
ina1,TCNT1L;Сохраняем 1-йбайт n1
ina2,TCNT1H;Сохраняем 2-йбайт n1
mova3,c3;Копируем из c3 в a3 3-й байт n1
lditemp,0b10000000;Разрешение внешнего прерывания только по PD3 (U2)
outGIMSK,temp;
reti;Выход из подпрограммы обработки прерывания
;-----------------------Подпрограмма обработки внешнего прерывания по
U2
com_U2:
inc1,TCNT1L;Сохраняем 1-й байт n2
inc2,TCNT1H;Сохраняем 2-й байт n2
cli;Глобально запрещаем прерывания
sbiPORTD,0;Выключение большого тока заряда конденсатора
sbiPORTD,4;Выключение малого тока заряда конденсатора
sbiPORTD,5;Включение разряда конденсатора
lditemp,0b00000000;Останов таймера
outTCCR1B,temp;
poptemp;Очистка стека (поскольку выход не по reti)
poptemp;Очистка стека
- ВВЕДЕНИЕ
- 1. ПОСТАНОВКА ЗАДАЧИ
- 1.1 Описание предметной области
- 1.1.1 Вступление
- 1.1.2 Постановка задачи
- 1.1.3 Сформулируем требования к ПТС
- 1.1.4 Функциональные требования
- 1.1.5 Требования качества и надежности
- 1.1.6 Аналог и устройства
- 1.1.7 Используемые для решения задачи инструменты
- 2. РЕШЕНИЕ ЗАДАЧИ
- 2.1 Решение
- 2.2 Основные формулы расчёта искомых параметров
- 2.2.1 Определим ёмкость конденсатора
- 2.2.2 Определим ёмкостное сопротивление
- 2.2.3 Определим полное комплексное сопротивление
- 3. Спецификация
- 4. Структура программного средства
- Руководство по использованию устройства
- Заключение