Dipl.-Ing. Detlef Rohde Dept. BM (Broadband Mobile Radio Networks) Group: OMW (Optical Microwave Generation) Heinrich-Hertz-Institut Berlin GmbH Einsteinufer 37 D-10587 Berlin Germany Phone: (49) 30 31002-444 Fax: (49) 30 31002-213 e-mail: rohde@hhi.de A.R.S.: DL7IY says: I have just had success in porting a program which I found in Scott Edwards booklet of Assembler routines for the PIC to the SX28. All what you have to do is to adjust carefully the delay settings for your baud rate. I use the 50 MHz resonator and checked the usage for 9600 Baud. Regards -- ; SERIN_2 bytes, filter (Fixed port, pin, baud rate, and polarity) ; Receives data serially. Stores the data as a counted string starting at ; buffer-1 (buffer is the number of bytes in the string). An optional filter ; causes the routine to ignore data outside a range of ASCII character ; values set by filt_lo and filt_hi. ; This routine differs from the Serin presented in the text in that you ; must set the baud rate and input pin through the equates below. They ; cannot be changed once the program is assembled. (The larger version ; can change pins, baud rate, and data polarity on the fly.) Removing ; the code necessary for runtime changes saves about 30 instruction ; words of space. If you only need to receive single bytes at a time, ; and don't require the buffering and filtering capabilities of this ; routine, check out SERIN_3 on this disk. ; To set the baud rate, just remove the comment symbol (;) in front of ; the desired baud rate in the list below. Make sure that all of the ; other "baud" definitions begin with (;) so that the assembler will ; ignore them. ; Note that the baud rates are all calculated at 4 MHz. At other clock ; rates, they will be proportional. For example, at 8 MHz, the fastest ; baud rate will be 4800. At 1 MHz, the fastest will be 600. ; To change the input pin, just change the line "sin_pin = " to the ; desired pin. Make sure that the pin is set up as an input before ; calling serin. ; To change the signalling polarity expected by serin, you must make ; three changes in the body of the program. There are comments next to ; the appropriate lines. Use comment symbols (;) to deactivate the ; version you don't want, and remove comment symbols from in front of ; the desired lines. The routine is currently set up for "inverted" ; polarity, meaning that it will receive input directly from a PC ; serial port with just a 22k resistor between the PC's data output ; and the PIC's sin_pin. Connect the PC signal ground to the PIC ; circuit ground. baud = 31 ; Bit delay for 2400 baud (4-MHz PIC clock). ; baud = 63 ; Bit delay for 1200 baud (4-MHz PIC clock). ; baud = 127 ; Bit delay for 600 baud (4-MHz PIC clock). ; baud = 255 ; Bit delay for 300 baud (4-MHz PIC clock). sin_pin = ra.2 ; Serial input pin. buffer = 31 ; String storage. filt_lo = '0' ; Set filter for ASCII filt_hi = '9' ; chars representing 0-9. org 8 bytes ds 1 ; Number of bytes to receive. temp1 ds 1 ; Temporary counter for Serin. temp2 ds 1 ; Temporary counter for Serin. temp3 ds 1 ; Temporary counter for delay. ser_fl ds 1 ; Flags for serin switches. filter = ser_fl.1 ; Range filter: 0=off, 1=on. filt_1st = ser_fl.2 ; 1st filter byte passed?: 0=no, 1=yes. aux = ser_fl.3 ; Temporary flag for filter comparisons. ; Device data and reset vector device pic16c55,xt_osc,wdt_off,protect_off reset start org 0 ; Subroutine used by Serin to get a bit and delay for a number of loops ; set by temp3. Jumping into get_bit:loop provides the delay, but ignores the ; input bit. get_bit movb c,/sin_pin ; > Uncomment this line for "inverted" polarity. ;get_bit movb c,sin_pin ; > Uncomment this line for "true" polarity. rr indirect ; Rotate carry into msb of data byte. :loop jmp $+1 ; Two-cycle nops. jmp $+1 jmp $+1 jmp $+1 jmp $+1 djnz temp3,:loop ret ; Main program start. Receives a single byte of data, unfiltered, ; and displays the data bits on LEDs connected to port RB. Repeats ; endlessly. start clr ser_fl ; Clear flag byte. mov !ra, #15 ; All inputs. mov !rb,#0 ; All outputs for LEDs. mov bytes,#1 ; Receive 1 byte clrb filter ; not filtered. call Serin ; Receive the data. mov rb,buffer-1 ; Move byte to LEDs on RB. jmp start ; Do it again. ; Body of the Serin routine. Expects the number of bytes to receive in bytes ; and the flag settings in ser_fl. Serin clr buffer ; Clear buffer counter. clrb filt_1st ; Initialize filter flag. mov fsr,#buffer-1 ; Point to first data address. :poll jnb sin_pin,:poll ; > Uncomment this line for "inverted" polarity. ;:poll jb sin_pin,:poll ; > Uncomment this line for "true" polarity. clc mov temp3,#baud/2 ; Set up 1/2 bit time delay. call get_bit:loop ; Jump into delay of get_bit. jnb sin_pin,:poll ; > Uncomment this line for "inverted" polarity. ; jb sin_pin,:poll ; > Uncomment this line for "true" polarity. jnb sin_pin,:poll ; Change to "jb sin_pin,:poll" for "true" polarity. mov temp3,#baud ; Set up full bit time delay. call get_bit:loop ; Jump into delay of get_bit. mov temp2,#8 ; Eight data bits. :rcv mov temp3,#baud ; Set up bit delay. call get_bit ; Get the next data bit. djnz temp2,:rcv ; Eight bits received? :done mov temp3,#baud ; Set up bit delay. call get_bit:loop ; Wait for stop bit. jnb filter,:skip ; IF filter=0 (off) THEN :skip clrb aux ; LET aux = 0. csae indirect,#filt_lo ; IF byte < filt_lo THEN aux=1 setb aux csbe indirect,#filt_hi ; IF byte > filt_hi THEN aux=1 setb aux jnb aux,:skip ; If aux = 0 (byte is within snb filt_1st ; filter range) :skip. If byte is ret ; out of range, but valid bytes have jmp :poll ; been received, return. Else poll. :skip setb filt_1st dec fsr ; Decrement buffer pointer. inc buffer ; Increment buffer counter. djnz bytes,:poll ; More bytes to receive: poll. ret