;|--------------------------------------------------------------|;| 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 |;|--------------------------------------------------------------| errorlevel -302 ;no bank warning errorlevel -301 ;no default file warning list p=16F83 ;define processor #include <p16F83.inc> ; __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;code protect = OFF ;watchdog = OFF ;power-up delay timer = ON ;oscillator mode = XT;===============================;define RAM variables cblock 0x0c ;GPR start from 0x0cw_temp ;W context saving during interruptstatus_temp ;STATUS context saving during interruptpclath_temp ;PCLATH context saving during interruptUSART_F ;containing flags for USARTRX_BUFF ;USART received data bufferTX_BUFF ;USART transmitting data bufferRX_SLICE ;RX bit-timing controlTX_SLICE ;TX bit-timing controlRX_bcnt ;RX received bit countingTX_bcnt ;TX transmitting bit countingRX_STA ;RX STATE-MACHINE controllerTX_STA ;TX STATE-MACHINE controller endc;===============================;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;===============================;define constant#define OSC_FREQ .4000 ;oscillator frequency in KHz#define BAUDRATE .2400#define TMR0CONST .118 ;256-OSC_FREQ*1000/4/(BAUDRATE*3) + 2;===============================;for my personal style#define skp0 btfsc#define skp1 btfss;********************************************************************** ORG 0x000 clrwdt goto MAIN ; go to beginning of program;=======================================;Interrupt service routine ORG 0x004 ; interrupt vector location 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 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_endtmr0IntStart ;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 nothingrxStartChk ;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 rxEndrxReceiveBit ;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 rxEndrxIdle ;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 txEndtxDo ;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 IDLEtxStartBit ;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 txEndtxDatBit ;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 txEndtxStop ;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 txEndtxIdle ;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 heretmr0IntEnd movlw TMR0CONST addwf TMR0,f goto int_endint_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;=======================================;Code wriiten for test purposeMAIN 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 call USART_INIT movlw TMR0CONST movwf TMR0 movlw 0xff movwf PORTB 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 ;;=======================================;Initializtion of software USARTUSART_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
导读:目前正在解读《PIC单片机模拟异步串行通讯UART源程序》的相关信息,《PIC单片机模拟异步串行通讯UART源程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《PIC单片机模拟异步串行通讯UART源程序》的详细说明。
简介:用TMR0实现定时查询。任何带中断的PIC上都可以实现。可用此法扩展多个串口。
提醒:《PIC单片机模拟异步串行通讯UART源程序》最后刷新时间 2024-03-14 01:00:17,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《PIC单片机模拟异步串行通讯UART源程序》该内容的真实性请自行鉴别。