;[DAC.asm]:数模转换驱动文件-----------------------------------------------*
;包含如下子函数:                                                          *
;    (1)DA_SPIInit:SPI初始化                                              *
;    (2)DAC:2片TLV5608转换                                                *
;    (3)TLV5608Init:TLV5608初始化                                         *
;    (4)TLV5608Z:1路DA转换                                                *
;硬件连接:                                                                *
;TLV5608与MC9S08AW60的接线:                                               *
;    ①SCLK(3)接AW60的SPSCK                                               *
;    ②DIN(2)接AW60的MISO                                                 *
;    ③LDAC(18)接AW60的PTC4                                               *
;    ④0-1片FS(4作为片选信号)接分别接的PTC2-3                             *
;    ⑤MODE接高电平，选择uC模式                                           *
;-------------------------------------------------------------------------*
    
    ;小灯驱动所需头文件
    INCLUDE 'MC9S08AW60.inc'    ;MCU映像寄存器名
    INCLUDE 'GeneralFun.asm'         ;应用通用函数文件
    

    ;定义
    SPICR1: equ SPI1C1        ;SPI控制寄存器1
    SPICR2: equ SPI1C2        ;SPI控制寄存器2
    SPIDR:  equ SPI1D         ;SPI数据寄存器
    SPISCR: equ SPI1S         ;SPI状态和控制寄存器
    SendEmptyBit: equ 3       ;SPI发送器空标志位
    CS_P: equ PTCD            ;C口作为TLV5608的片选信号输出口          
    CS_D: equ PTCDD  
          

;声明外部函数  
    XDEF DA_SPIInit      ;DA转换芯片初始化   
    XDEF DAC             ;DA数据转换
    XDEF TLV5608Init     ;TLV5608芯片初始化 
    
MY_ZEROPAGE: SECTION  SHORT ;在此处定义你的变量 
    LoopNum: DS.B 1             ;定义循环次数
    value:   DS.B 2             ;2片5608、16路通道的数字量值
    fs:      DS.B 1             ;
    tempHX:  DS.W 1             ;临时存放HX的值
    buf:     DS.B 2             ;存放数据
    channel: DS.B 2             ;通道号(1-16)
    temp:    DS.B 1             ;存放临时变量
MyCode:      SECTION

;DA_SPIInit:SPI初始化-----------------------------------------------------*
;功 能:对SPI进行初始化,默认为允许SPI,主机工作方式,时钟空闲低电平, 比特率  *
;      2分频,波特率为CGMOUT/2*BD(设CGMOUT=2*fBUS＝2*2.4576MHz)            *
;参 数:无                                                                 *
;返 回:无                                                                 *
;-------------------------------------------------------------------------*
DA_SPIInit:
    PSHA       ;保护寄存器A
    LDA #$50
    STA SPI1C1 ;使能SPI模块为主模式,禁止发送缓冲区空中断，数据传输从最高有效位开始
    LDA #$00
    STA SPI1C2 ;在等待模式中SPI 时钟继续运行,使用单独管脚用于数据输入或输出
    LDA #$42
    STA SPI1BR ;设置通讯波特率=20M/5/8=500K
    PULA       ;恢复寄存器A
    RTS
    

;DAC:2片TLV5608转换-------------------------------------------------------*
;功能:将TLV5608(0)-(1)片,共16通道的数字量转换为模拟量                     *
;入口:HX--2片5608、16路通道的数字量值                                     *
;调用:TLV5608Z                                                            *
;-------------------------------------------------------------------------*
DAC:
    PSHA             ;保护寄存器A
    PSHH             ;保护寄存器H
    PSHX             ;保护寄存器X     
    MOV #1,LoopNum
    STHX tempHX      ;寄存HX的值
    STHX value       ;要转换的值
DAC_Loop:
    LDA  value+1     ;取得要转换值的低8位
    ADD  LoopNum     ;将低位相加
    LDA  value       ;取得value的高8位
    ADC  #0
    LDHX value
    DEC ,X           ;调用下一个过程的入口参数HX
    LDA  LoopNum     ;调用下一个过程的入口参数A   
    JSR  TLV5608Z    ;调用下一个过程TLV5608Z
    LDA  LoopNum
    SUB  #16         ;判断循环次数>16跳出循环
    BGE DAC_Loop
    PULX
    PULH
    PULA     
    RTS
