[an error occurred while processing this directive]
Получите вашу гранату...
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено д 20 декабря 2005 г. 13:18
В ответ на: Ответ: А какой это родной. Я попробовал около 5 разных и всё одно и то же отправлено <font color=gray>Ericsson</font> 20 декабря 2005 г. 13:13

; ------ DALLAS DS1990A based lock ------
; ------ Supports 9 keys + 1 master-key -----
; ------ wubblick@yahoo.com -------

;TARGET = AT89C2051
#define DEBUG 0 ;0-off, 1-rdfn ports, 2-on
//#INCLUDE "LIBR51.ASM" ;8051 SFR set

CLK_KHZ equ 10000 ;OSC frequency, KHZ
RTC_MS equ 20 ;system clock, MS

RTCV set (-(CLK_KHZ*RTC_MS)/12)

;Macros:

#define LO(XXX) XXX & 0FFH
#define HI(XXX) (XXX shr 8) & 0FFH

//#IF (DEBUG>1)
//#INCLUDE "LIBDEF.ASM"
//#ENDIF

; ------ Constantes ------

MAXK EQU 9 ;max number of keys
I2C_ADDR EQU 0A0H ;I2C address for 24C02 (A0,A1,A2=0)
TMATMV EQU 25 ;x20mS TM access delay time
AENTMV EQU 2 ;x20mS TM access enable delay
OPNTMV EQU 150 ;x20mS open pulse duration
RETTMV EQU 250 ;x20mS return to normal mode delay

; ------ Ports ------

DDATA EQU P1 ;display data port
KEYOP EQU INT0 ;key OPEN
OWP EQU INT1 ;1-Wire port
SDA EQU T0 ;I2C SDA line
SCL EQU T1 ;I2C SCL line
SOLEN EQU RXD ;solenoid control line
WD EQU TXD ;watchdog line
KEYSL EQU P3.7 ;key SELECT

; ------ Variables ------

;Bit addressing memory:

RTPC EQU 20H ;Real time program counter
T040M bit 20H.0 ;40mS period bit
T080M EQU 20H.1 ;80mS period bit
T160M EQU 20H.2 ;160mS period bit
T320M EQU 20H.3 ;320mS period bit
T640M EQU 20H.4 ;640mS period bit
T1S28 EQU 20H.5 ;1.28S period bit
T2S56 EQU 20H.6 ;2.56S period bit
T5S12 EQU 20H.7 ;5.12S period bit

RTPCS EQU 21H ;Real time program counter (100mS part)

FLAGS1 EQU 22H
PROG EQU 22H.0 ;program mode flag
SNUM EQU 22H.1 ;set number flag
BLINK EQU 22H.2 ;display blink bit
SLKPR EQU 22H.3 ;SELECT press flag
OPNPR EQU 22H.4 ;OPEN press flag

;Internal Data Memory:
dseg
ORG 0030H ;data memory segment

ROMD: DS 8 ;touch memory ROM data
TEMP: DS 1 ;temporary byte (used in ACCESS90)

TMATM: DS 1 ;touch memory access timer
AENTM: DS 1 ;TM access enable timer
OPNTM: DS 1 ;open timer
RETTM: DS 1 ;return timer

NUM: DS 1 ;current PRG number (1..9)

;Debugger variables:

#if DEBUG > 0

DBGVA: DS 1
;debugger variable address in internal memory

DBGVV: DS 1 ;debugger variable value in internal memory
DBGA EQU 0FFFFH ;debugger address in external memory
#endif

STACK: ;stack location

; ------ Vectors Area ------
cseg
ORG 0000H ;reset vector
LJMP INIT
ORG 000BH ;INT TIMER 0 vector
LJMP RTC

; ------ Main Program ------

INIT: MOV SP,#STACK ;stack init
#if DEBUG >1
DEBUGINIT ;debug init
#endif

;Variables init:

CLR A
MOV FLAGS1,A ;clear flags 1
MOV TMATM,A ;touch memory access timer clear
MOV AENTM,A ;touch memory access delay timer clear
MOV OPNTM,A ;open timer clear
MOV RETTM,A ;return timer clear

;Periferal setup:

