;********************************************************************** ; Filename: irsend.asm * ; Date: 2002-02-22 * ; File Version: 1.0 * ; * ; Author: Per Zander * ;********************************************************************** ; Files required: p12c508a.inc * ;********************************************************************** ; ; Description: ; ; IR transmitter program for a model train recognition system. ; The transmitter sends an 8-bit code on GP0, and the same code, ; but with inverted bit 7, on GP1. ; ; Each data sequence consists of one parity bit, followed by the ; eight data bits, least significant bit first. The parity is such ; that there is an odd number of '1's, including the parity bit ; itself. ; ; The data is sent as 'LED off' pulses, which corresponds to high ; outputs on GP0 and GP1. A '0' or a '1' is coded by the length ; of the pulses, where a '0' is 38 instruction cycles and a '1' is ; 102 instruction cycles. The 'LED on' time between the data bits ; are 38 instruction cycles, and the 'LED on' pause between two ; consecutive data sequences is between 178 and 306 instruction cycles, ; depending on the value of bit 7 and the parity bit. ; ; The processor runs from its internal RC oscillator, which gives a ; nominal instruction length of 1 microsecond. ; ;********************************************************************** ;*---------- Device address, change for each unit. ----------* my_addr EQU 0x0a ; Decimal 10. ;*---------- Device select. ----------* list p=12c508a ; List directive to define processor #include ; Processor specific variable definitions ;*---------- Configuration specification. ----------* __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_ON & _IntRC_OSC ;*---------- Variable definitions. ----------* addr EQU 0x08 ; My address. loopc EQU 0x09 ; Counter variable in the wait loop. parity EQU 0x0a ; Parity bit (bit 0 in register). ;********************************************************************** ;* The program starts here after reset. ;********************************************************************** ;*---------- Skip Osc. cal. value if not UV erasable. ----------* ; ORG 0x3FF ; Processor reset vector. ; movlw 0x38 ; Osc. cal. value. ;*---------- Real start of program. ----------* ORG 0x000 ; Coding begins here. startofprog movwf OSCCAL ; Update register with factory cal value. goto init_code ; Jump over a few words to enable ; reprogramming. ORG 0x008 ;********************************************** ;*---------- Delay loop subroutine. ----------* ;********************************************** ;---------- Delays 4(W + 1) clock cycles. ----------* wait_sub movwf loopc wait_loop nop decfsz loopc, F goto wait_loop retlw 0xff ;************************************ ;*---------- Get address. ----------* ;************************************ ;---------- This allows for many address changes. ----------* ;---------- Replace the current 'movlw my_addr' ----------* ;---------- with 'nop', and replace the last ----------* ;---------- 'xorlw 0xff' with a 'movlw' with the ----------* ;---------- new address. ----------* ORG 0x80 get_addr xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff xorlw 0xff movlw my_addr goto got_addr ;****************************************** ;*---------- Main program loop. ----------* ;****************************************** start_bit ;---------- Start bit. ----------* clrf GPIO ; Turn on LED. ; t0 goto get_addr ; t1-t133 got_addr movwf addr movwf parity ; Parity calculation rrf parity, F addwf parity, W rrf parity, F addwf parity, W rrf parity, F addwf parity, W rrf parity, F addwf parity, W rrf parity, F addwf parity, W rrf parity, F addwf parity, W rrf parity, F addwf parity, F ; Bit 0 contains inverse of send parity. movlw 0x5 ; t150 call wait_sub ; t151-t174 ; line 38 ;---------- Parity bit. ----------* parity_bit movlw 2 btfsc parity, 0 movlw 1 ; t177 parity1 movwf GPIO ; Turn off LED. ; t0 movlw 0x0e call wait_sub nop movlw 0xff parity2 movwf GPIO ; Both led off movlw 0x08 call wait_sub clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 0. ----------* bit0 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 0 ; Test bit 0. goto d0 movlw 0x17 ; Value in case of sending a '1'. d0 nop ; t5 call wait_sub ; t6-t37 or t6-t101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 1. ----------* bit1 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 1 ; Test bit 1. goto d1 movlw 0x17 ; Value in case of sending a '1'. d1 nop ; t5 call wait_sub ; t6-t37 or t6-t101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 2. ----------* bit2 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 2 ; Test bit 2. goto d2 movlw 0x17 ; Value in case of sending a '1'. d2 nop ; t5 call wait_sub ; t6-t37 or t6-101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 3. ----------* bit3 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 3 ; Test bit 3. goto d3 movlw 0x17 ; Value in case of sending a '1'. d3 nop ; t5 call wait_sub ; t6-t37 or t6-t101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 4. ----------* bit4 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 4 ; Test bit 4. goto d4 movlw 0x17 ; Value in case of sending a '1'. d4 nop ; t5 call wait_sub ; t6-t37 or t6-t101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 5. ----------* bit5 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 5 ; Test bit 5. goto d5 movlw 0x17 ; Value in case of sending a '1'. d5 nop ; t5 call wait_sub ; t6-t37 or t6-t101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 6. ----------* bit6 movwf GPIO ; Turn off LED. movlw 0x07 ; Value in case of sending a '0'. btfss addr, 6 ; Test bit 6. goto d6 movlw 0x17 ; Value in case of sending a '1'. d6 nop ; t5 call wait_sub ; t6-t37 or t6-t101 clrf GPIO ; Turn on LED. ; t0 movlw 0x08 ; t1 call wait_sub ; t2-t37 ;---------- Bit 7. ----------* bit7 movwf GPIO ; Turn off LED. movlw 0xfc tris GPIO ; Set output port GP1 and GP0 to out. movlw 0x06 call wait_sub nop movlw 2 btfss addr, 7 movlw 1 goto last_bit last_bit movwf GPIO movlw 0x0e call wait_sub ; t8-t35 or t8-t99 goto start_bit ; t36-t37 or t100-t101 ;***************************************** ;*---------- Initial settings. ----------* ;***************************************** init_code movlw 0xc7 ; Internal timer clock, max prescaler. option movlw 0xff movwf GPIO ; Set output port, i.e. LED off. movlw 0xfc ; Set output port GP1 and GP0 to out. tris GPIO goto start_bit endofprog END ; directive 'end of program'