;TLV5608Init:TLV5608芯片D/A转换初始化-------------------------------------*
;功  能:初始化2片TLV5608的CTRL0、CTRL1寄存器                              *
;参  数:无                                                                *
;返  回:无                                                                *
;-------------------------------------------------------------------------*
TLV5608Init:
    PSHA             ;保护寄存器A
    MOV #0,fs        ;设置循环次数2次
TLV_Loop:
    LDA #%00001100   ;定义PTC2~3为输出   
    ORA CS_D
    STA CS_D
    LDA #%00001100   ;定义PTC2~3为输出   
    ORA CS_P
    STA CS_P  
    LDA fs
    ADD #2
    ASLA                    ;A左移一位
    COMA                    ;对A求反
    AND CS_P
    LDA CS_P                ;相应片TLV.FS由高电平变为低电平,产生下降沿
                            ;此后在每个SCLK的下降沿传送一位数据,共传输16位数据  
    JSR Delay               ;延时20个时钟周期          
    LDA #%10000000        ;发送高8位数据(CTRL0地址为1000)     
    STA SPIDR
TLV_loop_1:
    ;为0等待,也就是等待SPTE为1 发送完毕
    BRCLR SendEmptyBit,SPI1S,TLV_loop_1
    LDA #%00000000        ;发送低8位数据
TLV_loop_2:
    ;为0等待,也就是等待SPTE为1 发送完毕
    BRCLR SendEmptyBit,SPI1S,TLV_loop_2
    NOP
    NOP   
    LDA fs
    ADD #2
    ASLA                    ;左移一位
    ORA CS_P
    LDA CS_P                ;数据传输完毕,相应片TLV.FS由低电平变为高电平  
    ;设置CTRL1寄存器
    LDA fs
    ADD #2
    ASLA
    COMA
    AND  CS_P
    LDA  CS_P               ;相应片TLV.FS由高电平变为低电平,产生下降沿
                            ;此后在每个SCLK的下降沿传送一位数据 
    JSR Delay
    LDA #%10010000
    STA SPIDR               ;发送高8位数据(CTRL1地址为1001)
TLV_loop_3
    ;为0等待,也就是等待SPTE为1 发送完毕
    BRCLR SendEmptyBit,SPI1S,TLV_loop_3                           
    LDA #%00001111
    STA SPIDR
TLV_loop_4
    ;为0等待,也就是等待SPTE为1 发送完毕
    BRCLR SendEmptyBit,SPI1S,TLV_loop_4
    LDA fs
    ADD #2
    ASLA
    ORA CS_P
    LDA CS_P
    INC fs
    LDA fs
    CMPA #1
    BLE TLV_Loop     
    PULA     
    RTS                                   

;TLV5608Z:TLV5608芯片D/A转换----------------------------------------------*
;参数:A-通道号(1-16),HX-存放数据                                          *
;返回:无                                                                  *
;-------------------------------------------------------------------------*
TLV5608Z:
    PSHA
    STA  channel+1
    STHX buf
    MOV  #1,channel+1
    LDA  channel +1
    MOV  #1,fs
    CMP  #1
    BGT  next1
    JMP  next
next1:
    CMP  #9
    BLT  next2
next2:
    MOV #0,fs       
next:
    ;整合要发送的16位数据-(value的高4位为通道号,后12位为数据位)  
    LDA  fs
    ASLA
    ASLA
    ASLA
    INCA
    STA temp
    LDA channel +1
    SUB temp
    STA channel +1
    LDA #12
TLVZ_Loop:
    LDHX channel
    ASL ,X
    DBNZA TLVZ_Loop
    LDA channel+1
    ORA buf+1
    LDA channel 
    ORA buf
    LDA #%00001100  ;定义PTC2~3为输出    
    ORA CS_D
    STA CS_D
    LDA #%00001100  ;PTC2~3输出为高电平
    ORA CS_P
    STA CS_P    
    LDA fs
    ADD #2
    ASLA 
    COMA
    ADD CS_P
    STA CS_P        ;相应片TLV.FS由高电平变为低电平,产生下降沿
                    ;此后在每个SCLK的下降沿传送一位数据  
    JSR Delay
    LDA value+1
    STA SPIDR
TLVZ_Loop1:
    ;为0等待,也就是等待SPTE为1 发送完毕
    BRCLR SendEmptyBit,SPI1S,TLVZ_Loop1
    LDA value
    STA SPIDR
TLVZ_Loop2:
    ;为0等待,也就是等待SPTE为1 发送完毕
    BRCLR SendEmptyBit,SPI1S,TLVZ_Loop2
    NOP
    LDA fs
    ADD #2
    ASLA
    ORA CS_P
    LDA CS_P
    PULA
    RTS
