打印
[程序源码]

为何这么简单的AD采样程序无**常运行

[复制链接]
2125|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bb2009|  楼主 | 2014-9-7 12:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近我在学习c8051F340的内部ADC0采样,就利用它的P0.3口作为输入口,采样一个直流电压,并将采样值送到P1、P2口。可是发现总是不正常,具体如下。
第一中方法,用中断。问题是不能连续采样,复位启动后第一次采样正确,再往后就保持住第一次采样值不变了。郁闷!程序如下:$NOMOD51
$include (c8051f340.inc)
;public  Init_Device
    cseg AT 0
    ljmp Main
                ORG 0053H
                LJMP A00



Blink       segment  CODE

            rseg     Blink                ; Switch to this code segment.
            using    0                    ; Specify register bank for the
                                          ; following program code.


; Initialization function for device,
; Call Init_Device from your main program


   

MAIN:
               
               
               
    mov  VDM0CN,    #080h
    clr  A                     ; Wait 100us for initialization
    djnz ACC,       $
   
    mov  OSCICN,    #0c3h;使用单片机内部时钟作为系统时钟,且系统时钟频率就是12MHz
    mov  REF0CN,    #03h;使用单片机内部参考源作为AD的参考
                                    ;关闭内部温度传感器
    mov  REG0CN,    #0A0h;Voltage Regulator Disabled.

                anl PCA0MD, #NOT(40h) ;Watchdog Timer disabled
                anl RSTSRC, #NOT(06H);时钟丢失时复位,电源不正常时复位


;adc初始化设置
                MOV AMX0N,#1FH;AD工作在单端模式
                MOV ADC0CF,#18H;ADC时钟为3MHz,AD采样数据在寄存器中右对齐
    mov ADC0CN,#80h;ADC0 Enabled
                               ;连续转换,每次写‘1’ to AD0BUSY开始一次ADC0 conversion



                mov VDM0CN,#0;VDD Monitor Disabled
                mov SMB0CF,#0;SMBus interface disabled
                mov TCON,#0;Timer 0/1均为 disabled

                mov IE,#80H;根据各个位决定各个中断是否允许
                MOV IP,#10H;UART0设置为高中断优先级
                MOV EIE1,#0cH;ADC0中断允许
                mov EIP1,#08h;ADC0中断高优先级
    mov EIE2,#00h;关闭其他扩展中



                mov P0MDIN, #0f7h;P0.3为AD的输入口
                mov P1MDIN,#0ffh
    mov P2MDIN, #0ffh
                mov P3MDIN,#0ffh
                mov P4MDIN, #0ffh

                mov  P0MDOUT,   #0FFh
    mov  P1MDOUT,   #0FFh
    mov  P2MDOUT,   #0FFh
    mov  P3MDOUT,   #0FFh
    mov  P4MDOUT,   #0FFh

                MOV P0SKIP,#08H;P0.3 is skipped
    mov XBR0,#00H
                mov XBR1,#040h
    mov XBR2,#00H

                MOV P0,#00H
                MOV P2,#00H;p0和p1用于指示ad转化结果
                       

    MOV AMX0P,#11H;AD输入口为P0.3


                CLR AD0INT ;清除ADC转换完成标志   
                SETB AD0BUSY
;                acall DELAY
;                JNB AD0INT,$;AD0INT变高前原地等待
THER:
   JNB AD0INT,THER



HERE:ljmp THER


;经实测共计10ms延迟
DELAY:
    MOV R4,#85               ;此指令占有2个时钟周期
LOOP2:
    MOV R5,#255             ;此指令占有2个时钟周期
LOOP1:
    NOP                     ;此指令占有一个时钟周期
    NOP
    DJNZ R5,LOOP1           ;此指令占有2/3个时钟周期
    DJNZ R4,LOOP2
RET

A00:

                MOV P1,ADC0H;
                MOV P2,ADC0L;采样数据送出显示
                CLR AD0INT ;清除ADC转换完成标志,清除中断标志位

RETI


end
第二种方法,用循环。问题更严重,没有采样对过。每次开机P1、P2口输出的采样值就是全高不变,不管输入电压多少。
$include (c8051f340.inc)
;public  Init_Device
    cseg AT 0
    ljmp Main
                ORG 0053H
                LJMP A00



