⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 红外线通信.txt

📁 pic单片机对红外设备控制得一个源程序
💻 TXT
📖 第 1 页 / 共 3 页
字号:
;Nigel Goodwin 2002

	LIST	p=16F628		;tell assembler what chip we are using
	include "P16F628.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages
	__config 0x3D18			;sets the configuration settings (oscillator type etc.)




		cblock	0x20			;start of general purpose registers
			count			;used in looping routines
			count1			;used in delay routine
			counta			;used in delay routine
			countb			;used in delay routine
			LoX
			Bit_Cntr
			Cmd_Byte
			Dev_Byte
			Flags
			Flags2
			tmp1			;temporary storage
			tmp2
			tmp3
			lastdev
			lastkey

		endc

LED_PORT	Equ	PORTB
LED_TRIS	Equ	TRISB

IR_PORT		Equ	PORTA
IR_TRIS		Equ	TRISA
IR_In		Equ	0x02			;input assignment for IR data

OUT_PORT	Equ	PORTB
LED0		Equ	0x00
LED1		Equ	0x01
LED2		Equ	0x02
LED3		Equ	0x03
LED4		Equ	0x04
LED5		Equ	0x05
LED6		Equ	0x06
LED7		Equ	0x07

EEPROM_Addr	Equ	0x00			;address of EEPROM byte used

ErrFlag		Equ	0x00
StartFlag	Equ	0x01			;flags used for received bit
One		Equ	0x02
Zero		Equ	0x03

New		Equ	0x07			;flag used to show key released

TV_ID		Equ	0x01			;TV device ID

But1		Equ	0x00			;numeric button ID's
But2		Equ	0x01
But3		Equ	0x02
But4		Equ	0x03
But5		Equ	0x04
But6		Equ	0x05
But7		Equ	0x06
But8		Equ	0x07
But9		Equ	0x08

		org	0x0000
		goto	Start

            	org     0x0004
            	retfie

Start		movlw	0x07
		movwf	CMCON			;turn comparators off (make it like a 16F84)

Initialise	clrf	count
		clrf	PORTA
		clrf	PORTB
		clrf	Flags
                clrf    Dev_Byte
		clrf	Cmd_Byte	



SetPorts	bsf 	STATUS,		RP0	;select bank 1
		movlw	0x00			;make all LED pins outputs
		movwf	LED_TRIS
		movlw	b'11111111'		;make all IR port pins inputs
		movwf	IR_TRIS
		bcf 	STATUS,		RP0	;select bank 0

		call	EE_Read			;restore previous settings

Main
		call	ReadIR			;read IR signal
		call	ProcKeys		;do something with commands received

		goto	Main			;loop for ever

ProcKeys
		btfss	Flags2,	New
		retlw	0x00			;return if not new keypress
		movlw	TV_ID			;check for TV ID code
		subwf   Dev_Byte,	w
		btfss   STATUS    , Z
		retlw	0x00			;return if not correct code

		movlw	But1			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key1			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED0		;and test LED bit for toggling
		bsf	LED_PORT,	LED0	;turn on LED
		btfsc	tmp3,	LED0
		bcf	LED_PORT,	LED0	;turn off LED
		bcf	Flags2,	New		;and cancel new flag	
		call	EE_Write		;save the settings	
		retlw	0x00

Key1		movlw	But2			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key2			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED1		;and test LED bit for toggling
		bsf	LED_PORT,	LED1	;turn on LED
		btfsc	tmp3,	LED1
		bcf	LED_PORT,	LED1	;turn off LED
		bcf	Flags2,	New		;and cancel new flag	
		call	EE_Write		;save the settings	
		retlw	0x00

Key2		movlw	But3			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key3			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED2		;and test LED bit for toggling
		bsf	LED_PORT,	LED2	;turn on LED
		btfsc	tmp3,	LED2
		bcf	LED_PORT,	LED2	;turn off LED
		bcf	Flags2,	New		;and cancel new flag
		call	EE_Write		;save the settings		
		retlw	0x00

Key3		movlw	But4			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key4			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED3		;and test LED bit for toggling
		bsf	LED_PORT,	LED3	;turn on LED
		btfsc	tmp3,	LED3
		bcf	LED_PORT,	LED3	;turn off LED
		bcf	Flags2,	New		;and cancel new flag
		call	EE_Write		;save the settings		
		retlw	0x00