CLR TR0 ;timer 0 stop
CLR TR1 ;timer 1 stop
MOV TMOD,#11H ;timer 0 and timer 1 init
MOV TL0,#LO(RTCV) ;timer 0 load
MOV TH0,#HI(RTCV)
SETB TR0 ;timer 0 start
CLR PT0 ;int. timer 0 low priority
SETB ET0 ;int. timer 0 enable
SETB EA ;interrupts enable

; ------ Main Loop ------

;Read touch memory:

MAIN: LCALL ACCESS90 ;read touch memory
JNC NOTCH ;no touch
JB PROG,PRG ;jump to process PROG mode
LCALL CHKMAS ;check for master code
JC OPN
LCALL CHKMEM ;check for member code
JC OPN
SJMP NOTCH
PRG: LCALL PROGT ;process PROG mode when touch
SJMP NOTCH
OPN: LCALL OPEN ;open door

;Check open key:

NOTCH: LCALL CHKOPK ;check open key
JNC NOOPN
LCALL OPEN ;open door

;Check select key:

NOOPN: LCALL CHKSLK ;check select key
JNC NOSEL
LCALL PROGS ;process PROG mode when select

;Open timer check:

NOSEL: MOV A,OPNTM
JNZ NOCLS
LCALL CLOSE ;solenoid off

;Return timer check:

NOCLS: MOV A,RETTM
JNZ NORET
LCALL RETMD ;return to normal mode

;Display, watchdog wakeup:

NORET: LCALL DISP ;display
LCALL WAKEUP ;watchdog wakeup
LJMP MAIN

; ------ Subroutines Area ------

;Process PROG mode when touch:

PROGT: JB SNUM,PRGT1 ;SNUM = 1 ?
LCALL CHKMAS ;check for master
JC PRGT3
RET

PRGT3: SETB SNUM ;set "set number" flag
CLR BLINK ;clear blink flag
MOV NUM,#1 ;clear number
MOV RETTM,#RETTMV ;load return delay
RET

PRGT1: JB BLINK,PRGT2 ;PROG = 1, BLINK = 0 ?
SETB BLINK ;set blink flag
MOV RETTM,#RETTMV ;load return delay
RET

PRGT2: LCALL SAVE ;NVM[NUM] <- new key
CLR BLINK ;clear blink flag
MOV RETTM,#RETTMV ;load return delay
RET

;Process PROG mode when select:

PROGS: JB PROG,PRGS1 ;PROG = 1 ?
SETB PROG ;set program mode flag
CLR SNUM ;clear "set number" flag
CLR BLINK ;clear blink flag
MOV RETTM,#RETTMV ;load return delay
RET

PRGS1: JNB SNUM,PRGS2 ;SNUM = 0 ?
CLR BLINK ;clear blink flag
INC NUM ;NUM + 1
MOV A,NUM
CJNE A,#MAXK+1,PRGS2
MOV NUM,#1
PRGS2: MOV RETTM,#RETTMV ;load return delay
RET

;Return to normal mode:

RETMD: CLR BLINK ;clear blink flag
CLR PROG ;clear program mode flag
CLR SNUM ;clear "set number" flag
RET

;Open door:

OPEN: CLR SOLEN
MOV OPNTM,#OPNTMV ;load open pulse duration
RET

;Solenoid off:

CLOSE: SETB SOLEN
RET

;Check open key:
;Returns C=1 if pressed

CHKOPK: JNB KEYOP,OP1 ;jump if key OPEN pressed
CLR OPNPR ;clear OPEN pressed flag
OP3: CLR C
RET

OP1: JB OPNPR,OP2
LCALL DEL15 ;delay 15 mS
JB KEYOP,OP3
SETB OPNPR ;set OPEN pressed flag
OP2: SETB C ;C <- 1 if key OPEN pressed
RET

;Check select key:
;Returns C=1 if pressed

CHKSLK: JNB KEYSL,SL1 ;jump if key SELECT pressed
CLR SLKPR ;clear SELECT pressed flag
SL2: CLR C
RET

SL1: JB SLKPR,SL2
LCALL DEL15 ;delay 15 mS
JB KEYSL,SL2
SETB SLKPR ;set SELECT pressed flag
SETB C ;C <- 1 if key SELECT pressed
RET

;Watchdog wakeup:

WAKEUP: MOV C,T040M
MOV WD,C
RET

; ------ 1-Wire bus support ------

;Send reset pulse to OWP and receive presence pulse
;Out: C = 1 if OK

