打印

STC单片机AD转换问题

[复制链接]
10212|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LYB911|  楼主 | 2010-7-31 17:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
沙发
928315| | 2010-7-31 18:50 | 只看该作者
如何实现串口的模拟信号转换为数字信号(高于1.5v的输出高电平,低于1.5v的输出低电平),

????看不懂你要表达什么意思。。。

使用特权

评论回复
板凳
zhang123| | 2010-7-31 19:38 | 只看该作者
if(转换<1.5) {out=0;}
if(转换>1.5) {out=1;}

使用特权

评论回复
地板
coody| | 2010-8-1 19:28 | 只看该作者
8路8位, 就是8个通道,每个通道 8bit分辨率。
8路10位,就是8个通道,每个通道10bit分辨率。

使用特权

评论回复
5
yuanquan12345| | 2010-8-2 07:34 | 只看该作者
学习。。。。。。。。。。

使用特权

评论回复
6
LYB911|  楼主 | 2010-8-2 12:47 | 只看该作者

RE: STC单片机AD转换问题,8路8位,和8路10位什么意思

呵呵,我自己就对AD很糊涂,所以表述不太明白,
我要实现将P1.7口的模拟信号,转换成图中P1.7口那样的数字信号(图中使用的是LM339比较器得到的数字信号),要求大于1.5V电压的信号为1,低于1.5V电压的信号为0,图中P1.2口信号为同步信号,每格表示10MS,我写了一下程序不知对不,大家帮我看看

MOV A,#00H
    MOV 40H,#00H          ;第一个8位存于40H单元中
    MOV R2,#8
    CPL C
AAAA:LCALL AD17
    MOV A,ADC_Channel_7_Result
    SUBB A,#4DH            ;1.5V对应16进制数
    JC  DIA              ;小于1.5V时,此时进位标志位C为1,故转移至DI子程序
    SETB C             ;大于1.5V时,此时进位标志位C为0,故不转移
    MOV P1.0,C        ;取出数据以后同时给出同步信号,此处使用P1.0口
    MOV A,40H
    RLC A
    MOV 40H,A
    CLR C            ;将高电平1存入40H单元后,将进位标志位C清0
    AJMP NEXTA        ;取下一个数据
   
DIA: CLR C
    MOV P1.0,C
    MOV A,40H
    RLC A
    MOV 40H,A
    CLR C
NEXTA:LCALL DELAY10MS
    DJNZ R2,AAAA    ;40H单元中取满8位数据,换到41H单元取下8位数据


这是我看STC资料改的程序,实验时AD转换不了
;===================================
;-----------------------------------
;以下为p1.7口AD转换子程序
;-----------------------------------
AD17:
    MOV   SP, #7FH                  ;设置堆栈
    ACALL ADC_Power_On              ;开ADC电源, 第一次使用时要打开内部模拟电源
    ACALL Set_P17_ASF               ;设置 P1.7 为模拟功能口
    ACALL Set_ADC_Channel_7         ;设置 P1.7 作为A/D转换通道
    ACALL Get_AD_Result       ;测量电压并且数据存于ADC_Channel_7_Result
    ACALL Set_P17_Normal_IO    ;设置 P1.7为普通IO
    RET
;---------------------------------------------------
ADC_Power_On:
    PUSH  ACC
    ORL   ADC_CONTR, #80H           ;开A/D转换电源
    MOV   A, #20H
    ACALL Delay                    ;开A/D转换电源后要加延时,1mS以内就足够了
    POP   ACC
    RET
;---------------------------------------------------
;设置P1.7为模拟功能
Set_P17_ASF:
    PUSH  ACC
    MOV   A, #10000000B
    ORL   P1ASF, A
    POP   ACC
    RET
;---------------------------------------------------
;设置P1.7为普通IO
Set_P17_Normal_IO:
    PUSH  ACC
    MOV   A, #01111111B
    ORL   P1ASF, A
    POP   ACC
    RET
;---------------------------------------------------
Set_ADC_Channel_7:
    MOV   ADC_CONTR, #ADC_Power_On_Speed_Channel_7
                    ;选择P1.7作为A/D转换通道
;   MOV   A, #05H   ;更换 A/D 转换通道后要适当延时, 使输入电压稳定
;                   ;以后如果不更换 A/D 转换通道的话, 不需要加延时
;   ACALL Delay     ;切换 A/D 转换通道,加延时20uS~200uS就可以了,与输入电压源的内阻有关
;                   ;如果输入电压信号源的内阻在10K以下,可不加延时
    RET
;---------------------------------------------------
Get_AD_Result:
    PUSH  ACC                       ;入栈保护
    MOV   ADC_RES, #0
    ORL   ADC_CONTR, #00001000B     ;启动 AD 转换
    NOP   ;在对ADC_CONTR寄存器进行写操作后,要加4个空操作延时,才能够正确读到ADC_CONTR的值
    NOP   ;在对ADC_CONTR寄存器进行写操作后,要加4个空操作延时,才能够正确读到ADC_CONTR的值
    NOP   ;在对ADC_CONTR寄存器进行写操作后,要加4个空操作延时,才能够正确读到ADC_CONTR的值
    NOP   ;在对ADC_CONTR寄存器进行写操作后,要加4个空操作延时,才能够正确读到ADC_CONTR的值
Wait_AD_Finishe:
    MOV   A, #00010000B             ;判断AD转换是否完成
    ANL   A, ADC_CONTR
    JZ    Wait_AD_Finishe           ;AD 转换尚未完成, 继续等待
    ANL   ADC_CONTR, #11100111B     ;清0 ADC_FLAG, ADC_START 位, 停止A/D转换
    MOV   A, ADC_RES
    MOV   ADC_Channel_7_Result, A   ;保存 AD转换结果
    POP   ACC
    RET