Key4		movlw	But5			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key5			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED4		;and test LED bit for toggling
		bsf	LED_PORT,	LED4	;turn on LED
		btfsc	tmp3,	LED4
		bcf	LED_PORT,	LED4	;turn off LED
		bcf	Flags2,	New		;and cancel new flag
		call	EE_Write		;save the settings		
		retlw	0x00

Key5		movlw	But6			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key6			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED5		;and test LED bit for toggling
		bsf	LED_PORT,	LED5	;turn on LED
		btfsc	tmp3,	LED5
		bcf	LED_PORT,	LED5	;turn off LED
		bcf	Flags2,	New		;and cancel new flag
		call	EE_Write		;save the settings		
		retlw	0x00

Key6		movlw	But7			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		goto	Key7			;try next key if not correct code

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED6		;and test LED bit for toggling
		bsf	LED_PORT,	LED6	;turn on LED
		btfsc	tmp3,	LED6
		bcf	LED_PORT,	LED6	;turn off LED
		bcf	Flags2,	New		;and cancel new flag
		call	EE_Write		;save the settings		
		retlw	0x00

Key7		movlw	But8			;test for button 1
		subwf   Cmd_Byte, w
		btfss   STATUS    , Z
		retlw	0X00

		movf	LED_PORT,	w	;read PORTB (for LED status)
		movwf	tmp3			;and store in temp register
		btfss	tmp3,	LED7		;and test LED bit for toggling
		bsf	LED_PORT,	LED7	;turn on LED
		btfsc	tmp3,	LED7
		bcf	LED_PORT,	LED7	;turn off LED
		bcf	Flags2,	New		;and cancel new flag
		call	EE_Write		;save the settings		
		retlw	0x00

EE_Read		bsf 	STATUS,	RP0 		; Bank 1
		movlw 	EEPROM_Addr
		movwf 	EEADR			; Address to read
		bsf 	EECON1,	RD 		; EE Read
		movf 	EEDATA,	W 		; W = EEDATA
		bcf 	STATUS,	RP0 		; Bank 0
		movwf	LED_PORT		; restore previous value
		retlw	0x00

EE_Write	movf	LED_PORT,	w	; read current value
		bsf 	STATUS,	RP0 		; Bank 1
		bsf	EECON1,	WREN 		; Enable write
		movwf	EEDATA			; set EEPROM data
		movlw	EEPROM_Addr
		movwf	EEADR			; set EEPROM address
		movlw	0x55
		movwf	EECON2 			; Write 55h
		movlw	0xAA
		movwf	EECON2 			; Write AAh
		bsf	EECON1,	WR 		; Set WR bit
						; begin write
		bcf 	STATUS,	RP0 		; Bank 0
		
		btfss	PIR1,	EEIF		; wait for write to complete.
		goto	$-1
		bcf	PIR1,	EEIF		; and clear the 'write complete' flag
		bsf 	STATUS,	RP0 		; Bank 1
		bcf	EECON1,	WREN 		; Disable write
		bcf 	STATUS,	RP0 		; Bank 0
		retlw	0x00



;IR routines

ReadIR		call	Read_Pulse
		btfss	Flags,	StartFlag
		goto	ReadIR			;wait for start pulse (2.4mS)

Get_Data	movlw   0x07			;set up to read 7 bits
                movwf   Bit_Cntr
                clrf    Cmd_Byte
Next_RcvBit2    call	Read_Pulse
		btfsc	Flags,	StartFlag	;abort if another Start bit
		goto	ReadIR
		btfsc	Flags,	ErrFlag		;abort if error
		goto	ReadIR

                bcf     STATUS    , C
                btfss   Flags, 	Zero
                bsf     STATUS    , C
                rrf     Cmd_Byte  , f
                decfsz  Bit_Cntr  , f
                goto    Next_RcvBit2

                rrf     Cmd_Byte  , f		;correct bit alignment for 7 bits

Get_Cmd		movlw   0x05			;set up to read 5 bits
                movwf   Bit_Cntr
                clrf    Dev_Byte
Next_RcvBit     call	Read_Pulse
		btfsc	Flags,	StartFlag	;abort if another Start bit
		goto	ReadIR
		btfsc	Flags,	ErrFlag		;abort if error
		goto	ReadIR

                bcf     STATUS    , C
                btfss   Flags, 	Zero
                bsf     STATUS    , C
                rrf     Dev_Byte  , f
                decfsz  Bit_Cntr  , f
                goto    Next_RcvBit

                rrf     Dev_Byte  , f		;correct bit alignment for 5 bits
                rrf     Dev_Byte  , f		
                rrf     Dev_Byte  , f		

		retlw	0x00