Blink       segment  CODE

            rseg     Blink                ; Switch to this code segment.
            using    0                    ; Specify register bank for the
                                          ; following program code.


; Initialization function for device,
; Call Init_Device from your main program


   

MAIN:
               
               
               
    mov  VDM0CN,    #080h
    clr  A                     ; Wait 100us for initialization
    djnz ACC,       $
   
    mov  OSCICN,    #0c3h;使用单片机内部时钟作为系统时钟,且系统时钟频率就是12MHz
    mov  REF0CN,    #03h;使用单片机内部参考源作为AD的参考
                                    ;关闭内部温度传感器
    mov  REG0CN,    #0A0h;Voltage Regulator Disabled.

                anl PCA0MD, #NOT(40h) ;Watchdog Timer disabled
                anl RSTSRC, #NOT(06H);时钟丢失时复位,电源不正常时复位


;adc初始化设置
                MOV AMX0N,#1FH;AD工作在单端模式
                MOV ADC0CF,#18H;ADC时钟为3MHz,AD采样数据在寄存器中右对齐
    mov ADC0CN,#80h;ADC0 Enabled
                               ;连续转换,每次写‘1’ to AD0BUSY开始一次ADC0 conversion



                mov VDM0CN,#0;VDD Monitor Disabled
                mov SMB0CF,#0;SMBus interface disabled
                mov TCON,#0;Timer 0/1均为 disabled

                mov IE,#80H;根据各个位决定各个中断是否允许
                MOV IP,#10H;UART0设置为高中断优先级
                MOV EIE1,#0cH;ADC0中断允许
                mov EIP1,#08h;ADC0中断高优先级
    mov EIE2,#00h;关闭其他扩展中



                mov P0MDIN, #0f7h;P0.3为AD的输入口
                mov P1MDIN,#0ffh
    mov P2MDIN, #0ffh
                mov P3MDIN,#0ffh
                mov P4MDIN, #0ffh

                mov  P0MDOUT,   #0FFh
    mov  P1MDOUT,   #0FFh
    mov  P2MDOUT,   #0FFh
    mov  P3MDOUT,   #0FFh
    mov  P4MDOUT,   #0FFh

                MOV P0SKIP,#08H;P0.3 is skipped
    mov XBR0,#00H
                mov XBR1,#040h
    mov XBR2,#00H

                MOV P0,#00H
                MOV P2,#00H;p0和p1用于指示ad转化结果
                       

    MOV AMX0P,#11H;AD输入口为P0.3


                CLR AD0INT ;清除ADC转换完成标志   
                SETB AD0BUSY
;                acall DELAY
;                JNB AD0INT,$;AD0INT变高前原地等待
THER:
   JNB AD0INT,THER



HERE:ljmp THER


;经实测共计10ms延迟
DELAY:
    MOV R4,#85               ;此指令占有2个时钟周期
LOOP2:
    MOV R5,#255             ;此指令占有2个时钟周期
LOOP1:
    NOP                     ;此指令占有一个时钟周期
    NOP
    DJNZ R5,LOOP1           ;此指令占有2/3个时钟周期
    DJNZ R4,LOOP2
RET

A00:

                MOV P1,ADC0H;
                MOV P2,ADC0L;采样数据送出显示
                CLR AD0INT ;清除ADC转换完成标志,清除中断标志位

RETI


end

实在兄弟解决不了了。昨天折腾到半夜3点了也不行,救救我吧。

相关帖子

沙发
wangch_sh| | 2014-9-7 14:01 | 只看该作者
汇编那

使用特权

评论回复
板凳
shell.albert| | 2014-9-7 15:58 | 只看该作者
兄弟如果用C语言的话,我估计立即马上就能解决吧.

使用特权

评论回复
地板
coody| | 2014-9-7 18:59 | 只看该作者
打电话问c8051F的技术支持啊。。。。

使用特权

评论回复
5
chen_jhhb| | 2014-9-8 00:13 | 只看该作者
关注中

使用特权

评论回复
6
t446952352| | 2015-8-26 15:52 | 只看该作者
汇编好难

使用特权

评论回复
7
风的样子| | 2015-8-28 09:56 | 只看该作者
汇编啊,就开始学的时候会

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