;---------------------------------------------------
Delayad:                       ;暂时没用到
    PUSH  02                        ;将寄存器组0 的 R2 入栈
    PUSH  03                        ;将寄存器组0 的 R3 入栈
    PUSH  04                        ;将寄存器组0 的 R4 入栈
    MOV   R4, A
Delay_Loop0:
    MOV   R3, #200              ;2 CLOCK  ---------------------+
Delay_Loop1:                    ;                              |
    MOV   R2, #249              ;2 CLOCK  ------+              |
Delay_Loop:                     ;               | 1002 CLOCK   |200406 CLOCK
    DJNZ  R2, Delay_Loop        ;4 CLOCK        |              |
    DJNZ  R3, Delay_Loop1       ;4 CLOCK  ------+              |
    DJNZ  R4, Delay_Loop0       ;4 CLOCK  ---------------------+
    POP   04
    POP   03
    POP   02
    RET
;===================================

AD转换.jpg (70.28 KB )

AD转换.jpg

使用特权

评论回复
7
tcc8073| | 2010-8-2 15:06 | 只看该作者
其实程序不是靠写的,还要靠调试,很多时候可能就是时序上有点问题,自己调一下吧

使用特权

评论回复
8
LYB911|  楼主 | 2010-8-2 15:43 | 只看该作者
7楼说的很对,我也在调着,已经有一些电平变化了,但这里有个问题就是,我需要和1.5V比较,我按STC手册上将1.5V固定电压转换为二进制为4DH,不知对不,那个公式应该怎么理解,谁能帮我算算

使用特权

评论回复
9
LYB911|  楼主 | 2010-8-3 16:47 | 只看该作者
AD转换部分调试成功,以下是AD部分程序,已验证过,绝对可用,同大家分享喽,也使大家少走点弯路,这可是我花费好几天调出来的哦

AD定义部分:
           ;--------------------------AD转换
     ADC_CONTR EQU  0BCH   ;A/D转换寄存器
     ADC_RES   EQU  0BDH   ;8位A/D转换结果寄存器
     P1ASF     EQU  9DH    ;P1口中的相应位作为模拟功能使用时的控制寄存器,如做A/D用,相应位要置1

        ADC_ON_P10 EQU 11100000B  ;P1.0作为ADC输入
     ADC_ON_P11 EQU 11100001B  ;P1.1作为ADC输入
     ADC_ON_P12 EQU 11100010B  ;P1.2作为ADC输入
     ADC_ON_P13 EQU 11100011B  ;P1.3作为ADC输入
     ADC_ON_P14 EQU 11100100B  ;P1.4作为ADC输入
     ADC_ON_P15 EQU 11100101B  ;P1.5作为ADC输入
     ADC_ON_P16 EQU 11100110B  ;P1.6作为ADC输入
     ADC_ON_P17 EQU 11100111B  ;P1.7作为ADC输入
;----------------------------------------------------
     ADC_RESULT     EQU 30H    ;通道A/D转换结果
;--------------------------


;-----------------------------------
;以下为p1.2口AD转换子程序,若需要其他口作为AD口,可相应的改
;-----------------------------------
AD12:
      MOV A,#00000100B             ;设置P1.2为模拟功能,
                                  ;此处可改为P1的另外7个口,要用哪一位就把那位改为1就OK了
    ORL P1ASF,A
      MOV ADC_CONTR,#ADC_ON_P12    ;设置通道P1.2做A/D转换,
                                                             ;此处可改为其他7个口
    LCALL DELAY200US
      LCALL GET_AD_RESULT
      MOV A,#11111011B                        ;设置P1.2为普通IO口
      ANL P1ASF,A                                   ;设置P1.2为普通IO口
                                         ;改其他口时,将相应位改为0即可
      RET
                                                            
;=========================================================
GET_AD_RESULT:                                             ;以下为固定子程序,不用改变
    PUSH ACC
    MOV ADC_RES,#00H
    ORL ADC_CONTR,#00001000B      ;开始A/D转换
    NOP
    NOP
    NOP
    NOP
WAIT_AD_FINISHE:
    MOV A,#00010000B           ;判断A/D转换是否完成
    ANL A,ADC_CONTR
    JZ WAIT_AD_FINISHE         ;A/D没有转换完成,等待
    ANL ADC_CONTR,#11100111B   ;清零ADC_FLAG,ADC_START位,停止A/D转换
    MOV A,ADC_RES
    MOV ADC_RESULT,A          ;保存A/D转换结果
    POP ACC
    RET
;===================================

使用特权

评论回复
10
Galway-Zhang| | 2010-11-17 11:49 | 只看该作者
不错..不知道有没C语言的代码.
对于定义那些还不能理解..

使用特权

评论回复
11
mcu9999| | 2010-11-17 12:54 | 只看该作者
自学成才

使用特权

评论回复
12
tanglin419| | 2012-1-16 12:31 | 只看该作者
1# LYB911
何必呢~弄的那么繁琐,直接外围添加一个电压比较电路就行了呗,基准电压就调为1.5V就行了,当大于1.5V时为高电平,低于1.5V则为低电平。

使用特权

评论回复
13
zoyee.l| | 2012-1-16 20:36 | 只看该作者
你按照他的手册的程序模仿编写就行了,将最后得到的数字结果RES拿来比较就可以了,用unsigned  int RES,将结果变为整形即可处理。

使用特权

评论回复
14
wuxin999| | 2012-1-17 12:39 | 只看该作者
2051的内部比较器可以实现

使用特权

评论回复
15
chenyu988| | 2012-12-9 19:36 | 只看该作者
照楼主的意思,貌似AD都用不到吧,直接上模电书上的比较器不就行了?

使用特权

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

本版积分规则

2

主题

67

帖子

1

粉丝