;end of ReadIR


;read pulse width, return flag for StartFlag, One, Zero, or ErrFlag
;output from IR receiver is normally high, and goes low when signal received

Read_Pulse      clrf	LoX
		btfss   IR_PORT, 	IR_In	;wait until high
            	goto    $-1
		clrf	tmp1
		movlw	0xC0			;delay to decide new keypress
		movwf	tmp2			;for keys that need to toggle

Still_High	btfss   IR_PORT, 	IR_In	;and wait until goes low
            	goto    Next
		incfsz	tmp1,f
		goto	Still_High
		incfsz	tmp2,f
		goto	Still_High
		bsf	Flags2,	New		;set New flag if no button pressed
		goto	Still_High

Next		nop
		nop
		nop
		nop
		nop				;waste time to scale pulse
		nop				;width to 8 bits
		nop
		nop
		nop
		nop
		nop
		nop
		incf	LoX,	f
        	btfss   IR_PORT, 	IR_In
        	goto    Next			;loop until input high again

; test if Zero, One, or Start (or error)
		
Chk_Pulse	clrf	Flags

TryError	movf 	LoX,	w		; check if pulse too small
  		addlw 	d'255' - d'20'		; if LoX <= 20
  		btfsc   STATUS    , C
  		goto 	TryZero
		bsf	Flags,	ErrFlag		; Error found, set flag
		retlw	0x00

TryZero		movf 	LoX,	w		; check if zero
  		addlw 	d'255' - d'60'		; if LoX <= 60
  		btfsc   STATUS    , C
  		goto 	TryOne
		bsf	Flags,	Zero		; Zero found, set flag
		retlw	0x00

TryOne 		movf 	LoX,	w		; check if one
  		addlw 	d'255' - d'112'		; if LoX <= 112
  		btfsc   STATUS    , C
  		goto 	TryStart
		bsf	Flags,	One		; One found, set flag
		retlw	0x00

TryStart 	movf 	LoX,	w		; check if start
  		addlw 	d'255' - d'180'		; if LoX <= 180
  		btfsc   STATUS    , C
  		goto 	NoMatch
		bsf	Flags,	StartFlag	; Start pulse found
		retlw	0x00
NoMatch						; pulse too long
		bsf	Flags,	ErrFlag		; Error found, set flag		
		retlw	0x00

;end of pulse measuring routines



;Delay routines

Delay255	movlw	0xff		;delay 255 mS
		goto	d0
Delay100	movlw	d'100'		;delay 100mS
		goto	d0
Delay50		movlw	d'50'		;delay 50mS
		goto	d0
Delay20		movlw	d'20'		;delay 20mS
		goto	d0
Delay5		movlw	0x05		;delay 5.000 ms (4 MHz clock)
d0		movwf	count1
d1		movlw	0xC7
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00

;end of Delay routines


		end      
      
The EEPROM data is accessed by two new routines, EE_Read and EE_Write, the EE_Read routine is called as the program powers up, before we enter the main loop, and the EE_Write routine is called after every LED change. The EE_Read routine is very straightforward, we simply set the address we wish to read in the EEADR register, set the RD flag in the EECON1 register, and then read the data from the EEDATA register. Writing is somewhat more complicated, for a couple of reasons:

Microchip have taken great care to prevent accidental or spurious writes to the data EEPROM. In order to write to it we first have to set the 'Write Enable' bit in the EECON1 register, and then make two specific writes (0x55 and 0xAA) to the EECON2 register, only then can we set the WR bit in EECON1 and start the actual writing. One of the most common problems in domestic electronics today is data EEPROM corruption, hopefully the efforts of Microchip will prevent similar problems with the 16F628. 
Writing to EEPROM takes time, so we have to wait until the 'Write Complete' flag is set, it doesn't really matter in this application as the time spent waiting for the next IR command gives more than enough time to write to the data EEPROM, but it's good practice to do it anyway. 
The extra work involved makes the EE_Write routine a lot longer than the EE_Read routine, it also doesn't help that we need to access registers in different banks, so we do a fair bit of bank switching.

--------------------------------------------------------------------------------
 
http://www.winpicprog.co.uk/pic_tutorial5.htm

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -