Библиографический список⇐ ПредыдущаяСтр 12 из 12
1. Правила устройства электроустановок. Раздел 1. Общие правила. – Седьмое издание. – СПБ.: издательство ДЕАН, 2004.-176с. 2. Беркович М.А. Автоматика энергосистем: Учеб. для техникумов / М.А. Беркович, В.А. Гладышев, В.А. Семенов. // 3-е изд., перераб. и доп. – М.: Энергоатомиздат, 1991. - 240с. 3. Ресурсы интернет сайта http://www.mitsar.ru 4 Электрические измерения. Средства и методы измерений. Под ред. Е.Г. Шрамкова . М., “Высшая школа ”, 1972. 5. Справочник электромонтажника. Е. Г. Пантелеев. Монтаж и ремонт кабельных линий. 3. Нормы приемо-сдаточных испытаний силовых кабельных линий - Испытание кабелей 6. Как правильно измерить сопротивление изоляции электроустановок. Е. Иванов. Новости электротехники - №1(13)2002 С. 58-61. 7. Беркович М.А. Автоматика энергосистем: Учеб. для техникумов / М.А. Беркович, В.А. Гладышев, В.А. Семенов. // 3-е изд., перераб. и доп. – М.: Энергоатомиздат, 1991. - 240с. 8. Никитин К.И. Возможные направления совершенствования релейной защиты / К.И. Никитин, А.А., Вырва, М.М. Сарычев // Омский научный вестник, 2009, № 1 (77), С130-133. 9. Никитин К.И. Прогнозирование отказов кабельных линий электропередачи (статья) / К.И. Никитин, Б.Н Коврижин, П.С Рыбин // Энергетика на рубеже веков. Сборник материалов научно-практической конференции, посвященной 60-летию ОАО АК «Омскэнерго» и Омского механико-технологического техникума. Омск, ОмГТУ, 2003 . – с. 134-135. 10. Фризен А.Н., Петров А.В., Свойства изоляции нефтепогружных кабелей и возможность их прогнозирования в условиях эксплуатации, Кабели и провода, 2007, № 4. 11. Петров А.В., Фризен А.Н., Полтарыхина В.Н., Влияние старения в агрессивной среде на температурную зависимость электропроводности изоляции кабелей.// Материалы всероссийской научной конференции молодых ученых «Наука, технологии, инновации» – Новосибирск, 2004, ч.2, с. 179-181. 12. Аникеенко В.М., Петров А.В., Фризен А.Н., Электрические свойства изоляции нефтепогружных кабелей, Материалы международной научно-технической конференции «Электромеханические преобразователи энергии», Россия, Томск, 20-22 октября 2005 г., с. 399-400. 13. Фризен А.Н., Аникеенко В.М., Баклыков А.С., Влияние защитных покрытий на электрические свойства изоляции кабелей.// Материалы всероссийской научной конференции молодых ученых «Наука, технологии, инновации» – Новосибирск, 2004, ч.2, с. 195-196; 14. ГОСТ 2990 - 78 Кабели провода и шнуры. Методы испытания напряжением. 15. РД16 14.640 - 88 Кабели провода и шнуры. Испытание напряжением на проход. Типовой технологический процесс. 16. Сельницин А.А., Сидоров А.И., Бендяк Н.А. Способ определения сопротивления изоляции сетей с изолированной нейтралью напряжением 6 —35 кВ // Контроль изоляции в распределительных сетях: тезисы докладов научно–практической конференции. Челябинск. С. 13.1992. 17. Лапченков К.В. Управление состоянием изоляции в распределенных электрических сетях. — Челябинск, 1998. — 116 с. 18. Юрченко Е.Ю., Оценка состояния изоляции городских кабельных линий напряжением 6-10кВ с разработкой рекомендаций по улучшению условий электробезопасности, диссертация, Челябинск 2009. 19. Патент (51) МПК G01R31/02 (2006.01) (19)RU(11) 2348939(13)C1 Бородянский Илья Михайлович (RU), Бородянский Михаил Ефимович (RU), Самойлов Леонид Константинович (RU), Косторниченко Владимир Григорьевич (RU) 20. Патент (51) МПК G01R31/02 (2006.01) (19)RU(11)2313799(13)C1 Толочек Сергей Александрович (RU), Грудцинов Григорий Михайлович (RU), Замешин Александр Петрович 21. Патент (51) МПК G01R27/18 (2006.01) 19)RU(11)2275645(13)C2 Галка Виктор Леонидович (RU), Лазаревский Николай Алексеевич (RU), Александров Валентин Петрович (RU), Калашников Николай Семенович (RU), Плазовская Татьяна Николаевна (RU) 22. Патент МПК G01R27/18 (2006.01), G01R31/02 (2006.01) (19)RU(11)22756452(13)C2 Кислов Евгений Александрович (RU), Леонтьев Игорь Викторович (RU), Левичев Юрий Дмитриевич (RU), Кудрин Иван Александрович (RU) 23. Патент МПК G01R27/18 (19)RU(11)2149414(13)C1 Белов В.А. 24. Патент МПК G01R27/08, G01R27/18 (19)RU(11)2092862(13)C1 Григорьев Эдуард Николаевич, Мельников Евгений Георгиевич, Новоторцев Павел Николаевич 25. Патент МПК Н02Н3/17 (19)RU(11)2027271(13)C1 Покрашенко А.И., Котов К.В., Селиванов М.И. 26. Кудрявцев Д.М. Совершенствование локационных методов дистанционного контроля изоляции линий электропередачи 110-750 кВ. - дис. ... кандидата технических наук : 05.14.02 / Кудрявцев Дмитрий Михайлович; [Место защиты: Иван. гос. энергет. ун-т, Иваново, 2007] 27. Ресурсы интернет сайта www.electronpribor.ru 28. Кучинский Г.С. Частичные разряды в высоковольтных конструкциях. – Л.: Энергия, 1979.‑224 с., ил.
Приложение А. Печатная плата:
Приложение Б. Исходный код программного обеспечения с комментариями: Ядро операционной системы:
;============================================================================= ; Процедура очистки очереди ;============================================================================= ClearTaskQueue: push ZL push ZH
ldi ZL, low(TaskQueue) ldi ZH, high(TaskQueue)
ldi OSRG, $FF ; ldi Counter, TaskQueueSize
CEQL01: st Z+, OSRG ; dec Counter ; brne CEQL01 ; Loop
pop ZH pop ZL ret
;============================================================================= ; Процедура очистки таймеров ;============================================================================= ClearTimers: push ZL push ZH
ldi ZL, low(TimersPool) ldi ZH, high(TimersPool)
ldi Counter, TimersPoolSize ldi OSRG, $FF ; Empty ldi Tmp2, $00
CTL01: st Z+, OSRG ; Event st Z+, Tmp2 ; Counter Lo st Z+, Tmp2 ; Counter Hi
dec Counter ; brne CTL01 ; Loop
pop ZH pop ZL ret
;============================================================================= ; Процедура обработки очереди задач ;============================================================================= ProcessTaskQueue: ldi ZL, low(TaskQueue) ldi ZH, high(TaskQueue)
ld OSRG, Z ; For Event cpi OSRG, $FF ; No Event or Addr out of Range breq PTQL02 ; No Action
clr ZH lsl OSRG mov ZL, OSRG
subi ZL, low(-TaskProcs*2) sbci ZH, high(-TaskProcs*2) ; Add
lpm ; mov r0 <- CODE[Z] mov OSRG, r0 ld r0, Z+ ; inc Z lpm mov ZL, OSRG ; Get Addr mov ZH, r0
push ZL push ZH
; Advance Queue ldi Counter, TaskQueueSize-1 ldi ZL, low(TaskQueue) ldi ZH, high(TaskQueue)
cli
PTQL01: ldd OSRG, Z+1 ; Shift Queues st Z+, OSRG ; ; cpi OSRG, $FF ; ; breq PTQL02 ; For Long Queues dec Counter ; brne PTQL01 ; Loop ldi OSRG, $FF ; st Z+, OSRG ;
sei
pop ZH pop ZL
ijmp ; Minimize Stack Usage
PTQL02: ret ;------------------------------------------------------------------------- ; OSRG - Event SendTask: push ZL push ZH push Tmp2 push Counter
ldi ZL, low(TaskQueue) ldi ZH, high(TaskQueue)
ldi Counter, TaskQueueSize
SEQL01: ld Tmp2, Z+
cpi Tmp2, $FF breq SEQL02
dec Counter ; breq SEQL03 ; Loop rjmp SEQL01
SEQL02: st -Z, OSRG ; Store EVENT SEQL03: ; EXIT pop Counter pop Tmp2 pop ZH pop ZL ret ;------------------------------------------------------------------------ ; OSRG - Timer Event ; X - Counter SetTimer: push ZL push ZH push Tmp2 push Counter
ldi ZL, low(TimersPool) ldi ZH, high(TimersPool)
ldi Counter, TimersPoolSize
STL01: ld Tmp2, Z ; Value / Counter cp Tmp2, OSRG ; Search for Event breq STL02
subi ZL, Low(-3) ; Skip Counter sbci ZH, High(-3) ; Z+=2
dec Counter ; breq STL03 ; Loop rjmp STL01
STL02: ;cli std Z+1, XL ; Critical Section std Z+2, XH ; Update Counter ;sei ; leave Critical Section rjmp STL06 ; Exit STL03:
ldi ZL, low(TimersPool) ldi ZH, high(TimersPool)
ldi Counter, TimersPoolSize
STL04: ld Tmp2, Z ; Value / Counter cpi Tmp2, $FF ; Search for Empty Timer breq STL05
subi ZL, Low(-3) ; Skip Counter sbci ZH, High(-3) ; Z+=2
dec Counter ; breq STL06 ; No Empty Timer rjmp STL04
STL05: cli st Z, OSRG ; Set Event std Z+1, XL std Z+2, XH sei
STL06: pop Counter pop Tmp2 pop ZH pop ZL ret
;============================================================================= ; Процедура подсчета CRC8 области памяти ;============================================================================= ; Counter - количество байт ; ZL - начало адресного пространства CRC8: push tmp4 push tmp3 push tmp2
ldi tmp3,0x18 ; загрузка полинома mov tmp4,tmp3 ; в регистр HiCRC clr OSRG ; обнуление CRC регистра
CRC8_Loop: ldi tmp2,8 ; указываем 8 бит для подсчета ; ld tmp3,Z+ ; берем байт из буфера
CRC8_Bit_Loop: push tmp3 ; сохранение байта в стеке eor tmp3,OSRG ; xor байта и регистра CRC lsr tmp3 ; сдвигаем младший бит получившегося байта в перенос brcc CRC8_Zero_0 ; проверяем младший разряд байта eor OSRG,tmp4 ; если там 1, то CRC xor полином CRC8_Zero_0: ror OSRG ; если там 0, то просто сдвиг CRC регистра pop tmp3 ; возвращаем байт на место lsr tmp3 ; и сдвигаем его dec tmp2 ; brne CRC8_Bit_Loop ; переход на цикл проверки слеующего бита
dec Counter ; brne CRC8_Loop ; переход на следующий байт буфера
pop tmp2 pop tmp3 pop tmp4
ret
Wait255: push Counter ser Counter
Wait255_loop: nop nop nop nop nop
dec Counter cpi Counter, 0x00 brne Wait255_loop
pop Counter ret =================================================================================
Подпрограмма управления LCD дисплеем:
;===========LCDDefine============================================================= .equ DATA_PORT = PORTB ; LCD Data Port .equ DATA_PIN = PINB .equ DATA_DDR = DDRB
.equ CMD_PORT = PORTB ; LCD Control Port .equ CMD_PIN = PINB .equ CMD_DDR = DDRB
.equ E = 3 .equ RW = 2 .equ RS = 1
.equ SPEED = 14 ; 14 для XTAL=16MHz, 10 для XTAL=8MHz, 6 для XTAL=4MHz ================================================================================== ; LCD Init .equ LCD_CLR = 0 ; DB0: clear display .equ LCD_HOME = 1 ; DB1: return to home position
.equ LCD_ENTRY_MODE = 2 ; DB2: set entry mode .equ LCD_ENTRY_INC = 1 ; DB1: increment .equ LCD_ENTRY_SHIFT = 0 ; DB2: shift
.equ LCD_ON = 3 ; DB3: turn lcd/cursor on .equ LCD_ON_DISPLAY = 2 ; DB2: turn display on .equ LCD_ON_CURSOR = 1 ; DB1: turn cursor on .equ LCD_ON_BLINK = 0 ; DB0: blinking cursor
.equ LCD_MOVE = 4 ; DB4: move cursor/display .equ LCD_MOVE_DISP = 3 ; DB3: move display (0-> move cursor) .equ LCD_MOVE_RIGHT = 2 ; DB2: move right (0-> left)
.equ LCD_F = 5 ; DB5: function set .equ LCD_F_8B = 4 ; DB4: set 8BIT mode (0->4BIT mode) .equ LCD_F_2L = 3 ; DB3: two lines (0->one line) .equ LCD_F_10D = 2 ; DB2: 5x10 font (0->5x7 font) .equ LCD_CGRAM = 6 ; DB6: set CG RAM address .equ LCD_DDRAM = 7 ; DB7: set DD RAM address
.equ SCR_L = 0b00011000 ; Сдвиг экрана влево .equ SCR_R = 0b00011100 ; Сдвиг экрана вправо
.equ CUR_L = 0b00010000 ; Сдвиг курсора влево .equ CUR_R = 0b00010100 ; Сдвиг курсора вправо
================================================================================== ;===========LCDMacros============================================================== ; Init Config .MACRO LIB_LCD_Init ; Инициализация LCD RCALL InitHW ; Настроить контрольный порт
RCALL LCD_DELAY ; Подождать
WR_CMD (1<<LCD_F)|(0<<LCD_F_8B) ; Выдать функции в порт. Команда инициализации адресации ДВА РАЗА!!! WR_CMD (1<<LCD_F)|(0<<LCD_F_8B) ; Выдать функции в порт. Команда инициализации адресации ДВА РАЗА!!! WR_CMD (1<<LCD_F)|(0<<LCD_F_8B) ; Выдать функции в порт. Команда инициализации адресации ДВА РАЗА!!! WR_CMD (1<<LCD_F)|(0<<LCD_F_8B)|(1<<LCD_F_2L) ; Так как на 4 байтах нельзя передать сразу второй байт WR_CMD (1<<LCD_CLR) ;0x01 WR_CMD (1<<LCD_ENTRY_MODE)|(1<<LCD_ENTRY_INC) ;0x06 WR_CMD (1<<LCD_ON)|(1<<LCD_ON_DISPLAY)|(0<<LCD_ON_CURSOR)|(0<<LCD_ON_BLINK) ;0x0C WR_CMD (1<<LCD_HOME) .ENDM
================================================================================== ;Write Data .MACRO WR_DATA LDI R17,@0 RCALL DATA_WR .ENDM ================================================================================== ;Write CMD .MACRO WR_CMD LDI R17,@0 RCALL CMD_WR .ENDM ================================================================================== ; Read Data .MACRO RD_DATA RCALL DATA_RD .ENDM ==================================================================================
; Read CMD .MACRO RD_CMD RCALL CMD_RD .ENDM ================================================================================== ;Set COORD ;Syntax LCD_COORD X,Y .MACRO LCD_COORD LDI R17,(1<<LCD_DDRAM)|(@0+0x40*@1) RCALL CMD_WR .ENDM ================================================================================== ;Shift SCREEN/CURSOR .MACRO SHIFT LDI R17,@0 RCALL CMD_WR .ENDM ================================================================================== ;LCD Clear
.MACRO LCDCLR LDI R17,(1<<LCD_CLR) RCALL CMD_WR .ENDM ================================================================================== ;Write CGRAM .MACRO WR_CGADR LDI R17,(1<<LCD_CGRAM)|(@0) RCALL CMD_WR .ENDM
;Write DDRAM .MACRO WR_DDADR LDI R17,(1<<LCD_DDRAM)|(@0) RCALL CMD_WR .ENDM ;===========LCDProc=================================================================== InitHW: CBI CMD_PORT,RS ; Выставляем нужные уровни на управляющих выводах CBI CMD_PORT,RW ; Порты на выход CBI CMD_PORT,E ; И сразу же выставляются на 1
SBI CMD_DDR,RS SBI CMD_DDR,RW SBI CMD_DDR,E
RCALL PortIn ; Порт данных на вход RET
================================================================================== BusyWait: CLI ; Ожидание флага занятости контроллера дисплея RCALL PortIn ; Порты на вход
CBI CMD_PORT,RS ; Идет Команда! SBI CMD_PORT,RW ; Чтение!
BusyLoop: SBI CMD_PORT,E ; Поднять строб RCALL LCD_Delay ; Подождать
IN R16,DATA_PIN ; Считать байт
PUSH R16 Сохранить его в стек. Дело в том, что у нас R16 убивается в LCD_Delay
CBI CMD_PORT,E ; Бросить строб - первый цикл (старший полубайт) RCALL LCD_Delay ; Подождем маленько
SBI CMD_PORT,E ; Поднимем строб RCALL LCD_Delay ; Подождем CBI CMD_PORT,E ; Опустим строб - нужно для пропуска второго полубайта
RCALL LCD_Delay ; Задержка снова
POP R16 ; А теперь достаем спрятанны байт - в нем наш флаг. Может быть.
ANDI R16,0x80 ; Продавливаем по маске. Есть флаг? BRNE BusyLoop ; Если нет, то переход
BusyNo: SEI ; Разрешаем прерывания. RET ================================================================================== ; Запись команды в дисплей. Код команды в R17 CMD_WR: CLI ; Запрет прерываний RCALL BusyWait ; Ждем готовности
CBI CMD_PORT,RS ; Идет команда! RJMP WR_END ; Переход на запись
;----------------------------------------------------------------------------------------- ; Запись данных в дисплей. Код данных в R17 DATA_WR: CLI ; Запрет прерываний RCALL BusyWait ; Ждем готовности
SBI CMD_PORT,RS ; Идут данные! WR_END: CBI CMD_PORT,RW ; Запись! SBI CMD_PORT,E ; Поднять строб
RCALL PortOut ; Порт настроить на выход! PUSH R17 ; Сохраним данные которые будем выводить в стеке ANDI R17,0xF0 ; Отдавим по маске данным младшую тетраду.
IN R16,DATA_PORT ; Возьмем из порта данных старое значение ANDI R16,0x0F ; Отдавим ему старшую тетраду
PUSH R16 ; Сохраним результа в стеке. Пригодится
OR R16,R17; Склеим младшую тетраду из порта со старшей тетрадой данных
OUT DATA_PORT,R16 ; Выдадим этого мутанта в порт.
RCALL LCD_Delay ; Подождем CBI CMD_PORT,E ; Бросим строб вниз - данные ушли в индикатор
RCALL LCD_Delay ; Подождем SBI CMD_PORT,E ; Поднимем строб POP R16 ; Достанем из стека младшую тетраду из порта POP R17 ; И данные которые мы выводим
SWAP R17 ; Поменяем тетрады местами у байта данных ANDI R17,0xF0 ; Отдавим младшую тетраду
OR R16,R17 ; Склеим младшую тетраду из порта с старшей тетрадой данных (бывшая младшая) OUT DATA_PORT,R16 ; Выдадим в порт
RCALL LCD_Delay ; Подождем CBI CMD_Port,E ; Бросим строб
RCALL PortIn ; Порт вернем в прежнее состояние - на вход SEI ; Разрешим прерывания RET ; Возврат
================================================================================== ; Чтение команды из дисплея. Результат в R17 CMD_RD: CLI ; Запрет прерываний RCALL BusyWait ; Ждем контроллер CBI CMD_PORT,RS ; Команда!
RJMP RD_END ; Идем на чтение
;----------------------------------------------------------------------------------------- ; Чтение команды из дисплея. Результат в R17 DATA_RD: CLI ; Запрет прерываний RCALL BusyWait ; Ждем контроллер SBI CMD_PORT,RS ; Данные! RD_END: SBI CMD_PORT,RW ; Чтение!
SBI CMD_PORT,E ; Поднимаем строб RCALL LCD_Delay ; Ждем IN R17,DATA_PIN ; Читаем из порта байт CBI CMD_PORT,E ; Бросем строб вниз
ANDI R17,0xF0 ; Отдавливаем ему младшую тетраду SWAP R17 ; Обмениваем тетрады местами
RCALL LCD_Delay ; Ждем SBI CMD_PORT,E ; Поднимаем строб MOV R16,R17 ; Прячем старшую тетраду в R16
IN R17,DATA_PIN ; Берем еще один байт CBI CMD_PORT,E ; Бросаем строб
ANDI R17,0xF0 ; Отдавливаем младшую тетраду OR R17,R16 ; Склеиваем результат с старшим байтом SWAP R17 ; Разорваичаем байт. Т.к. первой выходила старшая тетрада
SEI ; разрешаем прерывания RET ; Возврат.
================================================================================== PortIn: IN R16,DATA_DDR ; Данные из DDR в регистр ANDI R16,0x0F ; Отдавливаем старшую тетраду - нам нужно сохранить младшую и обнулить старшую OUT DATA_DDR,R16 ; Выдаем результат в порт.
IN R16,DATA_PORT ; Берем данные из порта ORI R16,0xF0 ; Выставляем все биты старшей тетрады, не трогая младшую OUT DATA_PORT,R16 ; Выдаем в порт RET ================================================================================== PortOut: IN R16,DATA_DDR ; Данные из ДДР в регистр ORI R16,0xF0 ; Выставляем все биты старшей тетрады, не трогая младшую OUT DATA_DDR,R16 ; Выдаем данные в порт RET ================================================================================= LCD_Delay: LDI R16,SPEED ; Задержка на несколько тактов. Для того чтобы дисплей L_loop: DEC R16 ; Успевал обрабатывать данные BRNE L_loop RET =================================================================================
Подпрограмма управления дисплеем в графическом режиме:
===========LCDDefine=============================================================== .dseg LIB_LCD_GS_Step: .byte 1 ; Следующее событие в очереди LIB_LCD_GS_Buffer: .byte 2 ; 1 - data; 0 - cmd .cseg
.equ LIB_LCD_GS_Reset_P = PORTD ; Reset (active low) .equ LIB_LCD_GS_Reset_N = PIND .equ LIB_LCD_GS_Reset_D = DDRD .equ LIB_LCD_GS_Reset_I = 5
.equ LIB_LCD_GS_Commit_P = PORTD ; Storage Register .equ LIB_LCD_GS_Commit_N = PIND .equ LIB_LCD_GS_Commit_D = DDRD .equ LIB_LCD_GS_Commit_I = 6
.equ LIB_LCD_GS_CLK_P = PORTD ; Clock Register .equ LIB_LCD_GS_CLK_N = PIND .equ LIB_LCD_GS_CLK_D = DDRD .equ LIB_LCD_GS_CLK_I = 2
.equ LIB_LCD_GS_Data_P = PORTD ; Data Register .equ LIB_LCD_GS_Data_N = PIND .equ LIB_LCD_GS_Data_D = DDRD .equ LIB_LCD_GS_Data_I = 7
; Номер бита шины управления дисплея .equ LIB_LCD_GS_Line_CS1 = 1 ; 1 - on; 0 - off .equ LIB_LCD_GS_Line_CS2 = 2 ; 1 - on; 0 - off
.equ LIB_LCD_GS_Line_RST = 3 ; 1 - work; 0 - reset .equ LIB_LCD_GS_Line_RW = 4 ; 1 - read; 0 - write .equ LIB_LCD_GS_Line_DI = 5 ; 1 - data; 0 - instruction
.equ LIB_LCD_GS_Line_E = 6 ; .equ LIB_LCD_GS_Line_DEBUG = 7 ==================================================================================== ;Write Data .MACRO LIB_LCD_GS_Write_CMD cli ; Останавливаем прерывания
push XH push XL
ldi XL, @0 ldi XH, @1
ori XL, (1<<LIB_LCD_GS_Line_RST) ; Маска
rcall LIB_LCD_GS_Write
pop XL pop XH
sei ; Разрешаем прерывания .ENDM
.MACRO LIB_LCD_GS_Write_Data cli ; Останавливаем прерывания
push XH push XL
ldi XL, @0 ldi XH, @1 call LIB_LCD_GS_Write pop XL pop XH sei ; Разрешаем прерывания .ENDM ===================================================================================== LIB_LCD_GS_Init: sbi LIB_LCD_GS_Reset_D, LIB_LCD_GS_Reset_I ; Настроили на выход sbi LIB_LCD_GS_Reset_P, LIB_LCD_GS_Reset_I ; Поднимаем строб sbi LIB_LCD_GS_Commit_D, LIB_LCD_GS_Commit_I ; Настроили на выход cbi LIB_LCD_GS_Commit_P, LIB_LCD_GS_Commit_I ; Опускаем строб sbi LIB_LCD_GS_CLK_D, LIB_LCD_GS_CLK_I ; Настроили на выход cbi LIB_LCD_GS_CLK_P, LIB_LCD_GS_CLK_I ; Опускаем строб sbi LIB_LCD_GS_Data_D, LIB_LCD_GS_Data_I ; Настроили на выход cbi LIB_LCD_GS_Data_P, LIB_LCD_GS_Data_I ; Опускаем строб ret ===================================================================================== LIB_LCD_GS_Write: push OSRG ldi OSRG, (1<<LIB_LCD_GS_Line_E) ; Маска eor XL, OSRG rcall LIB_LCD_GS_SyncReg rcall LIB_LCD_GS_Transmit eor XL, OSRG rcall LIB_LCD_GS_SyncReg rcall LIB_LCD_GS_Transmit eor XL, OSRG rcall LIB_LCD_GS_SyncReg rcall LIB_LCD_GS_Transmit pop OSRG ret ===================================================================================== LIB_LCD_GS_SyncReg: ; XL - CMD ; XH - Data push ZH push ZL ldi ZL, low (LIB_LCD_GS_Buffer) ; Загружаем адрес буффера. ldi ZH, High(LIB_LCD_GS_Buffer) ; Старший и младший байты. st Z+, XL st Z, XH pop ZL pop ZH ret ===================================================================================== LIB_LCD_GS_Transmit: ; Останавливаем прерывания push OSRG ; Сохраняем регистр push Counter ; Сохраняем регистр in OSRG,SREG ; Save Sreg push OSRG ; Сохранение регистра состояния SREG push ZH push ZL ldi Counter, 2 ; Выставляем количество байт ldi ZL, low (LIB_LCD_GS_Buffer) ; Загружаем адрес буффера. ldi ZH, High(LIB_LCD_GS_Buffer) ; Старший и младший байты. sbi LIB_LCD_GS_Reset_P, LIB_LCD_GS_Reset_I ; Поднимаем строб cbi LIB_LCD_GS_Commit_P, LIB_LCD_GS_Commit_I ; Опускаем строб LIB_LCD_GS_Transmit_ByteLoop: ; Цикл отправки байта push Counter ldi Counter, 8 ; Выставляем количество бит ld OSRG, Z+ ; Читаем байт из буфера LIB_LCD_GS_Transmit_BitLoop: cbi LIB_LCD_GS_CLK_P, LIB_LCD_GS_CLK_I ; Опускаем строб lsl OSRG ; Старший бит в перенос brcc LIB_LCD_GS_Transmit_bit_put0 ; Если в переносе 0 то переходим LIB_LCD_GS_Transmit_bit_put1: sbi LIB_LCD_GS_Data_P, LIB_LCD_GS_Data_I ; Поднимаем строб rjmp LIB_LCD_GS_Transmit_bit_sync LIB_LCD_GS_Transmit_bit_put0: cbi LIB_LCD_GS_Data_P, LIB_LCD_GS_Data_I ; Опускаем строб rjmp LIB_LCD_GS_Transmit_bit_sync LIB_LCD_GS_Transmit_bit_sync: sbi LIB_LCD_GS_CLK_P, LIB_LCD_GS_CLK_I ; Поднимаем строб dec Counter cpi Counter, 0 brne LIB_LCD_GS_Transmit_BitLoop pop Counter dec Counter cpi Counter, 0 brne LIB_LCD_GS_Transmit_ByteLoop sbi LIB_LCD_GS_Commit_P, LIB_LCD_GS_Commit_I ; Поднимаем строб cbi LIB_LCD_GS_Reset_P, LIB_LCD_GS_Reset_I ; Опускаем строб pop ZL pop ZH pop OSRG ; Восстанавливаем регистр состояния SREG out SREG,OSRG ; Восстанавливаем регистр pop OSRG ; Разрешаем прерывания RCALL LCD_Delay ret ===================================================================================== ; Functions High LIB_LCD_GS_On: LIB_LCD_GS_Write_CMD (1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b00111111 ret LIB_LCD_GS_Off: LIB_LCD_GS_Write_CMD (1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b00111110 ret LIB_LCD_GS_Load: LIB_LCD_GS_Write_CMD (1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b00111111 ; Display ON LIB_LCD_GS_Write_CMD (1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01000011 ; Set Address LIB_LCD_GS_Write_CMD (1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b10111011 ; Set Page LIB_LCD_GS_Write_CMD (1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b11000001 ; Display Line LIB_LCD_GS_Write_Data(1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01010101 LIB_LCD_GS_Write_Data(1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01010101 LIB_LCD_GS_Write_Data(1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01010101 LIB_LCD_GS_Write_Data(1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01010101 LIB_LCD_GS_Write_Data(1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01010101 LIB_LCD_GS_Write_Data(1<<LIB_LCD_GS_Line_CS1)|(1<<LIB_LCD_GS_Line_CS2), 0b01010101 ret ;LIB_LCD_GS_COORD: ;LIB_LCD_GS_SetY: ===================================================================================== Подпрограмма реализации сетевого интерфейса ;============================================================================= ; Данные в памяти ;============================================================================= .equ UART_Packet_Size = 12 .dseg UART_Address: .byte 1 UART_Packet_CRC8: .byte 1 UART_R_Count: .byte 1 UART_R_SAddress: .byte 1 UART_R_DAddress: .byte 1 UART_R_Command: .byte 1 UART_R_Data: .byte 8 UART_R_Data_CRC: .byte 1 UART_S_Count: .byte 1 UART_S_SAddress: .byte 1 UART_S_DAddress: .byte 1 UART_S_Command: .byte 1 UART_S_Data: .byte 8 . UART_S_Data_CRC: .byte 1 .cseg ;========================================================================== ; Macro ;========================================================================== .MACRO mk_uart_crc8 ; @0 = UART_[R|S]_Address ; OSRG - Out push Counter ldi Counter, UART_Packet_Size-1 ; Пакет из 11+crc байт ldi ZL, low(@0) ldi ZH, high(@0) rcall CRC8 pop Counter .ENDMACRO ; Добавить управление драйвером приема .MACRO mk_uart_irq_rx_enable sbi UCSRB, RXCIE .ENDMACRO .MACRO mk_uart_irq_rx_disable cbi UCSRB, RXCIE .ENDMACRO .MACRO mk_uart_irq_tx_enable sbi UCSRB, TXCIE sbi UCSRB, UDRIE .ENDMACRO .MACRO mk_uart_irq_tx_disable cbi UCSRB, TXCIE cbi UCSRB, UDRIE .ENDMACRO .MACRO mk_uart_packet_clear push OSRG push Counter clr OSRG ldi ZL, low(@0) ldi ZH, high(@0) ldi Counter, UART_Packet_Size-1 rcall UART_Packet_Clear pop Counter pop OSRG .ENDMACRO ;============================================================================= ; Команда начала отправки буффера ;============================================================================= UART_SendBuffer: StateSave ; Сохраняем состояние в стек clr ZL ; Очищаем регистр для адреса ячейки clr ZH ; lds Counter, UART_S_Count ; Читаем значение счетсчика cpi Counter, 0x01 ; Проверяем на 0x01 brne UART_SendBuffer_Exit ; Нет, валим mk_uart_irq_rx_disable ; Запрещаем прием данных sbis UCSRA,UDRE ; Пропуск если нет флага готовности rjmp UART_SendBuffer_Wait ; ждем готовности - флага UDRE ldi ZL, UART_S_Count ; Записываем начальное положение буфера add ZL, Counter ; Суммируем и получаем [адрес байта для записи] ld OSRG, Z ; Считываем из памяти нужный бай out UDR, OSRG ; Отсылаем текущий байт в порт INC Counter ; Увеличиваем текущее положение каретки на 1 STS UART_S_Count, Counter ; Сохраняем каретку mk_uart_irq_tx_enable ; Разрешаем передачу данных rjmp UART_SendBuffer_Exit UART_SendBuffer_Wait: SetTimerTask TS_UART_SendBuffer, 5 ; Вызываем сами себя через 5 милисекунд UART_SendBuffer_Exit: StateRestore ; Восстанавливаем состояние из стека ret ;============================================================================= ; Процедура разбора входяшего пакета(полного) ;============================================================================= UART_ReciveParse: StateSave ; Сохраняем состояние в стек lds Counter, UART_R_Count ; Читаем значение счетсчика cpi Counter, 0xFF ; Проверяем стоп бит brne UART_ReciveParse_Exit ; Стоит не стоп бит, пропускаем обработку lds Counter, UART_S_Count ; Читаем значение счетсчика cpi Counter, 0xFF ; Проверяем стоп бит brne UART_ReciveParse_Wait ; Стоит не стоп бит, подождем 50 миллисекунд lds Counter, UART_R_Command ; Читаем из памяти команду lsl Counter ; Сдвигом влево умножаем содержимое Counter на два. ldi ZL, low (UART_Commands*2) ; Загружаем адрес нашей таблицы. ldi ZH, High(UART_Commands*2) ; Старший и младший байты. clr OSRG ; Сбрасываем регистр OSRG - нам нужен ноль. add ZL, Counter ; Складываем младший байт адреса. Если возникнет переполнение adc ZH, OSRG ; То вылезет флаг переноса. lpm Counter,Z+ ; Загрузили в Counter адрес из таблицы lpm OSRG,Z ; Старший и младший байт movw ZH:ZL,OSRG:Counter ; забросили адрес в Z ijmp ; Переходим к обработке команды UART_ReciveParse_Wait: SetTimerTask TS_UART_ReciveParse, 5 ; Вызываем сами себя через 5 милисекунд UART_ReciveParse_Exit: StateRestore ; Восстанавливаем состояние из стека ret UART_ReciveParse_Return: lds Counter, UART_S_Count ; Читаем значение счетсчика cpi Counter, 0x01 ; Проверяем на наличае начального положения каретки brne UART_ReciveParse_ClearAll ; Не стоит: значит сносим буффера и включаем прерывания lds OSRG, UART_Packet_CRC8 ; Получаем параметр о CRC8 cpi OSRG, 0x00 ; Если параметр 0x00 ;breq UART_ReciveParse_SetAddrs ; то пропускаем проверку CRC8 mk_uart_crc8 UART_S_Count+1 ; Расчитываем CRC8 (выхлоп в OSRG) sts UART_S_Data_CRC, OSRG ; Сохраняем контрольную сумму UART_ReciveParse_SetAddrs: lds OSRG, UART_R_SAddress ; Считываем исходяший адрес sts UART_S_DAddress, OSRG ; Вписываем адрес получателя lds OSRG, UART_Address ; Считываем адрес устройства sts UART_S_SAddress, OSRG ; Вписываем исходяший адрес lds OSRG, UART_R_Command ; Считываем номер команды sts UART_S_Command, OSRG ; Вписываем номер команды rcall UART_SendBuffer ; Вызываем функцию отправки первого байта rjmp UART_ReciveParse_Clear ; Сносим входящий буфер UART_ReciveParse_ClearAll: ; Сносим данные и выставляем нули mk_uart_packet_clear UART_R_Count mk_memory_set UART_R_Count, 0x01 mk_memory_set UART_S_Count, 0xFF mk_uart_irq_tx_disable ; Запрещаем передачу данных mk_uart_irq_rx_enable ; Разрешаем прием данных rjmp UART_ReciveParse_Exit UART_ReciveParse_Clear: ; Сносим данные и выставляем нули mk_uart_packet_clear UART_R_Count mk_memory_set UART_R_Count, 0x01 rjmp UART_ReciveParse_Exit ;============================================================================= ; Список команд протокола ;============================================================================= ; 0x00 - Ping ; пинговалка, спросили - ответили UART_Command_00: mk_memory_set UART_S_Count, 0x01 ; Выставляем каретку, для отправки mk_memory_set UART_S_Data, 0x07 ; Копируем LIB_1Wire_DS1820_Strachpad ; push OSRG ; push Counter ; push ZL ; push ZH ; push XL ; push XH ; ldi Counter, 8 ; ldi ZL, low (LIB_1Wire_DS1820_Strachpad) ; Загружаем адрес нашей таблицы. ; ldi ZH, High(LIB_1Wire_DS1820_Strachpad) ; Старший и младший байты. ; ldi XL, low (UART_S_Data) ; Загружаем адрес нашей таблицы. ; ldi XH, High(UART_S_Data) ; Старший и младший байты. ; UART_Command_00_data_loop: ; ld OSRG, Z+ ; st X+, OSRG ; ; dec Counter ; cpi Counter, 0x00 ; brne UART_Command_00_data_loop ; ; pop XH ; pop XL ; pop ZH ; pop ZL ; pop Counter ; pop OSRG rjmp UART_ReciveParse_Return ; Возвращаемся в процедуру проверки буффера ;============================================================================= UART_Command_01: mk_memory_set UART_S_Count, 0x01 ; Выставляем каретку, для отправки mk_memory_set UART_S_Data, 0x00 Debug_Led_Yellow_On push OSRG push Counter push ZL push ZH push XL push XH ldi Counter, 2 ldi ZL, low (UART_R_Data) ; Загружаем адрес нашей таблицы. ldi ZH, High(UART_R_Data) ; Старший и младший байты. ldi XL, low (LIB_LCD_GS_Buffer) ; Загружаем адрес нашей таблицы. ldi XH, High(LIB_LCD_GS_Buffer) ; Старший и младший байты. UART_Command_01_data_loop: ld OSRG, Z+ st X+, OSRG dec Counter cpi Counter, 0x00 brne UART_Command_01_data_loop rcall LIB_LCD_GS_Transmit pop XH pop XL pop ZH pop ZL pop Counter pop OSRG ; Восстанавливаем регистр Debug_Led_Yellow_Off rjmp UART_ReciveParse_Return ; Возвращаемся в процедуру проверки буффера ;============================================================================= UART_Command_02: mk_memory_set UART_S_Count, 0x01 ; Выставляем каретку, для отправки mk_memory_set UART_S_Data, 0xff Debug_Led_Yellow_Off push OSRG push ZL push ZH ldi ZL, low (UART_R_Data) ; Загружаем адрес нашей таблицы. ldi ZH, High(UART_R_Data) ; Старший и младший байты. ld OSRG, Z ; call LIB_Power_Update pop ZH pop ZL pop OSRG rjmp UART_ReciveParse_Return ; Возвращаемся в процедуру проверки буфера ;============================================================================= UART_Commands: .dw UART_Command_00, UART_Command_01, UART_Command_02 ============================================================================= UART_Packet_Clear: st Z+, OSRG dec Counter brne UART_Packet_Clear ret ============================================================================== Основной файл прошивки (generic) .include "m32def.inc" ; Используем Mega32 ;============================================================================= .include "RTOS-Define.asm" ; Наши все определения переменных .include "RTOS-Macros.asm" ; Все макросы у нас тут .include "RTOS-Interrupts.asm" ; Все вектора прерываний ;============================================================================= .ORG INT_VECTORS_SIZE ; Конец таблицы прерываний ;============================================================================= .include "RTOS-Network.asm" ; Все операции с сетью.+ ;============================================================================= .include "RTOS-InterruptsProcs.asm" ; Все обработчики прерываний ;============================================================================= ; Library Code ;============================================================================= .include "LIB-LCD.asm" ; LCD экран. .include "LIB-LCD-GraphShift.asm" ; LCD экран графический на сдвиговых регистрах ; .include "LIB-Power.asm" ; Релюшки. .include "LIB-1Wire-DS1820.asm" ; DS1820 Датчик темпиратуры ; .include "LIB-I2C.asm" ; I2C ; .include "LIB-I2C-PCF8583.asm" ; PCF8583 - Часы ; .include "LIB-SPI-SDCard.asm" ; S D Card ; .include "LIB-SPI-AD7705.asm" ; AD7705 - 2-/3-Channel 16-Bit, Sigma-Delta ADCs ;============================================================================= ; Main code ;============================================================================= Reset: .include "RTOS-Init.asm" ; Все инициализации тут. ;============================================================================= ; Library Code ;============================================================================= ; LCD LIB_LCD_Init rcall LIB_LCD_GS_Init rcall LIB_LCD_GS_On rcall LIB_LCD_GS_Load ; rcall LIB_Power_Init rcall LIB_IR_Init rcall LIB_1Wire_DS1820_Init ; ; I2C RTS ; LIB_IIC_Init ; SPI ; LIB_SPI_Init ; rcall LIB_SPI_SDCard_Init ; rcall LIB_SPI_AD7705_Init ; LIB_SPI_AD7705_Device_On ; Выбираем устройство rcall SW_Display_Init ; Начинаем отрисовку ;============================================================================= ; Background ;============================================================================= Background: rcall Debug_LedBlink MainLoop: wdr ; Reset Watch DOG (Если не "погладить" "собаку". то она устроит reset для процессора) rcall ProcessTaskQueue ; Обработка очереди процессов rcall Idle ; Простой Ядра rjmp MainLoop ; Основной цикл микроядра РТОС ;============================================================================= ; все задачи которые будет выболнять микроядро ;============================================================================= Idle: NOP RET ;----------------------------------------------------------------------------- ;Task1: RET ;----------------------------------------------------------------------------- ;Task2: RET ;----------------------------------------------------------------------------- Task3: RET ;----------------------------------------------------------------------------- Task4: RET ;----------------------------------------------------------------------------- Task5: RET ;----------------------------------------------------------------------------- Task6: RET ;----------------------------------------------------------------------------- Task7: RET ;----------------------------------------------------------------------------- Task8: RET ;----------------------------------------------------------------------------- Task9: RET ;----------------------------------------------------------------------------- Debug_LedBlink: SetTimerTask TS_Debug_LedBlink, 500 ; rcall LIB_SPI_AD7705_Init ; rcall LIB_SPI_AD7705_Configure_CH1 ; LIB_SPI_RWtest ; rcall LIB_SPI_AD7705_Read_CH1 ; rcall LIB_SPI_AD7705_Read ; ;LIB_SPI_Device_On ; sbis UCSRA, UDRE ; rjmp Skip ; lds OSRG, LIB_SPI_AD7705_CH1_Data_H ; out UDR, OSRD ; rcall Debug_SD Skip: lds OSRG, Debug_Led_Red_State cpi OSRG, 0 breq Light sbic Debug_Led_Red_N, Debug_Led_Red rjmp Dark Light: Debug_Led_Red_On ldi OSRG, 0xFF sts Debug_Led_Red_State, OSRG RET Dark: Debug_Led_Red_Off ldi OSRG, 0x00 sts Debug_Led_Red_State, OSRG RET ;Debug_SD: ; ldi ZL, low(LIB_SPI_SDCard_Buffer) ; ldi ZH, high(LIB_SPI_SDCard_Buffer)
; clr LIB_SPI_SDCard_AdrHH ; Очищаем Адресацию ; clr LIB_SPI_SDCard_AdrHL ; clr LIB_SPI_SDCard_AdrLH clr LIB_SPI_SDCard_AdrLL ; rcall LIB_SPI_SDCard_ReadSector ; ====== ; ldi ZL, low(LIB_SPI_SDCard_Buffer) ; ldi ZH, high(LIB_SPI_SDCard_Buffer) ; clr LIB_SPI_SDCard_AdrHH ; Очищаем Адресацию ; clr LIB_SPI_SDCard_AdrHL ; clr LIB_SPI_SDCard_AdrLH ; clr LIB_SPI_SDCard_AdrLL ; rcall LIB_SPI_SDCard_ReadSector ; ldi ZL, low(LIB_SPI_SDCard_Buffer) ; ldi ZH, high(LIB_SPI_SDCard_Buffer) ; ser Counter ; ML: ; ld OSRG, Z+ ; Считываем из памяти нужный бай ; ML2: ; sbis UCSRA, UDRE ; rjmp ML2 ; out UDR, OSRG ; Отсылаем текуший байт в порт ; dec Counter ; brne ML ; ret ;============================================================================= ; RTOS Here ;============================================================================= .include "RTOS-Kernel.asm" ; Подклчюаем ядро ОС TaskProcs: .dw Idle ; [00] .dw UART_ReciveParse ; [01] .dw UART_SendBuffer ; [02] .dw LIB_1Wire_DS1820_Task ; [03] LIB_1Wire_DS1820_Task .dw Task4 ; [04] .dw LIB_IR_Task ; [05] .dw Task6 ; [06] .dw Task7 ; [07] .dw SW_Display_Update ; [08] .dw Debug_LedBlink ; [09] ;============================================================================ Управление внешними устройствами при помощи электромагнитных реле: .equ LIB_Power_P = PORTC .equ LIB_Power_D = DDRC .equ LIB_Power_N = PINC .dseg LIB_Power_RAM: .byte 1 ; Буффер для приема\\передачи .eseg LIB_Power_EEROM: .byte 1 ; Буффер для приема\\передачи .cseg LIB_Power_Init: ser OSRG ; 0xFF out LIB_Power_D, OSRG ; Инициализируем порт на выход ; Read from EEROM to RAM ret ; OSRG - New Status LIB_Power_Update: push ZL push ZH out LIB_Power_P, OSRG ldi ZL, low (LIB_Power_RAM) ; Загружаем адрес нашей таблицы. ldi ZH, High(LIB_Power_RAM) ; Старший и младший байты. st Z, OSRG pop ZH pop ZL ret ; OSRG - Status LIB_Power_Read: ret Работа с датчиком температуры: .equ LIB_1Wire_DS1820_D = DDRD ; .equ LIB_1Wire_DS1820_P = PORTD ; .equ LIB_1Wire_DS1820_N = PIND ; .equ LIB_1Wire_DS1820_DQ = 4 ; DQ .dseg LIB_1Wire_DS1820_Step: .byte 1 ; Следующее событие в очереди LIB_1Wire_DS1820_Strachpad: .byte 8 ; Текущее значение LIB_1Wire_DS1820_Buffer: .byte 9 ; Временный буффер .cseg .equ LIB_1Wire_DS1820_TaskId = 3 ; ID основного процесса библиотеки .equ LIB_1Wire_DS1820_TaskParseId= 0xFF ; ID процесса, который надо запустить при получении данных ===================================================================================== .MACRO LIB_1Wire_DS1820_TaskSet ldi OSRG, @0 sts LIB_1Wire_DS1820_Step, OSRG SetTask LIB_1Wire_DS1820_TaskId .ENDM .MACRO LIB_1Wire_DS1820_TaskSetTimer ldi OSRG, @0 sts LIB_1Wire_DS1820_Step, OSRG SetTimerTask LIB_1Wire_DS1820_TaskId, @1 .ENDM ===================================================================================== LIB_1Wire_DS1820_Init: LIB_1Wire_DS1820_TaskSetTimer 0x00, 100 ret ===================================================================================== LIB_1Wire_DS1820_Task: push XH push XL push ZH push ZL push OSRG push Counter lds XL, LIB_1Wire_DS1820_Step ; Читаем из памяти команду lsl XL ; Сдвигом влево умножаем содержимое Counter на два. ldi ZL, low (LIB_1Wire_DS1820_Commands*2) ; Загружаем адрес нашей таблицы. ldi ZH, High(LIB_1Wire_DS1820_Commands*2) ; Старший и младший байты. clr XH ; Сбрасываем регистр OSRG - нам нужен ноль. add ZL, XL ; Складываем младший байт адреса. Если возникнет переполнение adc ZH, XH ; То вылезет флаг переноса. lpm XL,Z+ ; Загрузили в Counter адрес из таблицы lpm XH,Z ; Старший и младший байт movw ZH:ZL,XH:XL ; забросили адрес в Z ijmp ; Переходим к обработке команды LIB_1Wire_DS1820_Return: pop Counter pop OSRG pop ZL pop ZH pop XL pop XH ret ===================================================================================== LIB_1Wire_DS1820_Command_00: ; Инициализация преобразования rcall LIB_1Wire_DS1820_Reset ; вызов обнуления линии ldi OSRG, 0xCC ; пропуск идентификации rcall LIB_1Wire_DS1820_WriteByte ldi OSRG, 0x44 ; начало преобразования rcall LIB_1Wire_DS1820_WriteByte LIB_1Wire_DS1820_TaskSetTimer 0x01, 10 rjmp LIB_1Wire_DS1820_Return ;================ LIB_1Wire_DS1820_Command_01: ; Получение данных rcall LIB_1Wire_DS1820_Reset ; вызов обнуления линии ldi OSRG, 0xCC ; пропуск идентификации rcall LIB_1Wire_DS1820_WriteByte ldi OSRG, 0xBE ; запрос на данные rcall LIB_1Wire_DS1820_WriteByte LIB_1Wire_DS1820_TaskSet 0x02 rjmp LIB_1Wire_DS1820_Return ;================ LIB_1Wire_DS1820_Command_02: ; Получение данных ldi Counter, 9 ldi ZL, low (LIB_1Wire_DS1820_Buffer) ; Загружаем адрес нашей таблицы. ldi ZH, High(LIB_1Wire_DS1820_Buffer) ; Старший и младший байты. LIB_1Wire_DS1820_Command_02_loop: rcall LIB_1Wire_DS1820_ReadByte st Z+, OSRG dec Counter brne LIB_1Wire_DS1820_Command_02_loop LIB_1Wire_DS1820_TaskSet 0x03 rjmp LIB_1Wire_DS1820_Return ;================ LIB_1Wire_DS1820_Command_03: Подсчет контрольной суммы и копирование в рабочую область ldi ZL, low(LIB_1Wire_DS1820_Buffer) ldi ZH, high(LIB_1Wire_DS1820_Buffer) ldi Counter, 8 rcall CRC8 ; Считаем контрольную сумму буффера ld OSRD, Z cp OSRG, OSRD ; Если не сходится то пропускаем копирование brne LIB_1Wire_DS1820_Command_03_skip
cli ; Копирование памяти! ОТРУБАЕМ ПРЕРЫВАНИЯ ldi XL, low(LIB_1Wire_DS1820_Strachpad) ; Копируем буфер в страчпад ldi XH, high(LIB_1Wire_DS1820_Strachpad) ldi ZL, low(LIB_1Wire_DS1820_Buffer) ldi ZH, high(LIB_1Wire_DS1820_Buffer) ldi Counter, 8 LIB_1Wire_DS1820_Command_03_loop: ld OSRG, Z+ st X+, OSRG dec Counter brne LIB_1Wire_DS1820_Command_03_loop sei ; Включаем прерывания ldi OSRG, LIB_1Wire_DS1820_TaskParseId ; Загружаем ID процедуры обработки cpi OSRG, 0xFF ; Если 0xFF то пропускаем обработку breq LIB_1Wire_DS1820_Command_03_skip SetTask LIB_1Wire_DS1820_TaskParseId ; Ставим в очередь процедуру обработки LIB_1Wire_DS1820_Command_03_skip: LIB_1Wire_DS1820_TaskSet 0x00 rjmp LIB_1Wire_DS1820_Return ;================ LIB_1Wire_DS1820_Commands: .dw LIB_1Wire_DS1820_Command_00, LIB_1Wire_DS1820_Command_01, LIB_1Wire_DS1820_Command_02, LIB_1Wire_DS1820_Command_03 ===================================================================================== LIB_1Wire_DS1820_Reset: cbi LIB_1Wire_DS1820_P, LIB_1Wire_DS1820_DQ
sbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ
ldi OSRG, 220 ; обнуление 600мкс rcall LIB_1Wire_DS1820_Delay
cbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ ldi OSRG, 220 ; принятие импульса присутствия 600мкс rcall LIB_1Wire_DS1820_Delay ret ===================================================================================== ; IN - OSRG - Command LIB_1Wire_DS1820_WriteByte: push Counter ldi Counter,8 LIB_1Wire_DS1820_WriteByte_loop: lsr OSRG ; Старший бит в перенос brcs LIB_1Wire_DS1820_WriteByte_loop_put_1 ; пререход если CF=1 LIB_1Wire_DS1820_WriteByte_loop_put_0: push OSRG cbi LIB_1Wire_DS1820_P, LIB_1Wire_DS1820_DQ sbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ ldi OSRG, 26 ; 70мкс rcall LIB_1Wire_DS1820_Delay cbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ rjmp LIB_1Wire_DS1820_WriteByte_loop_wait LIB_1Wire_DS1820_WriteByte_loop_put_1: push OSRG cbi LIB_1Wire_DS1820_P, LIB_1Wire_DS1820_DQ sbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ ldi OSRG, 1 ; 2,7мкс rcall LIB_1Wire_DS1820_Delay cbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ ldi OSRG, 20 ; 60мкс - продление "1" rcall LIB_1Wire_DS1820_Delay rjmp LIB_1Wire_DS1820_WriteByte_loop_wait LIB_1Wire_DS1820_WriteByte_loop_wait: ldi OSRG, 1 ; 2,7мкс rcall LIB_1Wire_DS1820_Delay pop OSRG dec Counter brne LIB_1Wire_DS1820_WriteByte_loop ; проверка счетчика pop Counter ret ===================================================================================== LIB_1Wire_DS1820_ReadByte: push Counter push OSRD clr OSRD ldi Counter, 8 LIB_1Wire_DS1820_ReadByte_loop: cbi LIB_1Wire_DS1820_P, LIB_1Wire_DS1820_DQ sbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ ldi OSRG, 1 ; 2,7мкс rcall LIB_1Wire_DS1820_Delay cbi LIB_1Wire_DS1820_D, LIB_1Wire_DS1820_DQ ldi OSRG, 3 ; 2,7мкс rcall LIB_1Wire_DS1820_Delay sbic LIB_1Wire_DS1820_N, LIB_1Wire_DS1820_DQ ; читаем бит с DQ и пропускаем переход если бит пустой rjmp LIB_1Wire_DS1820_loop_get_1 LIB_1Wire_DS1820_loop_get_0: clc rjmp LIB_1Wire_DS1820_loop_render LIB_1Wire_DS1820_loop_get_1: sec ; rjmp LIB_1Wire_DS1820_loop_render LIB_1Wire_DS1820_loop_render: ror OSRD ldi OSRG, 22 ; 2,7мкс rcall LIB_1Wire_DS1820_Delay dec Counter brne LIB_1Wire_DS1820_ReadByte_loop mov OSRG, OSRD pop OSRD pop Counter ret ===================================================================================== ; IN - OSRG LIB_1Wire_DS1820_Delay: push Counter LIB_1Wire_DS1820_Delay_loop: ldi Counter, 3 ; 2,75uS*wreg LIB_1Wire_DS1820_Delay_loop_sub: nop dec Counter brne LIB_1Wire_DS1820_Delay_loop_sub dec OSRG brne LIB_1Wire_DS1820_Delay_loop pop Counter ret ===================================================================================== Реализация I2C протокола: ..MACRO LIB_IIC_Init mk_register_set TWBR,0xC0 ; Настройка частоты работы TWI mk_register_set TWSR, (1<<TWPS1|1<<TWPS0) .ENDM ; Даем старт на линию I2C IIC_START: mk_register_set TWCR,1<<TWINT|1<<TWSTA|1<<TWEN|0<<TWIE IIC_S: IN OSRG,TWCR ANDI OSRG,1<<TWINT BREQ IIC_S ; Ждем пока передатчик IIC выполнит старт RET ;----------------------------------------------------------------------------- ;Посылаем байт по IIC IIC_BYTE: OUT TWDR,OSRG mk_register_set TWCR,1<<TWINT|1<<TWEN|0<<TWIE IIC_B: IN OSRG,TWCR ANDI OSRG,1<<TWINT ; Ждем пока передатчик пошлет байт BREQ IIC_B RET ;----------------------------------------------------------------------------- ; Принять байт. IIC_RCV: mk_register_set TWCR,1<<TWINT|1<<TWEN|1<<TWEA|0<<TWIE IIC_R: IN OSRG,TWCR ANDI OSRG,1<<TWINT BREQ IIC_R ; Ждем пока байт будет принят RET ;----------------------------------------------------------------------------- ; Принять последний байт. IIC_RCV2: mk_register_set TWCR,1<<TWINT|1<<TWEN|0<<TWEA|0<<TWIE IIC_R2: IN OSRG,TWCR ANDI OSRG,1<<TWINT ; Ждем пока байт будет принят BREQ IIC_R2 RET ;----------------------------------------------------------------------------- ; Сгенерировать STOP IIC_STOP: mk_register_set TWCR,1<<TWINT|1<<TWSTO|1<<TWEN|0<<TWIE IIC_ST: IN OSRG,TWCR ANDI OSRG,1<<TWSTO BREQ IIC_ST ; Ждем пока не будет готов стоп. RET Реализация часов и календаря: .equ LIB_SPI_AD7705_D = DDRB ; .equ LIB_SPI_AD7705_P = PORTB ; .equ LIB_SPI_AD7705_N = PINB ; .equ LIB_SPI_AD7705_MOSI = 5 ; .equ LIB_SPI_AD7705_MISO = 6 ; .equ LIB_SPI_AD7705_SCK = 7 ; .equ LIB_SPI_AD7705_DRDY = 2 ; .equ LIB_SPI_AD7705_CS = 1 ; ===================================================================================== .MACRO LIB_SPI_AD7705_Device_On cbi LIB_SPI_AD7705_P, LIB_SPI_AD7705_CS ; Опускаем строб(линия инверная) .ENDM .MACRO LIB_SPI_AD7705_Device_Off sbi LIB_SPI_AD7705_P, LIB_SPI_AD7705_CS ; Поднимаем строб .ENDM ===================================================================================== LIB_SPI_AD7705_COM: sbis UCSRA, UDRE rjmp LIB_SPI_AD7705_COM out UDR, OSRG ret ===================================================================================== LIB_SPI_AD7705_Init: cbi LIB_SPI_AD7705_D, LIB_SPI_AD7705_DRDY ; Порт ны вход sbi LIB_SPI_AD7705_P, LIB_SPI_AD7705_DRDY ; С поддяжкой в 100к до питания sbi LIB_SPI_AD7705_D, LIB_SPI_AD7705_MOSI ; Порт на выход sbi LIB_SPI_AD7705_D, LIB_SPI_AD7705_SCK ; Порт на выход sbi LIB_SPI_AD7705_D, LIB_SPI_AD7705_CS ; Порт на выход sbi LIB_SPI_AD7705_P, LIB_SPI_AD7705_CS ; Поднимаем строб cbi LIB_SPI_AD7705_D, LIB_SPI_AD7705_MISO ; Порт ны вход sbi LIB_SPI_AD7705_P, LIB_SPI_AD7705_MISO ; С поддяжкой в 100к до питания mk_register_set GICR, (1<<INT2) ; Включаем прерывание на DRDY ; mk_register_set SPCR, ((1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(0<<SPI2X)|(1<<SPR1)|(1<<SPR0)) ; mk_register_set SPCR, ((1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(0<<SPI2X)|(1<<SPR1)|(1<<SPR0)) mk_register_set SPCR, 0b1011111 ret ===================================================================================== ; OSRG - Input byte LIB_SPI_AD7705_WriteToReg: LIB_SPI_AD7705_Device_On ; Выбираем устройство out SPDR, OSRG ; Начать передачу LIB_SPI_AD7705_WriteToReg_wait: sbis SPSR, SPIF ; Ожидаем конца передачи rjmp LIB_SPI_AD7705_WriteToReg_wait LIB_SPI_AD7705_Device_Off ; Выбираем устройство in OSRG, SPDR ; Чтение данных rcall LIB_SPI_AD7705_COM ret ===================================================================================== LIB_SPI_AD7705_Read: rcall LIB_SPI_AD7705_Wait_DRDY push OSRG push Counter ldi Counter, 2 LIB_SPI_AD7705_Device_On ; Выбираем устройство LIB_SPI_AD7705_Read_loop: clr OSRG out SPDR, OSRG ; Начать передачу LIB_SPI_AD7705_Read_loop_wait: sbis SPSR, SPIF ; Ожидаем конца передачи rjmp LIB_SPI_AD7705_Read_loop_wait in OSRG, SPDR rcall LIB_SPI_AD7705_COM dec Counter brne LIB_SPI_AD7705_Read_loop LIB_SPI_AD7705_Device_Off ; Выбираем устройство pop Counter pop OSRG ret ===================================================================================== LIB_SPI_AD7705_Configure_CH1: push OSRG ldi OSRG, 0x20 ; Send to Comm Reg: Next Write Clk rcall LIB_SPI_AD7705_WriteToReg ldi OSRG, 0x01 ; Send to ClkReg: Clock Bits and Update rate rcall LIB_SPI_AD7705_WriteToReg ldi OSRG, 0x10 ©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|