| #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuo #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh 用TMR0實現(xiàn)定時查詢。任何帶中斷的PIC上都可以實現(xiàn)?捎么朔〝U展多個串口。 #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;|--------------------------------------------------------------| ;| Implement duplex USART base on normal I/O pin | ;| Using TIMER0 interrupt for bit timing | ;| Tested on PIC16F83 running at 4MHz | ;| Written by Paul Zhang, Microchip Tech Inc | ;| 6 Aug, 2000 | ;| All rights reserved | ;|--------------------------------------------------------------| #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh errorlevel -302 ;no bank warning errorlevel -301 ;no default file warning list p=16F83 ;define processor #include <p16F83.inc> ; #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;code protect = OFF ;watchdog = OFF ;power-up delay timer = ON ;oscillator mode = XT #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;=============================== ;define RAM variables cblock 0x0c ;GPR start from 0x0c w_temp ;W context saving during interrupt status_temp ;STATUS context saving during interrupt pclath_temp ;PCLATH context saving during interrupt #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDhUSART_F ;containing flags for USART RX_BUFF ;USART received data buffer TX_BUFF ;USART transmitting data buffer RX_SLICE ;RX bit-timing control TX_SLICE ;TX bit-timing control RX_bcnt ;RX received bit counting TX_bcnt ;TX transmitting bit counting RX_STA ;RX STATE-MACHINE controller TX_STA ;TX STATE-MACHINE controller endc #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;=============================== ;pre-definition for readability #define RX_PIN PORTA,2 ;assign RX pin #define TX_PIN PORTA,3 ;assign TX pin #define TXEN USART_F,0 ;USART transmit enable #define TXBUSY USART_F,1 ;USRAT transmit is in progress #define RXBF USART_F,2 ;USART receive buff full #define RXBUSY USART_F,3 ;USART receive is in progress #define RX_ERR USART_F,4 ;USART receive error #define TX_ERR USART_F,5 ;USART transmit error #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;=============================== ;define constant #define OSC_FREQ .4000 ;oscillator frequency in KHz #define BAUDRATE .2400 #define TMR0CONST .118 ;256-OSC_FREQ*1000/4/(BAUDRATE*3) + 2 #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;=============================== ;for my personal style #define skp0 btfsc #define skp1 btfss #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;********************************************************************** ORG 0x000 clrwdt goto MAIN ; go to beginning of program #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh ;======================================= ;Interrupt service routine ORG 0x004 ; interrupt vector location #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh MOVwf w_temp ; save off current W register contents MOVf STATUS,w ; move status register into W register banksel status_temp MOVwf status_temp ; save off contents of STATUS register MOVf PCLATH,w MOVwf pclath_temp ; save off contents of PCLATH #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh banksel INTCON ;select bank skp0 INTCON,T0IF ;test for TMR0 interrupt goto tmr0IntStart ;do TMR0 ISR ;here test for any other interrupt source goto int_end #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDhtmr0IntStart ;TIMER0 interrupt service bcf INTCON,T0IF ;clear T0IF ;====== start of RX ======= MOVlw high($) MOVwf PCLATH ;set PCLATH before PCL change MOVf RX_STA,w ;get the state value for RX andlw 0x03 ;for safeguard purpose addwf PCL,f ;switch to STATE goto rxStartChk ;check for START bit goto rxReceiveBit ;receive DATA bit goto rxIdle ;wait for idle goto rxEnd ;do nothing rxStartChk ;check for START bit skp0 RX_PIN ;test RX pin for START bit goto rxEnd ;not found ;start bit found. do following MOVlw .8 MOVwf RX_bcnt ;count for 8 bits incoming data MOVlw .4 MOVwf RX_SLICE ;wait 4 time-slice for 1st data bit MOVlw .1 MOVwf RX_STA ;switch to STATE 1 for 1st data bit sampling goto rxEnd rxReceiveBit ;receive DATA bit decfsz RX_SLICE,f ;wait of bit timing goto rxEnd ;time to sample incoming data bit rrf RX_BUFF,f ;right shift for new bit space bcf RX_BUFF,7 ;pre-set to 0 skp0 RX_PIN ;incoming data bit test bsf RX_BUFF,7 ;set if data bit = 1 MOVlw .3 ;3 slice for data bit timing MOVwf RX_SLICE ;bit timing for next data bit decfsz RX_bcnt,f ;see if 8-bit completed goto rxEnd ;bit receive completed, do follwoing MOVlw .2 MOVwf RX_STA ;set to STATE 2 for idle waiting bsf RXBF ;set receive buffer full MOVf RX_BUFF,w ;display data on PORTB MOVwf PORTB goto rxEnd rxIdle ;wait for idle skp0 RX_PIN ;try to find STOP bit clrf RX_STA ;back to STATE 0 for next byte goto rxEnd ;====== End of RX ========= rxEnd ;====== start of TX ======= ;do TX, if transmit is engaged skp1 TXEN ;skip if TXEN set, do TX goto tmr0IntEnd ;not in transmit mode MOVf TX_SLICE,f ;see if in bit-timing delay skpnz ; goto txDo ;bit-timing completed decfsz TX_SLICE,f ;keep bit-timing delay goto txEnd txDo ;Transmit STATE-MACHINE control MOVlw high($) MOVwf PCLATH ;set PCLATH before PCL change MOVf TX_STA,w ;get current state andlw 0x03 ;make sure in range addwf PCL,f ;switch to TX STATE goto txStartBit ;send START bit goto txDatBit ;send DATA bit goto txStop ;send STOP bit goto txIdle ;set transtim IDLE txStartBit ;TX_STA=0, send START bit here bsf TXBUSY ;set TX busy flag MOVlw .8 MOVwf TX_bcnt ;count for 8 bit transmitting bcf TX_PIN ;start bit MOVlw .3 MOVwf TX_SLICE ;set bit timing MOVlw .1 MOVwf TX_STA ;set transmit STATE-MACHINE goto txEnd txDatBit ;TX_STA=1, send DATA bit here ;time for next bit sending rrf TX_BUFF,f ;rotate bit to C skpnc ;test C goto $+3 bcf TX_PIN ;0 out goto $+2 bsf TX_PIN ;1 out MOVlw .3 MOVwf TX_SLICE ;wait 3 time-slices decfsz TX_bcnt,f goto txEnd ;8 bit serial not end MOVlw .2 MOVwf TX_STA ;set transmit STATE-MACHINE goto txEnd txStop ;TX_STA=2, send STOP bit here bsf TX_PIN ;send STOP bit MOVlw .3 MOVwf TX_SLICE ;set bit timing MOVlw .3 MOVwf TX_STA ;set transmit STATE-MACHINE goto txEnd txIdle ;TX_STA=3, reset transmission to IDLE bcf TXBUSY ;not busy bcf TXEN ;not in transmission clrf TX_STA ;reset transmit STATE-MACHINE goto txEnd ;====== End of TX ========= txEnd ;add more TMR0 related code here tmr0IntEnd MOVlw TMR0CONST addwf TMR0,f goto int_end #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDhint_end banksel pclath_temp MOVf pclath_temp,w ; retieve copy of PCLATH register MOVwf PCLATH MOVf status_temp,w ; retrieve copy of STATUS register MOVwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh ;======================================= ;Code wriiten for test purpose MAIN banksel TRISA ;select respective bank MOVlw b'00000100' ;RA2-input, RA3-output MOVwf TRISA clrf TRISB MOVlw b'10001000' ;TMR0 in timer mode MOVwf OPTION_REG clrf STATUS ;make sure in bank 0 #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh call USART_INIT #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh MOVlw TMR0CONST MOVwf TMR0 #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh MOVlw 0xff MOVwf PORTB #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh bsf INTCON,T0IE bsf INTCON,GIE LOOP ;test code skp1 RXBF ;wait for data received goto $-1 bcf RXBF ;clear data flag MOVf RX_BUFF,w MOVwf TX_BUFF ;send back received data bsf TXEN skp0 TXEN ;wait for transmit completion goto $-1 goto LOOP ; #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh #s嵌入式研究網 href=\"http://www.cnemb.com\">http://www.cnemb.com22222asdfiuuoAowcnemb.commDh;======================================= ;Initializtion of software USART USART_INIT clrf USART_F ;clear all flag bit clrf RX_STA ;reset STATE MACHINE clrf TX_STA bsf TX_PIN ;TX is in Idle return |