📄 红外线通信.txt
字号:
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_Line1 movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
retlw 0x00
LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
call LCD_Cmd
retlw 0x00
LCD_Line1W addlw 0x80 ;move to 1st row, column W
call LCD_Cmd
retlw 0x00
LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
call LCD_Cmd
retlw 0x00
LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_Clr movlw 0x01 ;Clear display
call LCD_Cmd
retlw 0x00
LCD_HEX movwf tmp1
swapf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
movf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
retlw 0x00
Pulse_e bsf LCD_PORT, LCD_E
nop
bcf LCD_PORT, LCD_E
retlw 0x00
LCD_Busy
bsf STATUS, RP0 ;set bank 1
movlw 0x0f ;set Port for input
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
bcf LCD_PORT, LCD_RS ;set LCD for command mode
bsf LCD_PORT, LCD_RW ;setup to read busy flag
bsf LCD_PORT, LCD_E
swapf LCD_PORT, w ;read upper nibble (busy flag)
bcf LCD_PORT, LCD_E
movwf templcd2
bsf LCD_PORT, LCD_E ;dummy read of lower nibble
bcf LCD_PORT, LCD_E
btfsc templcd2, 7 ;check busy flag, high = busy
goto LCD_Busy ;if busy check again
bcf LCD_PORT, LCD_RW
bsf STATUS, RP0 ;set bank 1
movlw 0x00 ;set Port for output
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
return
;end of LCD 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
;This routine downloaded from http://www.piclist.com
Convert: ; Takes number in NumH:NumL
; Returns decimal in
; TenK:Thou:Hund:Tens:Ones
swapf NumH, w
iorlw B'11110000'
movwf Thou
addwf Thou,f
addlw 0XE2
movwf Hund
addlw 0X32
movwf Ones
movf NumH,w
andlw 0X0F
addwf Hund,f
addwf Hund,f
addwf Ones,f
addlw 0XE9
movwf Tens
addwf Tens,f
addwf Tens,f
swapf NumL,w
andlw 0X0F
addwf Tens,f
addwf Ones,f
rlf Tens,f
rlf Ones,f
comf Ones,f
rlf Ones,f
movf NumL,w
andlw 0X0F
addwf Ones,f
rlf Thou,f
movlw 0X07
movwf TenK
; At this point, the original number is
; equal to
; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
; if those entities are regarded as two's
; complement binary. To be precise, all of
; them are negative except TenK. Now the number
; needs to be normalized, but this can all be
; done with simple byte arithmetic.
movlw 0X0A ; Ten
Lb1:
addwf Ones,f
decf Tens,f
btfss 3,0
goto Lb1
Lb2:
addwf Tens,f
decf Hund,f
btfss 3,0
goto Lb2
Lb3:
addwf Hund,f
decf Thou,f
btfss 3,0
goto Lb3
Lb4:
addwf Thou,f
decf TenK,f
btfss 3,0
goto Lb4
retlw 0x00
end
Tutorial 5.2 - requires one Main Board, one IR Board and Switch Board.
This program implements a Sony SIRC IR transmitter, pressing one of the four buttons sends the corresponding code, you can alter the codes as you wish, for this example I chose Volume Up and Down, and Program Up and Down. In order to use this with the LED switching above, I would suggest setting the buttons to transmit '1', '2', '3' and '4', where '4' should have no effect on the LED - the codes are 0x00, 0x01, 0x02, 0x03 respectively (just to confuse us, the number keys start from zero, not from one).
;Tutorial 5.2 - Nigel Goodwin 2002
;Sony SIRC IR transmitter
LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
__config 0x3D18 ;sets the configuration settings (oscillator type etc.)
cblock 0x20 ;start of general purpose registers
count1 ;used in delay routine
counta ;used in delay routine
countb
count
Delay_Count
Bit_Cntr
Data_Byte
Dev_Byte
Rcv_Byte
Pulse
endc
IR_PORT Equ PORTB
IR_TRIS Equ TRISB
IR_Out Equ 0x01
IR_In Equ 0x02
Ser_Out Equ 0x01
Ser_In Equ 0x02
SW1 Equ 7 ;set constants for the switches
SW2 Equ 6
SW3 Equ 5
SW4 Equ 4
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
ProgUp Equ d'16'
ProgDn Equ d'17'
VolUp Equ d'18'
VolDn Equ d'19'
org 0x0000 ;org sets the origin, 0x0000 for the 16F628,
goto Start ;this is where the program starts running
org 0x005
Start movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
clrf IR_PORT ;make PortB outputs low
bsf STATUS, RP0 ;select bank 1
movlw b'11111101' ;set PortB all inputs, except RB1
movwf IR_TRIS
movlw 0xff
movwf PORTA
bcf STATUS, RP0 ;select bank 0
Read_Sw
btfss PORTA, SW1
call Switch1
btfss PORTA, SW2
call Switch2
btfss PORTA, SW3
call Switch3
btfss PORTA, SW4
call Switch4
call Delay27
goto Read_Sw
Switch1 movlw ProgUp
call Xmit_RS232
retlw 0x00
Switch2 movlw ProgDn
call Xmit_RS232
retlw 0x00
Switch3 movlw VolUp
call Xmit_RS232
retlw 0x00
Switch4 movlw VolDn
call Xmit_RS232
retlw 0x00
TX_Start movlw d'92'
call IR_pulse
movlw d'23'
call NO_pulse
retlw 0x00
TX_One movlw d'46'
call IR_pulse
movlw d'23'
call NO_pulse
retlw 0x00
TX_Zero movlw d'23'
call IR_pulse
movlw d'23'
call NO_pulse
retlw 0x00
IR_pulse
MOVWF count ; Pulses the IR led at 38KHz
irloop BSF IR_PORT, IR_Out
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
BCF IR_PORT, IR_Out
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP
NOP
NOP ;
NOP ;
DECFSZ count,F
GOTO irloop
RETLW 0
NO_pulse
MOVWF count ; Doesn't pulse the IR led
irloop2 BCF IR_PORT, IR_Out
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
BCF IR_PORT, IR_Out
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP ;
NOP
NOP
NOP ;
NOP ;
DECFSZ count,F
GOTO irloop2
RETLW 0
Xmit_RS232 MOVWF Data_Byte ;move W to Data_Byte
MOVLW 0x07 ;set 7 DATA bits out
MOVWF Bit_Cntr
call TX_Start ;send start bit
Ser_Loop RRF Data_Byte , f ;send one bit
BTFSC STATUS , C
call TX_One
BTFSS STATUS , C
call TX_Zero
DECFSZ Bit_Cntr , f ;test if all done
GOTO Ser_Loop
;now send device data
movlw D'1'
movwf Dev_Byte ;set device to TV
MOVLW 0x05 ;set 5 device bits out
MOVWF Bit_Cntr
Ser_Loop2 RRF Dev_Byte , f ;send one bit
BTFSC STATUS , C
call TX_One
BTFSS STATUS , C
call TX_Zero
DECFSZ Bit_Cntr , f ;test if all done
GOTO Ser_Loop2
retlw 0x00
;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
Delay27 movlw d'27' ;delay 27mS
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
Tutorial 5.3 - requires one Main Board, one IR Board and LED Board.
This program implements toggling the 8 LED's on the LED board with the buttons 1 to 8 on a Sony TV remote control, you can easily change the device ID and keys used for the LED's. I've also used a (so far unused) feature of the 16F628, the EEPROM data memory - by using this the program remembers the previous settings when unplugged - when you reconnect the power it restores the last settings by reading them from the internal non-volatile memory. The 16F628 provides 128 bytes of this memory, we only use one here (address 0x00, set in the EEPROM_Addr constant).
;Tutorial 5_3
;Read SIRC IR and toggle LED display, save settings in EEPROM data memory.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -