;---------------------------------------------------------------------------*
;[SCI.asm]串口通信程序                                                      *
;本文件包含:                                                                *
;    (1) SCIInit:串行口初始化                                               *
;    (2) SCISend1:串行发送A中的1个字节                                      *
;    (3) SCISendN:串行发送N个字节                                           *
;    (4) SCIRe1:串行接收一个字节->A                                         *
;    (5) SCIReN:串行接收N个字节                                             *
;硬件连接:                                                                  *
;    MCU的串行口与PC机的串行口相连,使用SCI1                                 *
;---------------------------------------------------------------------------*
   
;串口驱动所需头文件
    INCLUDE 'MC9S08AW60.inc' 
 
 ReSendStatusR:  equ  SCI1S1      ;SCI1状态寄存器1
 ReTestBit:      equ  5           ;接收缓冲区满标志位(第5位)
 SendTestBit:    equ  7           ;发送缓冲区空标志位(第7位)
 ReSendDataR:    equ  SCI1D       ;SCI1数据寄存器
 
 ;声明外部函数   
    XDEF  EnableSCIReInt          ;允许SCI接收中断
    XDEF  DisableSCIReInt         ;禁止SCI接收中断
    XDEF  SCIInit                 ;串行口初始化
    XDEF  SCISend1                ;串行发送A中的1个字节
    XDEF  SCISendN                ;串行发送N个字节
    XDEF  SCIRe1                  ;串行接收A中的1个字节
    XDEF  SCIReN                  ;串行接收N个字节
 
;允许SCI接收中断
EnableSCIReInt:
    BSET 5,SCI1C2    
 RTS

;禁止SCI接收中断
DisableSCIReInt:
    BCLR 5,SCI1C2    
 RTS 

;---------------------------------------------------------------------------*
;函 数 名: SCIInit                                                          *
;功能描述: 对串行口进行初始化,允许SCI,正常码输出,8位数据,无校验,允许        *
;          发送器,允许接收器,波特率为9600(设fBUS = 20MHz)                   *
;入    口:无                                                                *
;出    口:无                                                                *
;堆栈深度:2 + 1 = 3                                                         *
;说    明:该子程序与具体的芯片型号(MC9S08AW60)有关                          *
;---------------------------------------------------------------------------*
SCIInit:
    ;总线频率fBUS＝20MHz
    ;定义波特率Bt=9600 
    LDA  #0
    STA  SCI1BDH
    LDA  #130
    STA  SCI1BDL
    ;设置允许SCI，正常码输出、8位数据、无校验
    LDA  #%00000000
    ;         |  |___校验允许位PE=0，无校验
    ;         |______模式选择位M=0，正常模式(8位数据(先发最低位))   
    STA  SCI1C1
    ;允许SCI1接收和发送、禁止接收中断
    LDA  #%00001100
    ;      ||| ||____RE   = 1，接收器允许
    ;      ||| |_____TE   = 1，发送器允许
    ;      |||_______RIE  = 0，禁止接收器中断
    ;      ||________TCIE = 0，禁止发送完成中断
    ;      |_________TIE  = 0，禁止发送器中断
    STA  SCI1C2 
   RTS

;---------------------------------------------------------------------------*
;函 数 名: SCISend1                                                         *
;功能描述: 串行口发送A中的1个字节数据                                       *
;入    口: A = 待发送的数据                                                 *
;出    口: 无                                                               *
;堆栈深度: 2                                                                *
;说    明: 无                                                               *
;---------------------------------------------------------------------------*
SCISend1:
    ;判断发送缓冲区是否为空
    BRCLR SendTestBit,ReSendStatusR,SCISend1
    ;发送数据 
    STA ReSendDataR
   RTS

;---------------------------------------------------------------------------*
;函 数 名: SCISendN                                                         *
;功能描述: 串行发送以HX为首地址的N个字节数据                                *
;入    口: A = 字节个数,HX = 首地址                                         *
;出    口: 无                                                               *
;堆栈深度: 2 + 2 + 1 = 5                                                    *
;内部调用: SCISend1                                                         *
;说    明: 无                                                               *
;---------------------------------------------------------------------------*
SCISendN:
    ;在堆栈区开辟1个字节作临时变量N
    AIS  #-1
    ;若发送字节数为0,退出
    STA  1,SP
    CMP  #0
    BEQ  SCISendN_EXIT
SCISendN_1:
    LDA  ,X                 ;从存储器中取出待发送的数据
    JSR  SCISend1
    AIX  #1
    DBNZ 1,SP,SCISendN_1    ;(N - 1)不等于0转
SCISendN_EXIT:
    ;释放1个字节临时变量
    AIS  #1
   RTS

;---------------------------------------------------------------------------*
;函 数 名: SCIRe1                                                           *
;功能描述:                                                                  *
;        (1)串行接收1个字节的数据放在A中                                    *
;        (2)约655350时钟周期内收不到数返回若时钟周期= 0.4us,大约等待2.6s    *
;入    口: 无                                                               *
;出    口: A = 接收的数据,C = 是否收到数据标志,0收到,1未收到                *
;堆栈深度: 2 + 2 = 4                                                        *
;说    明: 无                                                               *
;---------------------------------------------------------------------------*
SCIRe1:
    PSHH
    PSHX
    ;等待接收一个字节数据
    LDHX  #$FFFF
SCIRe1_1:
    BRCLR ReTestBit,ReSendStatusR,SCIRe1_2
    LDA   ReSendDataR    ;收到的数据放入A中
    CLC
    BRA   SCIRe1_3       ;收到数据,退出
SCIRe1_2:
    NOP
    AIX   #-$1
    CPHX  #$0000
    BNE   SCIRe1_1
    ;等待时间到,未收到数据,令C = 1,A = FF,返回
    LDA   #$FF
    SEC
SCIRe1_3:
    PULX
    PULH
 RTS

;---------------------------------------------------------------------------*                                           
;函 数 名: SCIReN                                                           *
;功能描述: 串行接收N个字节放在以HX为首地址的内存中                          *
;入    口: A = 待接收数据的字节数N,HX = 接收数据存放的首地址                *
;出    口: C = 是否收到数据标志,0收到,1未收到                               *
;堆栈深度: 2 + 4 + 1 = 7                                                    *
;内部调用: SCIRe1                                                           *
;说    明: 无                                                               *
;---------------------------------------------------------------------------*
SCIReN:
    ;在堆栈区开辟1个字节作临时变量
    AIS  #-1
    ;若接受字节数为0,退出
    STA  1,SP
    CMP  #0
    BEQ  SCIReN_EXIT
SCIReN_1:
    JSR  SCIRe1         ;调用接收1个字节的子程序
    BCS  SCIReN_EXIT    ;C = 1未收到数据,退出
    STA  ,X             ;收到数据,放入内存
    AIX  #1             ;HX + 1 ->HX
    DBNZ 1,SP,SCIReN_1
SCIReN_EXIT:
    ;释放1个字节临时变量
    AIS  #1
 RTS
 