TRESET: PUSH B
CLR OWP ;OWP <- 0
MOV B,#CLK_KHZ/48
DJNZ B,$ ;delay 500 uS
CLR EA ;interrupt disable
SETB OWP ;OWP <- 1 (0uS)

MOV B,#CLK_KHZ/2000
DJNZ B,$ ;delay
MOV C,OWP ;read OWP (14 uS)
JNC FAIL ;fail if OWP = 0

MOV B,#CLK_KHZ/500
DJNZ B,$ ;delay
MOV C,OWP ;read OWP (66 uS)
JC FAIL ;fail if OWP = 1

SETB EA ;interrupts enable
MOV B,#CLK_KHZ/100
DJNZ B,$ ;delay
MOV C,OWP ;read OWP (312 uS or more)
JC RESOK ;OK if OWP = 1

FAIL: CLR C
SETB EA ;interrupts enable (if fail)
RESOK: POP B
RET

;Read/Write byte via 1-Wire bus
;Input: A - input byte
; R4 - CRC
;Out: A - output byte
; R4 - updated CRC

TBYTE: PUSH B
MOV B,#8 ;perform to read 8 bit
TBYTE1: RRC A ;C <- bit
LCALL TBIT ;transmit bit
DJNZ B,TBYTE1 ;next bit
RRC A ;A <- last bit
POP B
RET

;Read/Write bit via 1-Wire bus
;Input: C - input bit.
; R4 - CRC
;Out: C - output bit
; R4 - updated CRC

TBIT: PUSH ACC
CLR EA ;interrupts disable
CLR OWP ;OWP <- 0 (begin of time slot)
NOP ;delay to be sure...
NOP ;that thermometr...
NOP ;looks low level
JC TB_1
SJMP TB_0 ;if data bit = 0 then OWP <- 0
TB_1: SETB OWP ;if data bit = 1 then OWP <- 1
NOP ;delay for data setup
TB_0: NOP
NOP
NOP
NOP
; NOP ;10 MHz !
; NOP
MOV C,OWP ;read port 15 uS later
PUSH B ;save register B
MOV B,#CLK_KHZ/706
DJNZ B,$ ;delay to complete 60 uS slot
POP B ;restore register B
SETB OWP ;OWP <- 1, end of time slot
SETB EA ;interrupts enable

PUSH PSW ;update CRC, save C
RLC A ;ACC.0 <- C
XRL A,R4 ;~ACC.0 if CRC.0 = 1
RRC A ;ACC.0 -> C
MOV A,R4 ;A <- CRC
JNC BCRC0
XRL A,#18H ;update CRC
BCRC0: RRC A ;shift CRC
MOV R4,A ;CRC <- new value
POP PSW ;restore C

POP ACC
RET

; Accesses to DALLAS DS1990A touch memory.
; Returns C=1 in case of valid code, else C=0.
; Out: ROMD (8 bytes)

ACCESS90: CLR C ;indicate failure
MOV A,AENTM ;check access enable timer
JNZ RET90 ;exit if AENTM > 0
MOV AENTM,#AENTMV ;reload access enable timer

LCALL TRESET ;issue reset pulse
JNC RET90 ;leave if no parts on bus

CLR C ;indicate failure
MOV A,TMATM ;check TM access timer
JNZ DIS90 ;exit if TMATM > 0

MOV A,#033H ;read ROM command
LCALL TBYTE ;send command byte

MOV R0,#ROMD ;init pointer
MOV R1,#8 ;init counter
MOV R4,#0 ;initialize CRC variable

RDMORE: MOV A,#0FFH ;prepare to read a byte
LCALL TBYTE ;read byte
MOV @R0,A ;save byte
INC R0 ;next address
DJNZ R1,RDMORE ;repeat until finished

MOV A,R4 ;get CRC value in ACC
JZ CRC_OK ;jump if successful
CLR C ;indicate failure
SJMP RET90

CRC_OK: LCALL CHKZ ;check code for zero
JNC RET90 ;invalid code

DIS90: MOV TMATM,#TMATMV
RET90: RET ;return to caller

;Check TM code for zero:

CHKZ: MOV R0,#ROMD ;init pointer
MOV R1,#8 ;init counter
NEXTZ: MOV A,@R0
ADD A,#0FFH ;C = 1 if A>0
JC OKZ
INC R0 ;next address
DJNZ R1,NEXTZ
OKZ: RET

