;******************************************************************* ; Sends ASCII codes out every time it gets a character in, puts ; character it got on PORT B - tests these routines ; ; This code is improved from the 'example' code because we sense ; the bit's state in the middle of a bit time. When I orignally ; used this code, it would miss bits, because of timing shifts ; between the sending computer and the pic. When using higher ; baud rates, you should use NOP's to get to the center. ;******************************************************************* ; LIST p=16C84 ; PIC16C84 is the target processor include "P16c84.inc" clkrate equ .4000000 ; 4 Mhz clock rate bdrate equ .2400 ; 2400 baud fclk equ clkrate/4 ; baudfig equ ((fclk/bdrate)/3-2) ;must be a 8 bit value baud2 equ baudfig/2 ;half bit time ra equ 5 ; I/O port A rb equ 6 ; I/O port B count equ 0x10 ; temp count txreg equ 0x11 ; temp tx register deltmp equ 0x12 ; delay temp storage switchc equ 0x15 ; used as temp storage #define tx PORTA,1 ; the bit for serial tx #define rx PORTA,4 ; the bit for serial rx ; ; ;******************************************************************** ; Test Program ;********************************************************************* reset ;everything starts at 0 start movlw B'11000101' ;whatever option movlw B'00000000' ;RB0-7 0=outputs tris rb ; set them movlw B'00010000' ;RA4 is 1=input tris ra ; set them movlw 0 sss movlw 0x2F movwf switchc main incf switchc ;ASCII code go up the list btfsc switchc,7 ;we print the ASCII code up to end goto sss movf switchc,w call sendtx ;send the character call getrx ;rx will wait till you send something movwf PORTB ;put it out on port B for checking goto main sendtx movwf txreg ;store our data byte was in w bcf tx ;tx = LOW, start bit here movlw baudfig ;set up our delay movwf deltmp movlw .9 ;set up bit counter movwf count txwait decfsz deltmp goto txwait ;wait for bit time to end movlw baudfig ;set up bit delay again movwf deltmp decfsz count ;see if we are done yet goto nextbit bsf tx ;tx = HIGH - 2 stop bits txwait1 decfsz deltmp goto txwait1 ;wait for bit time to end movlw baudfig ;set up bit delay again movwf deltmp txwait2 decfsz deltmp goto txwait2 ;wait for bit time to end return nextbit rrf txreg ;shift it >>>> to c btfss STATUS,C ;skip if c = HIGH goto setlo bsf tx ;tx = HIGH goto txwait setlo bcf tx ;tx = LOW goto txwait getrx movlw baud2 ;set up HALF bit delay movwf deltmp movlw .9 ;set up bit counter movwf count getrxl btfsc rx ;watch for LOW on rx line, start bit goto getrxl halfbt decfsz deltmp ;move out 1/2 bit time goto halfbt movlw baudfig ;set up full bit delay movwf deltmp rxwait decfsz deltmp ;lets wait for this bit to pass by goto rxwait movlw baudfig ;set up bit delay again movwf deltmp decfsz count ;are all bits in yet? goto rxgo movf txreg,w ;put result into w return ;we don't wait for stop bits, no reason to rxgo bcf STATUS,C ;clear the carry bit always btfsc rx ;skip if rx is LOW bsf STATUS,C ;set the carry if rx was HIGH rrf txreg ;shift C >>>> into our holding reg goto rxwait ;go do the next bit ;we sense the bit's state in the ;middle of a bit time. That's why ;we did the half bit time delay. END