hpdell 发表于 2011-12-24 09:56:48

松翰AD转换

我现在搞的AD转换,刚开始时单步还可以,现在单步也不准确了,不知道是何故,程序如下:
ADC_ADR_BUF                                EQU                00000000B        ;set Fcpu/16, adc分辨率bit5=0是8bit; =1是10bit,



;********************************************************************************
;函数名称:L_Adc_Init
;函数功能:adc初始化函数
;p4.0, p4.1, p4.2为adc输入,不带上啦
;输入参数:无
;输出参数:无
;********************************************************************************
L_Adc_Init:

        b0bclr        p4m.0                                ;adc0 set input mode
        b0bclr        p4m.1                                ;adc1 set input mode
        b0bclr        p4m.2                                ;adc2 set input mode
        mov                a,p4ur
        and                a,#11111000b
        b0mov        p4ur,a                                ;设置p4.0 ~ p4.2不带上啦的,可以提高省电

        mov                a,p4con
        or                a,#00000111b
        b0mov        P4CON,a                                ;p4.0 ~ p4.2只能作为模拟输入,不能作为GPIO引脚

        RET



;********************************************************************************
;函数名称:L_Adc_Choose
;函数功能:ADC转换通道选择函数
;输入参数:rAdc_Choose(选择ADC通道p40-p47),根据此参数输出如下数据:
;输出参数0:rVol_Data0,外部电压检测AD值数据
;输出参数1:rBat_Data0,电池自身电压检测AD值数据
;输出参数2:rAdc_Data0,过流电压检测AD值数据
;0C8H    Bit 7   Bit 6   Bit 5   Bit 4    Bit 3    Bit 2   Bit 1    Bit 0
;ADM   ADENB    ADS   EOC   GCHS   CHS3   CHS2    CHS1   CHS0
;读/写    R/W      R/W    R/W      R/W   R/W      R/W   R/W      R/W
;0000 = AIN0;0001 = AIN1;0010 = AIN2;0011 = AIN3;0100 = AIN4;0101 = AIN5;0110 = AIN6;
;0111 = AIN7;1000 = AIN8;1001 = AIN9;1010 = AIN10;1011 = AIN11;1100~1111 = 系统保留。
;********************************************************************************
L_Adc_Choose:

        clr                adm                                        ; 清ADM 寄存器。

        mov                a,#ADC_ADR_BUF                        ;set Fcpu/16, adc分辨率bit5=0是8bit; =1是10bit,
        b0mov        adr,a

        b0bset        fadenb                                ;使能ADC。

        mov                a,#200                                ;20=100US
        call        L_Delay_Xus                        ; 执行ADC 100us 启动时间延迟循环。

        mov                a,#0                                ;清0
        mov                a,rAdc_Choose                ;选择ADC的AIN8通道,即P4.0~P5.3引脚
        or                adm,a

        b0bset        fgchs                                ; 使能ADC 输入通道。总开关开启

        b0bclr        fadcirq                                ; 清ADC 中断请求。
        ;b0bset        fadcien                                ; 使能ADC 中断功能。采用查询法,故此具屏蔽了

        b0bset        fads                                ; 开始AD 转换。

;-----------------------------------------------------------------
aaa:
        b0bts1        feoc                                ; 检查ADC 状态标志。
        jmp                aaa                                        ; EOC=0:AD 转换中。
       
        mov                a,#0                                ;清0
        mov                a,rAdc_Choose
        b0add        pcl,a
        jmp                extern_vol                        ;检测外部电压
        jmp                Battery_vol                        ;检测电池本身电压
        jmp                guoliu_vol                        ;检测过流
;-----------------------------------------------------------------
extern_vol:
        b0mov        a,adb                        ; EOC=1:AD 转换结束,处理AD 转换结果。外部电源
        b0mov        rVol_Data0,a
        jmp                adc_exit
;-----------------------------------------------------------------
Battery_vol:
        b0mov        a,adb                        ; EOC=1:AD 转换结束,处理AD 转换结果。电池检测
        b0mov        rBat_Data0,a
        jmp                adc_exit
;-----------------------------------------------------------------
guoliu_vol:
        b0mov        a,adb                        ; EOC=1:AD 转换结束,处理AD 转换结果。过流检测
        b0mov        rAdc_Data0,a

        ;mov                a,#00000011b        ;8位此句不用
        ;and                a,adr                        ;8位此句不用
        ;b0mov        rAdc_Data2,a                ;8位此句不用 AD 转换结果处理完成。
;-----------------------------------------------------------------
adc_exit:
        b0bclr                feoc                        ; 清除ADC 状态标志以准备下一次ADC。


                ret




main:


callL_Adc_Init

nd:
mov   a,#1   ;选择转换通道AD1
mov   rAdc_Choose,a
callL_Adc_Choose


mov   a,#2   ;选择转换通道AD2
mov   rAdc_Choose,a
callL_Adc_Choose

mov   a,#0   ;选择转换通道AD0
mov   rAdc_Choose,a
callL_Adc_Choose



jmpnd

erxun 发表于 2011-12-24 10:05:31

void adc_init(void)
{
    FADENB = 1;
        delay100us();       //after ADC enable,must delay 100us
        delay100us();       //after ADC enable,must delay 100us
        P4CON = 0x01;       //P4.0is ADC input
        ADR = 0x10;       //8bit adc,adcclock = fcpu/8
        ADM = 0x90;       // AD convert time:
}

void get_ad(void)
{
        FADS = 1;       
        while(FEOC==0);
       
        FEOC = 0;

    //NewValue = ADB;
        //adbuf_low= ADR&0x0f;
        //NewValue = (NewValue<<4) | adbuf_low;

        AD_temp = ADB; //只取8位
}

hpdell 发表于 2011-12-24 10:32:05

好的,我试一下,感谢了

hpdell 发表于 2011-12-24 10:39:42

在程序中要进行几个通道的AD检测,有什么好的方法啊
页: [1]
查看完整版本: 松翰AD转换