; I2C NVM memory 24C02 support:
;
; I2C - bus supported subroutines:
;
; I2C_WR - Write byte from A via I2C bus
; I2C_RD - Read byte to A via I2C bus
; I2C_LRD - Read last byte to A via I2C bus (no ASK)
; I2C_SUB - Send subaddress from R1 to I2C device
; I2C_SUBR - Send subaddress from R1 and perform read.
; I2C_STOP - Stop condition generation on I2C bus
;
; I2C slave address I2C_ADDR (0A0H for 24C02 A0,A1,A2=0)
; I2C data line SDA
; I2C clock line SCL

;Send subaddress to I2C device.
;Input: R1 - subaddress.

I2C_SUB: MOV A,#I2C_ADDR ;I2C device address, write mode
LCALL I2C_WR ;send device address
MOV A,R1 ;subaddress
LCALL I2C_WR ;send subaddress
RET

;Send subaddress and perform read.
;Input: R1 - subaddress.

I2C_SUBR: LCALL I2C_SUB ;send subaddress
LCALL I2C_STOP ;stop
MOV A,#I2C_ADDR+1 ;I2C device address, read mode
LCALL I2C_WR ;send device address
RET

;Send byte from A via I2C bus.

I2C_WR: PUSH B
MOV B,#9H ;bit counter load
SETB C ;set C, for bit 9 = 1 (when ACK)
LCALL SDA0 ;SDA 1 -> 0 - start
I2CWR1: LCALL SCL0 ;SCL 1 -> 0
RLC A
JC OUTP1 ;jump if bit = 1
LCALL SDA0 ;else SDA=0
SJMP OUTP0
OUTP1: LCALL SDA1 ;SDA=1, if bit = 1
OUTP0: LCALL SCL1 ;SCL 0 -> 1
DJNZ B,I2CWR1 ;loop
POP B
RET

;Read byte via I2C to A.

I2C_RD: MOV A,#1H ;A init to receive 8 bit
I2CRD1: LCALL SCL0 ;SCL 1 -> 0
LCALL SDA1 ;SDA=1 - SDA line release
LCALL SCL1 ;SCL 0 -> 1
MOV C,SDA ;move bit from SDA line to C
RLC A ;shift bit C into A
JNC I2CRD1 ;loop until C = 1
LCALL SCL0 ;SCL 1 -> 0
LCALL SDA0 ;SDA=0 - ACK generation
LCALL SCL1 ;SCL 0 -> 1
RET

;Read byte via I2C to A without ASK
;(receive last byte).

I2C_LRD: MOV A,#1H ;A init to receive 8 bit
I2CLRD1: LCALL SCL0 ;SCL 1 -> 0
LCALL SDA1 ;SDA=1 - SDA line release
LCALL SCL1 ;SCL 0 -> 1
MOV C,SDA ;move bit from SDA line to C
RLC A ;shift bit C into A
JNC I2CLRD1 ;loop until C = 1
LCALL SCL0 ;SCL 1 -> 0
LCALL SCL1 ;SCL 0 -> 1 when SDA=1: no ACK
RET

;STOP condition generation:

I2C_STOP: LCALL SCL0
LCALL SDA0
LCALL SCL1
LCALL SDA1
RET

;SDA and SCL lines control:

SDA0: CLR SDA ;SDA 1/0
RET
SDA1: SETB SDA ;SDA 0/1
RET
SCL0: CLR SCL ;SCL 1/0
RET
SCL1: SETB SCL ;SCL 0/1
RET

;EEPROM address map:

;00H - page not used
;08H - touch memory code 1
;10H - touch memory code 2
;...

;Save new key:
;NUM - key number (1..9)

SAVE: MOV A,NUM
MOV B,#8
MUL AB ;NUM x 8
MOV R1,A ;R1 <- subaddress
LCALL I2C_SUB ;send subaddress
MOV R1,#8 ;init counter
MOV R0,#ROMD ;init pointer
DOWR: MOV A,@R0
LCALL I2C_WR ;send data
INC R0
DJNZ R1,DOWR
LCALL I2C_STOP ;stop
LCALL DEL15 ;delay 15mS to page write
RET

;Check for member:
;Returns C=1 if code O.K.

CHKMEM: MOV R2,#1 ;init key counter

