用AVR單片機(jī)模擬的串口程序
在一些應(yīng)用中,經(jīng)常要用到雙串口,但是一般單片機(jī)只提供一個(gè)串口,其實(shí)完全可以用普通I/O口模擬一個(gè)串口。以下的程序是我編寫的模擬串口程序,程序中使用了單片機(jī)的定時(shí)器0,和INT0中斷。數(shù)據(jù)的發(fā)送和接收由中斷程序自動(dòng)進(jìn)行。程序已經(jīng)過AVR仿真器仿真和實(shí)際燒片使用,證明可靠。有一點(diǎn)需要說明的是,此模擬的串口為半雙工方式。
主程序中,單片機(jī)將標(biāo)準(zhǔn)串口設(shè)置為115200bps,將模擬串口設(shè)置為19200bps。單片機(jī)將標(biāo)準(zhǔn)串口收到的數(shù)據(jù)從模擬串口發(fā)送出去,將模擬串口接收到的數(shù)據(jù)從標(biāo)準(zhǔn)串口發(fā)送回來。
;*****************************************************************
*********************************
;*title:halfduplexuartsimulatonprogram
;*version:1.0
;*programtime:2001/11/05
;*target:AT90S8515
;*design:zsmbj@beijing
;*****************************************************************
*********************************
.include"c:programfilesatmelavrstudioappnotes8515def.inc"
;BPS=19200
;F=11059200
.equN=72
.equtxd0=3;uart0txd
.equrxd0=2;uart0rxd
;****************************************************************
.equstack=0x0ff
;****************************************************************
;bitdefine
.equrdr=0
.equfe0=1
.equtd=6
.equbusy=7
;registerdefine
.deftemp=r16
.defsbuf0=r17
.defstatus=r18
.defbit_cnt=r19
;**********************************************************
****************************************
.org0x00
rjmpreset
.org0x01
rjmpint00
.org0x07
rjmptimer0_int
;**********************************************************
.cseg
;**********************************************************
;****initial
;**********************************************************
.org0x0010
;resetat90s8515
reset:
lditemp,0b00001000
outddrb,temp
lditemp,high(stack);stack
outsph,temp
lditemp,low(stack)
outspl,temp
lditemp,5;baud115200bpsat11.0592Mfosc
outubrr,temp
lditemp,0b00011000;enablerxandtx
outucr,temp
;timer0set
lditemp,0x02;ck/80.72338us
outtccr0,temp
lditemp,0x0a;disableoutsidesram,int0falledgemakeainterrupt
outmcucr,temp
lditemp,0x40
outgimsk,temp;enableint0andint1interrupt
lditemp,0
movstatus,temp
sbiportb,txd0;txd0bit=1
sei;globleinterruptenable
rjmpmain
;******************************************
timer0_int:
pushtemp
intemp,sreg
pushtemp
lditemp,(256-N)
outTCNT0,temp
incbit_cnt
sbrsstatus,td
rjmptimer0_receive
;>>>>>>>>>>>>>>>>>>>>>>>>>>
;senddata8databitand1stopbit
timer0_send:
sbrcbit_cnt,3;ifbit_cnt=8thenstopbit
rjmptimer0_send_stop
timer0_send_data:
sbrcsbuf0,0;txd=0
sbiportb,txd0
sbrssbuf0,0;txd=1
cbiportb,txd0
lsrsbuf0
rjmptimer0_end
timer0_send_stop:
sbiportb,txd0;stopbit=1
sbrcbit_cnt,0
rjmptimer0_complete;ifbit_cnt=9thencomplete
;;;;;;;;;;;;;;;;;;;
intemp,gifr
sbrtemp,(1intf0)
outgifr,temp;clrint0flag
intemp,gimsk
sbrtemp,(1int0)
outgimsk,temp;enablegimsk/int0
rjmptimer0_end
評(píng)論