| 最近我在学习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点了也不行,救救我吧。
 |