在一些应用中,经常要用到双串口,但是一般单片机只提供一个串口,其实完全可以用普通I/O口模拟一个串口。以下的程序是我编写的模拟串口程序,程序中使用了单片机的定时器0,和INT0中断。数据的发送和接收由中断程序自动进行。程序已经过AVR仿真器仿真和实际烧片使用,证明可靠。有一点需要说明的是,此模拟的串口为半双工方式。
主程序中,单片机将标准串口设置为115200bps,将模拟串口设置为19200bps。单片机将标准串口收到的数据从模拟串口发送出去,将模拟串口接收到的数据从标准串口发送回来。
;**************************************************************************************************
;*title:halfduplexuartsimulatonprogram
;*version:1.0
;*programtime:2001/11/05
;*target:AT90S8515
;*design:zsmbj@beijing
;**************************************************************************************************
.include"c:\programfiles\atmel\avrstudio\appnotes\8515def.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,(1<outgifr,temp;clrint0flag
intemp,gimsk
sbrtemp,(1<outgimsk,temp;enablegimsk/int0
rjmptimer0_end
;>>>>>>>>>>>>>>>>>>>>>>>>>>
;receivestart1bitdata8bitstop1bit
timer0_receive:
cpibit_cnt,1;ifbit_cnt=1thenstartbit
breqtimer0_receive_start
cpibit_cnt,10;ifbit_cnt=10thenstopbit
breqtimer0_receive_stop
rjmptimer0_receive_data
timer0_receive_start:
sbispind,rxd0
rjmptimer0_end
cbrstatus,(1<rjmptimer0_complete
timer0_receive_data:
sec
sbispind,rxd0;getrxd0data
clc
rorsbuf0
rjmptimer0_end
timer0_receive_stop:
cbrstatus,(1<sbispind,rxd0
rjmptimer0_complete
sbrstatus,(1<sbrstatus,(1<;>>>>>>>>>>>>>>>>>>>>>>>>>>
timer0_complete:
intemp,timsk
cbrtemp,(1<outtimsk,temp;disabletimsk/toie0
;;;;;;;;;;;;;;;;;;;
intemp,gifr
sbrtemp,(1<outgifr,temp;clrint0flag
intemp,gimsk
sbrtemp,(1<outgimsk,temp;enablegimsk/int0
cbrstatus,(1<poptemp
outsreg,temp
poptemp
reti
;******************************************
int00:
pushtemp
intemp,sreg
pushtemp
lditemp,(256-N/2);skip0.5bit
outTCNT0,temp
ldistatus,(1<clrbit_cnt
intemp,tifr
sbrtemp,(1<outtifr,temp;clrtifr/tov0
intemp,timsk
sbrtemp,(1<outtimsk,temp;enabletimsk/toie0
intemp,gimsk
cbrtemp,(1<outgimsk,temp;disablegimsk/int0
poptemp
outsreg,temp
poptemp
reti
;**********************************************************rxd0_data:
txd0_data:
ldistatus,(1<pushtemp
intemp,gimsk
cbrtemp,(1<outgimsk,temp;disablegimsk/int0
poptemp
serbit_cnt;bit_cnt=0xff
movsbuf0,temp;senddata
lditemp,(256-N)
outTCNT0,temp;wait1bittimer0interrupt
intemp,tifr
sbrtemp,(1<outtifr,temp;clrtifr/tov0
intemp,timsk
sbrtemp,(1<outtimsk,temp;enabletimsk/toie0
cbiportb,txd0;uartstart
ret
;******************************************
rxd0_data:
sbrsstatus,fe0;iffe0=0thenexit
rjmprxd0_data_end
cbrstatus,(1<movtemp,sbuf0
rxd0_data_end:
ret
;******************************************
;uartreceivedabytsfromuartandthenreturnitfromuart0:
;uartreceivedabytsfromuart0andthenreturnitfromuart:
main:
sbicusr,rxc
rjmpsend_115200
sbrsstatus,rdr
rjmpuart_end
send_19200:
rcallrxd0_data;getuartdatafrom19200bpsuart0
wait2:sbisusr,udrie
rjmpwait2
outudr,temp;senddatato115200bpsuart
rjmpuart_end
send_115200:
intemp,udr;getuartdatafrom115200bpsuart
sbicusr,fe
rjmpuart_end;iffeerrthenend
wait3:sbrcstatus,td;waitsendflag
rjmpwait3
rcalltxd0_data;senddatato19200bpsuart0
uart_end:
rjmpmain
;**********************************************************
.exit
;**********************************************************
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
大嘴业话:苹果与三星之间纠缠不清的爱恨情仇
英飞凌迎接新太空应用的内存市场挑战
如何通过混合信号仿真优化硅光子学
tffs中标map函数的具体意思?
英特尔宣布新任销售及工程技术领导层任命
Robei FPGA仿真工具视频教程
LVDMOS全桥垂直偏转输出电路TDA8357J/8359J
TDA8357J/8359J的测试电路
中智科仪STC810数字延迟脉冲发生器全新升级
通用RS232通讯调试程序v1.5
康文特PDA无线餐饮管理系统
LED追踪效率下降的来源
TDA8351/8356的应用电路
LVDMOS全桥垂直偏转输出电路TDA8358J
Vicor更高密度 - 电源在更小的空间容纳更多功能
中国汽车制造商目标是2026年实现100%采用本地产芯片
大嘴业话:日本半导体产业沉浮录
提取汉字点阵程序
特斯拉采用台积电3nm工艺2026年量产HW5芯片
TDA8357J/8359J应用电路
高薪聘请运动控制高手加盟深圳大族激光科技股份有限公司
Mitsubishi开发用于制造的边缘语言模型
大嘴业话:Intel 部门调整 揭开“英阿大战”序幕
双执行器机器人将高效的地面滚动和旋转飞行结合在一个设计中
台湾MICON MDT20XX 系列单片机
TI的600亿美元晶圆厂支出计划
寻兼职,承接开发项目
数字信号处理与噪音抑制
求职宝典(不断更新)
谈谈我的单片机编程思路