;[AD.asm]A/D转换---------------------------------------*
;本文件包含:                                           *
;    (1)ADCInit:A/D转换初始化                          *
;    (2)ADCValue:获取AN0~AN7中任意一路的模拟量的A/D转  *
;                换结果                                *
;    (3)ADCMid:获取中值滤波后的A/D转换结果             *
;    (4)ADCAve:获取均值滤波后的A/D转换结果             *
;硬件连接:                                             *
;    没有显式的外部连接,使用默认的26通道时,直接读出相  *
;    应寄存器的数值即可                                *
;------------------------------------------------------*
  INCLUDE 'MC9S08AW60.inc'

;声明外部可以引用的函数  
  XDEF  ADCInit      ;A/D转换初始化
  XDEF  ADCValue     ;获取AN0~AN7中任意一路的模拟量的A/D转换结果
  XDEF  ADCMid       ;获取中值滤波后的A/D转换结果
  XDEF  ADCAve       ;获取均值滤波后的A/D转换结果
        
;ADCInit:A/D转换初始化---------------------------------*
;功能:A/D转换初始化,设置A/D转换时钟频率为1MHz          *
;入口:无                                               *
;出口:无                                               *
;堆栈深度:2                                            *
;------------------------------------------------------*
ADCInit:
    LDA #%10110011
    ;     ||||||||
    ;     |||||||+-ADICLK0 \
    ;     ||||||+--ADICLK1 / -- 模块内部ADACK(ADLPC=1时，约为2MHz)
    ;     |||||+---MODE \
    ;     ||||+----MODE /    -- 8位
    ;     |||+-----ADLSMP    -- 长采样时间
    ;     ||+------ADIV0 \
    ;     |+-------ADIV1 /   -- 2分频
    ;     +--------ADLPC     -- 低功耗配置
    STA ADC1CFG
    
    LDA #%00000000
    STA ADC1SC1
    
    LDA #%00000000  
    ;     ||||xxxx
    ;     ||||
    ;     |||+-----ACFGT     -- 未使用
    ;     ||+------ACFE      -- 禁止比较功能
    ;     |+-------ADTRG     -- 软件触发
    ;     +--------ADACT     -- 没有正在进行中的转换
    STA ADC1SC2
    
    ;为了保持ADCInit的通用性，没有加上这句,但实际应用中,应加上这句
    ;LDA #%00000001
    ;STA APCTL2
    ;禁止AD8引脚的I/O控制
   RTS

;ADCValue:1路A/D转换子程序------------------------------*
;功    能:对某通道进行A/D转换,结果放入A                 *
;入    口:A=通道号                                      *
;出    口:HX=该通道的A/D转换结果                        *
;堆栈深度:2 + 2 = 4                                     *
;-------------------------------------------------------* 
ADCValue:
    AIS #-2
    AND #%00011111
    STA 1,SP            ;暂存通道号AD0-AD27=00000-11011
    LDA ADC1SC1
    AND #%11100000
    ORA 1,SP
    STA ADC1SC1
TestCocoBit:    
    BRCLR ADC1SC1_COCO,ADC1SC1,TestCocoBit   ;取A/D转换结果
    LDA ADC1RH
    STA 1,SP      ;暂存最后结果的高八位
    LDA ADC1RL
    STA 2,SP      ;暂存最后结果的低八位
    LDHX 1,SP     ;将(SP+1)和(SP+2)中的数一起放入HX中
                  ;其中(SP+1)中的数放入H中
                  ;(SP+2)中的数放入X中
    AIS #2 
   RTS

;ADCMid:1路A/D转换子程序(中值滤波)----------------------*
;功    能:对某通道进行三次采样,中值滤波结果放入HX       *
;入    口:A=通道号                                      *
;出    口:HX=该通道中值滤波后的A/D转换结果              *
;堆栈深度:2 + 9 + 4 = 15                                *
;内部调用:ADCValue                                      *
;-------------------------------------------------------*
ADCMid:
    AIS #-9          ;在堆栈区开辟临时变量
    STA 9,SP         ;暂存通道号
    
    LDA 9,SP         ;取三次A/D转换结果
    JSR ADCValue
    STHX 1,SP        ;第一次转换结果存入
    
    LDA 9,SP
    JSR ADCValue
    STHX 3,SP        ;第二次转换结果存入
    
    LDA 9,SP
    JSR ADCValue
    STHX 5,SP        ;第三次转换结果存入
    
    ;从三次A/D转换结果中取中值
    ;取出堆栈前2个数比较,小的放在(SP+1):(SP+2)中,大的放在(SP+3):(SP+4)中
    LDHX 1,SP
    CPHX 3,SP
    BLS ADCMid1        ;若(SP+1):(SP+2)<=(SP+3):(SP+4),转ADCMid1 
    STHX 7,SP          ;否则(SP+1):(SP+2)与(SP+3):(SP+4)互换
    LDHX 3,SP
    STHX 1,SP
    LDHX 7,SP
    STHX 3,SP
ADCMid1:     
    LDHX 5,SP          ;取出(SP+5):(SP+6)中的数,与(SP+3):(SP+4)比较
    CPHX 3,SP
    BHS ADCMid2        ;若(SP+5):(SP+6)>(SP+3):(SP+4),转ADCMid2
    CPHX 1,SP          ;否则与(SP+1):(SP+2)比较
    BHI ADCMid3
    LDHX 1,SP
    BRA ADCMid_Exit
ADCMid2:
    LDHX 3,SP
    BRA ADCMid_Exit
ADCMid3:
    LDHX 5,SP
ADCMid_Exit:
    AIS #9            ;释放临时变量
  RTS

;ADCAve:1路A/D转换子程序(均值滤波)-----------------------*
;功    能:求某通道X次均值滤波结果,并放入HX中             *
;入    口:A=通道号 X=平均次数(1--255)                    *
;出    口:HX=该通道中值滤波后的A/D转换结果               *
;堆栈深度:2 + 7 + 15 = 24                                *
;内部调用:ADCMid                                         *
;--------------------------------------------------------*
ADCAve:
     AIS #-7         ;在堆栈区开辟临时变量
     STX 7,SP
     STX 6,SP        ;暂存平均次数
     STA 5,SP        ;暂存通道号
     LDA #0          ;初始化次数值
     STA 4,SP        ;存放一次中值滤波结果的低八位
     STA 3,SP        ;存放一次中值滤波结果的高八位
     STA 2,SP        ;存放和的结果高的八位
     STA 1,SP        ;存放和的结果的低八位
     
ADCAve_1:            ;求X次的和
     STX 7,SP
     LDA 5,SP        ;取通道号
     JSR ADCMid
     
     STHX 3,SP
     LDA 4,SP        ;先低八位求和
     ADD 1,SP        ;相加
     STA 1,SP
    
     LDA 3,SP
     ADC 2,SP        ;带进位的高八位相加
     STA 2,SP        ;无论如何高八位是不可能溢出的
     
     LDX 7,SP
     DBNZX  ADCAve_1
     
     CLRA
     STA 3,SP
     STA 4,SP        ;(SP+3):(SP+4)里面放入均值求得的商
Div_Loop:
     LDA 1,SP
     SUB 6,SP
     STA 1,SP
     LDA 2,SP
     SBC #0
     STA 2,SP
     BCS ADCAve_End;测试为1的话,说明有借位,不够减,则减法结束
     LDA 4,SP
     INCA
     STA 4,SP
     LDA 3,SP 
     ADC #0    
     STX 3,SP
     BRA Div_Loop
ADCAve_End:
     LDHX 3,SP
	 AIS #7            ;释放临时变量
   RTS



 
  