1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      用AVR單片機模擬的串口程序

      更新時間: 2007-01-23 16:18:59來源: 粵嵌教育瀏覽量:1559

        在一些應用中,經常要用到雙串口,但是一般單片機只提供一個串口,其實完全可以用普通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 "c:\program files\atmel\avr studio\appnotes\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
              rjmp    int00
              .org    0x07
              rjmp    timer0_int
      ;**********************************************************
      .cseg
      ;**********************************************************
      ;****initial
      ;**********************************************************
              .org    0x0010
      ;reset at90s8515
      reset:
              ldi    temp,0b00001000
              out    ddrb,temp

              ldi    temp,high(stack)        ;stack
              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
              out    ucr,temp
      ;timer0 set
              ldi    temp,0x02            ;ck/8 0.72338us
              out    tccr0,temp

              ldi    temp,0x0a            ;disable outside sram,int0 fall edge make a interrupt
              out    mcucr,temp
              ldi    temp,0x40
              out    gimsk,temp            ;enable int0 and int1 interrupt

              ldi    temp,0
              mov    status,temp
              sbi    portb,txd0            ;txd0 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<<intf0)
              out    gifr,temp            ;clr int0 flag
              
              in    temp,gimsk
              sbr    temp,(1<<int0)
              out    gimsk,temp            ;enable gimsk/int0

              rjmp    timer0_end
      ;>>>>>>>>>>>>>>>>>>>>>>>>>>
      ;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<<rdr)            ;start bit wrong then rdr=0 exit
              rjmp    timer0_complete
      timer0_receive_data:
              sec
              sbis    pind,rxd0            ;get rxd0 data
              clc
              ror    sbuf0
              rjmp    timer0_end
      timer0_receive_stop:
              cbr    status,(1<<fe0)            ;if stop bit=0 then fe0=0
              sbis    pind,rxd0
              rjmp    timer0_complete
              sbr    status,(1<<fe0)
              sbr    status,(1<<rdr)            ;rdr=1
      ;>>>>>>>>>>>>>>>>>>>>>>>>>>
      timer0_complete:        
              in    temp,timsk
              cbr    temp,(1<<toie0)
              out    timsk,temp            ;disable timsk/toie0
      ;;;;;;;;;;;;;;;;;;;
              in    temp,gifr
              sbr    temp,(1<<intf0)
              out    gifr,temp            ;clr int0 flag
              
              in    temp,gimsk
              sbr    temp,(1<<int0)
              out    gimsk,temp            ;enable gimsk/int0

              cbr    status,(1<<busy)|(1<<td)    ;busy=0,td=0
      timer0_end:
              pop    temp
              out    sreg,temp
              pop    temp

              reti        
      ;******************************************    
      int00:
              push    temp
              in    temp,sreg
              push    temp

              ldi    temp,(256-N/2)            ;skip 0.5bit
              out    TCNT0,temp

              ldi    status,(1<<busy)        ;busy=1,rdr=0,td=0,fe0=0
              clr    bit_cnt
              
              in    temp,tifr
              sbr    temp,(1<<tov0)
              out    tifr,temp            ;clr tifr/tov0

              in    temp,timsk
              sbr    temp,(1<<toie0)
              out    timsk,temp            ;enable timsk/toie0

              in    temp,gimsk
              cbr    temp,(1<<int0)
              out    gimsk,temp            ;disable gimsk/int0

              pop    temp
              out    sreg,temp
              pop    temp
              reti
      ;**********************************************************rxd0_data:
      txd0_data:
              ldi    status,(1<<busy)|(1<<td)    ;busy=1,td=1,rdr=0

              push    temp
              in    temp,gimsk
              cbr    temp,(1<<int0)
              out    gimsk,temp            ;disable gimsk/int0
              pop    temp
              
              ser    bit_cnt                ;bit_cnt=0xff
              mov    sbuf0,temp            ;send data
              
              ldi    temp,(256-N)
              out    TCNT0,temp            ;wait 1 bit timer0 interrupt

              in    temp,tifr
              sbr    temp,(1<<tov0)
              out    tifr,temp            ;clr tifr/tov0

              in    temp,timsk
              sbr    temp,(1<<toie0)
              out    timsk,temp            ;enable timsk/toie0

              cbi    portb,txd0            ;uart start        

              ret
      ;******************************************    
      rxd0_data:
              sbrs    status,fe0            ;if fe0=0 then exit
              rjmp    rxd0_data_end
              cbr    status,(1<<rdr)            ;rdr=0
              mov    temp,sbuf0
      rxd0_data_end:
              ret
      ;******************************************    

      ;uart received a byts from uart  and then return it from uart0:
      ;uart received a byts from uart0 and then return it from uart :
      main:
          sbic    usr,rxc
          rjmp    send_115200

          sbrs    status,rdr
          rjmp    uart_end
      send_19200:    
          rcall    rxd0_data            ;get uart data from 19200bps uart0

      wait2:    sbis    usr,udrie
          rjmp    wait2
          out    udr,temp            ;send data to 115200bps uart
          rjmp    uart_end

      send_115200:
          in    temp,udr            ;get uart data from 115200bps uart
          sbic    usr,fe
          rjmp    uart_end            ;if fe err then end

      wait3:    sbrc    status,td            ;wait send flag
          rjmp    wait3
          rcall    txd0_data            ;send data to 19200bps uart0
      uart_end:
          rjmp    main
      ;**********************************************************
          .exit
      ;**********************************************************

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 亚洲性爱免费视频在线 | 亚洲精品国产精品乱码无卡 | 中文字幕高清视频在线不卡 | 日韩欧美人成在线观看 | 午夜国产免费观看 | 欧美专区亚洲专区日韩专区 |