NEXT: MOV A,R2
MOV B,#8
MUL AB ;NUM x 8
MOV R1,A ;R1 <- subaddress
LCALL I2C_SUBR ;send subaddress and read mode
MOV R1,#8 ;init counter
MOV R0,#ROMD ;init pointer

DORD: LCALL I2C_RD ;read data
XRL A,@R0
JNZ INVAL ;jump if invalid code
INC R0 ;next address
DJNZ R1,DORD
LCALL I2C_LRD ;stop read
LCALL I2C_STOP
SETB C ;valid code, C <- 1
RET

INVAL: LCALL I2C_LRD ;stop read
LCALL I2C_STOP
INC R2 ;next key
MOV A,R2
CJNE A,#MAXK+1,NEXT
CLR C ;invalid code, C <- 0
RET

;Check for master:

CHKMAS: MOV R1,#8 ;init counter
MOV DPTR,#MK ;init pointer to ROM
MOV R0,#ROMD+7 ;init pointer to RAM
DOCM: CLR A
MOVC A,@A+DPTR ;read ROM
XRL A,@R0 ;ROM[DPTR] = RAM[R0] ?
JNZ INVM ;jump if invalid code
INC DPTR ;next ROM address
DEC R0 ;next RAM address
DJNZ R1,DOCM
SETB C ;valid master code, C <- 1
RET

INVM: CLR C ;invalid master code, C <- 0
RET

;Display support:
;Input: NUM = value
;if PROG = 0 display is blanked
;if PROG = 1 and BLINK = 1 display is blinking

DISP: MOV A,#BLANK ;blank display if PROG = 0
JNB PROG,IND
MOV A,#CH_P ;display "P" if SNUM = 0
JNB SNUM,IND
MOV A,NUM ;display NUM if PROG = 1 and SNUM = 1

IND: MOV C,T320M ;load blink period bit
ORL C,/BLINK ;check blink enable bit
JC IND1
MOV A,#BLANK
IND1: MOV DPTR,#FONT ;font table pointer
MOVC A,@A+DPTR ;read font
MOV DDATA,A ;indicator control
RET

;Delay 15mS:

DEL15: PUSH B
PUSH ACC
MOV B,#30
DEL05: MOV A,#CLK_KHZ/48
DJNZ ACC,$
LCALL WAKEUP ;watchdog wakeup
DJNZ B,DEL05
POP ACC
POP B
RET

; ------ Interrupt Holders ------

; TIMER 0 Interrupt
; System clock (20mS)

RTC: PUSH ACC
CLR TR0 ;timer 0 stop
MOV TH0,#HI(RTCV) ;timer 0 load for 20mS
MOV TL0,#LO(RTCV)
SETB TR0 ;timer start

INC RTPC ;advance Real Time Program Counter

; 20mS program counters

RTC1: MOV A,TMATM
JZ RTC2
DEC TMATM

RTC2: MOV A,AENTM
JZ RTC3
DEC AENTM

RTC3: MOV A,OPNTM
JZ RTC4
DEC OPNTM

RTC4: MOV A,RETTM
JZ RTC5
DEC RETTM

RTC5: POP ACC
RETI

; FGABSCDE
FONT: DB 01001000B ;code 00H, character 0
DB 11101011B ;code 01H, character 1
DB 10001100B ;code 02H, character 2
DB 10001001B ;code 03H, character 3
DB 00101011B ;code 04H, character 4
DB 00011001B ;code 05H, character 5
DB 00011000B ;code 06H, character 6
DB 11001011B ;code 07H, character 7
DB 00001000B ;code 08H, character 8
DB 00001001B ;code 09H, character 9
DB 00001010B ;code 0AH, character A
DB 00111000B ;code 0BH, character B
DB 01011100B ;code 0CH, character C
DB 10101000B ;code 0DH, character D
DB 00011100B ;code 0EH, character E
DB 00011110B ;code 0FH, character F
DB 11111111B ;code 10H, character blank
DB 10111111B ;code 11H, character -
DB 00001110B ;code 12H, character P

;Characters codes table:

BLANK EQU 010H ;character "blank" code
CH_MIN EQU 011H ;character "-" code
CH_P EQU 012H ;character "P" code

;Master key code:

MK: DB 062H,000H,000H,002H,0D6H,089H,029H,001H

//#IF (DEBUG>1)
//#INCLUDE "LIBDBG16.ASM"
//#ENDIF
END

Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание

E-mail: info@telesys.ru