PIC 单片机模拟异步串行通讯UART源程序
2012-10-04
标签: PIC

用TMR0实现定时查询。任何带中断的PIC上都可以实现。可用此法扩展多个串口。

;|--------------------------------------------------------------|

;|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

listp=16F83;define processor

#include ;

__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

cblock0x0c;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

USART_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

;===============================

;pre-definition for readability

#defineRX_PINPORTA,2;assign RX pin

#defineTX_PINPORTA,3;assign TX pin

#defineTXENUSART_F,0;USART transmit enable

#defineTXBUSYUSART_F,1;USRAT transmit is in progress

#defineRXBFUSART_F,2;USART receive buff full

#defineRXBUSYUSART_F,3;USART receive is in progress

#defineRX_ERRUSART_F,4;USART receive error

#defineTX_ERRUSART_F,5;USART transmit error

;===============================

;define constant

#defineOSC_FREQ.4000;oscillator frequency in KHz

#defineBAUDRATE.2400

#define TMR0CONST.118;256-OSC_FREQ*1000/4/(BAUDRATE*3) + 2

;===============================

;for my personal style

#defineskp0btfsc

#defineskp1btfss

;**********************************************************************

ORG0x000

clrwdt

gotoMAIN; go to beginning of program

;=======================================

;Interrupt service routine

ORG0x004; interrupt vector location

movwfw_temp; save off current W register contents

movfSTATUS,w; move status register into W register

bankselstatus_temp

movwfstatus_temp; save off contents of STATUS register

movfPCLATH,w

movwfpclath_temp; save off contents of PCLATH

bankselINTCON;select bank

skp0INTCON,T0IF;test for TMR0 interrupt

gototmr0IntStart;do TMR0 ISR

;here test for any other interrupt source

gotoint_end

tmr0IntStart;TIMER0 interrupt service

bcfINTCON,T0IF;clear T0IF

;====== start of RX =======

movlwhigh($)

movwfPCLATH;set PCLATH before PCL change

movfRX_STA,w;get the state value for RX

andlw0x03;for safeguard purpose

addwfPCL,f;switch to STATE

gotorxStartChk;check for START bit

gotorxReceiveBit;receive DATA bit

gotorxIdle;wait for idle

gotorxEnd;do nothing

rxStartChk;check for START bit

skp0RX_PIN;test RX pin for START bit

gotorxEnd;not found

;start bit found. do following

movlw.8

movwfRX_bcnt;count for 8 bits incoming data

movlw.4

movwfRX_SLICE;wait 4 time-slice for 1st data bit

movlw.1

movwfRX_STA;switch to STATE 1 for 1st data bit sampling

gotorxEnd

rxReceiveBit;receive DATA bit

decfszRX_SLICE,f;wait of bit timing

gotorxEnd

;time to sample incoming data bit

rrfRX_BUFF,f;right shift for new bit space

bcfRX_BUFF,7;pre-set to 0

skp0RX_PIN;incoming data bit test

bsfRX_BUFF,7;set if data bit = 1

movlw.3;3 slice for data bit timing

movwfRX_SLICE;bit timing for next data bit

decfszRX_bcnt,f;see if 8-bit completed

gotorxEnd

;bit receive completed, do follwoing

movlw.2

movwfRX_STA;set to STATE 2 for idle waiting

bsfRXBF;set receive buffer full

movfRX_BUFF,w;display data on PORTB

movwfPORTB

gotorxEnd

rxIdle;wait for idle

skp0RX_PIN;try to find STOP bit

clrfRX_STA;back to STATE 0 for next byte

gotorxEnd

;====== End of RX =========

rxEnd

;====== start of TX =======

;do TX, if transmit is engaged

skp1TXEN;skip if TXEN set, do TX

gototmr0IntEnd;not in transmit mode

movfTX_SLICE,f;see if in bit-timing delay

skpnz;

gototxDo;bit-timing completed

decfszTX_SLICE,f;keep bit-timing delay

gototxEnd

txDo

;Transmit STATE-MACHINE control

movlwhigh($)

movwfPCLATH;set PCLATH before PCL change

movfTX_STA,w;get current state

andlw0x03;make sure in range

addwfPCL,f;switch to TX STATE

gototxStartBit;send START bit

gototxDatBit;send DATA bit

gototxStop;send STOP bit

gototxIdle;set transtim IDLE

txStartBit;TX_STA=0, send START bit here

bsfTXBUSY;set TX busy flag

movlw.8

movwfTX_bcnt;count for 8 bit transmitting

bcfTX_PIN;start bit

movlw.3

movwfTX_SLICE;set bit timing

movlw.1

movwfTX_STA;set transmit STATE-MACHINE

gototxEnd

txDatBit;TX_STA=1, send DATA bit here

;time for next bit sending

rrfTX_BUFF,f;rotate bit to C

skpnc;test C

goto 3

bcfTX_PIN;0 out

goto 2

bsfTX_PIN;1 out

movlw.3

movwfTX_SLICE;wait 3 time-slices

decfszTX_bcnt,f

gototxEnd;8 bit serial not end

movlw.2

movwfTX_STA;set transmit STATE-MACHINE

gototxEnd

txStop;TX_STA=2, send STOP bit here

bsfTX_PIN;send STOP bit

movlw.3

movwfTX_SLICE;set bit timing

movlw.3

movwfTX_STA;set transmit STATE-MACHINE

gototxEnd

txIdle;TX_STA=3, reset transmission to IDLE

bcfTXBUSY;not busy

bcfTXEN;not in transmission

clrfTX_STA;reset transmit STATE-MACHINE

gototxEnd

;====== End of TX =========

txEnd

;add more TMR0 related code here

tmr0IntEnd

movlwTMR0CONST

addwfTMR0,f

gotoint_end

int_end

bankselpclath_temp

movfpclath_temp,w; retieve copy of PCLATH register

movwfPCLATH

movfstatus_temp,w; retrieve copy of STATUS register

movwfSTATUS; restore pre-isr STATUS register contents

swapfw_temp,f

swapfw_temp,w; restore pre-isr W register contents

retfie; return from interrupt

;=======================================

;Code wriiten for test purpose

MAIN

bankselTRISA;select respective bank

movlwb'00000100';RA2-input, RA3-output

movwfTRISA

clrfTRISB

movlwb'10001000';TMR0 in timer mode

movwfOPTION_REG

clrfSTATUS;make sure in bank 0

callUSART_INIT

movlwTMR0CONST

movwfTMR0

movlw0xff

movwfPORTB

bsfINTCON,T0IE

bsfINTCON,GIE

LOOP;test code

skp1RXBF;wait for data received

goto$-1

bcfRXBF;clear data flag

movfRX_BUFF,w

movwfTX_BUFF;send back received data

bsfTXEN

skp0TXEN;wait for transmit completion

goto$-1

gotoLOOP;

;=======================================

;Initializtion of software USART

USART_INIT

clrfUSART_F;clear all flag bit

clrfRX_STA;reset STATE MACHINE

clrfTX_STA

bsfTX_PIN;TX is in Idle

return

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号