;*用AVR 單片機類比的串口程式 ;*zsmbj 發表於 11/7/2001 9:50:17 PM AVR 單片機 _返回版面 ;*在一些應用中經常要用到雙串口但是一般單片機只提供一個串口其實完全可以用普通I/O 口 ;*類比一個串口以下的程式是我編寫的類比串口程式程式中使用了單片機的計時器0 和INT0 ;*中斷資料的發送和接收由中斷程式自動進行程式已經過AVR 模擬器仿真和實際燒片使用證 ;*明可靠有一點需要說明的是此類比的串口?半雙工方式 ;*主程序中單片機將標準串口設置?115200bps,將類比串口設置?19200bps 單片機將標準串口收 ;*到的資料從類比串口發送出去將類比串口接收到的資料從標準串口發送回來 ;**************************************************************** ;* title: half duplex uart simulaton program ;* version: 1.0 ;* program time: 2001/11/05 ;* target: AT90S8515 ;* design: zsmbj@beijing ;**************************************************************** .include "8515def.inc" ;BPS=19200 ;F=11059200 .equ N=72 .equ txd0 =3 ;uart0 txd .equ rxd0 =2 ;uart0 rxd ;**************************************************************** .equ stack=0x0ff ;**************************************************************** ;bit define .equ rdr=0 .equ fe0=1 .equ td=6 .equ busy=7 ;register define .def temp=r16 .def sbuf0=r17 .def status=r18 .def bit_cnt=r19 ;**************************************************************** .org 0x00 rjmp reset .org 0x01 ;外部中斷0 rjmp int00 .org 0x07 ;T/C0溢出 rjmp timer0_int ;********************************************************** .cseg ;********************************************************** ;****initial ;********************************************************** .org 0x0010 ;reset at90s8515 reset: ldi temp,0b00001000 out ddrb,temp ;PB=00001000,PB3=output ldi temp,high(stack) ;stack=0x0ff(前面有定義) out sph,temp ldi temp,low(stack) out spl,temp ldi temp,5 ;baud 115200bps at 11.0592M fosc out ubrr,temp ldi temp,0b00011000 ;enable rx and tx(rxen=1,txen=1) out ucr,temp ;timer0 set ldi temp,0x02 ;ck/8 0.72338us=(1/11.0592M*ck/8) out tccr0,temp ldi temp,0x0a ;disable out sidesram,int0 falledge makea interrupt(int0下降沿中斷) out mcucr,temp ldi temp,0x40 out gimsk,temp ;enable int0 and int1 interrupt(外部中斷int0請求使能) ldi temp,0 ;temp=r16=0 mov status,temp ;status=r18=0 sbi portb,txd0 ;txd0 =3 bit=1 sei ;globle interrupt enable rjmp main ;****************************************** timer0_int: push temp in temp,sreg push temp ldi temp,(256-N) out TCNT0,temp inc bit_cnt sbrs status,td rjmp timer0_receive ;>>>>>>>>>>>>>>>>>>>>>>>>>> ;send data 8 data bit and 1 stop bit timer0_send: sbrc bit_cnt,3 ;if bit_cnt=8 then stop bit rjmp timer0_send_stop timer0_send_data: sbrc sbuf0,0 ;txd=0 sbi portb,txd0 sbrs sbuf0,0 ;txd=1 cbi portb,txd0 lsr sbuf0 rjmp timer0_end timer0_send_stop: sbi portb,txd0 ;stop bit=1 sbrc bit_cnt,0 rjmp timer0_complete ;if bit_cnt=9 then complete ;;;;;;;;;;;;;;;;;;; in temp,gifr sbr temp,(1<>>>>>>>>>>>>>>>>>>>>>>>>> ;receive start 1bit data 8 bit stop 1bit timer0_receive: cpi bit_cnt,1 ;if bit_cnt=1 then start bit breq timer0_receive_start cpi bit_cnt,10 ;if bit_cnt=10 then stop bit breq timer0_receive_stop rjmp timer0_receive_data timer0_receive_start: sbis pind,rxd0 rjmp timer0_end cbr status,(1<>>>>>>>>>>>>>>>>>>>>>>>>> timer0_complete: in temp,timsk cbr temp,(1<