打印
[STC单片机]

AD通道1中断函数 测试无作用?

[复制链接]
2277|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
opal11|  楼主 | 2013-8-20 19:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AD放在主函数中,不用中断就可以检测电压,,但把AD放入AD中断,就检测不了电压,不知是什么原因?

以下程序是源程序:
/***************************************************  
        AD通道1中断函数 测试无作用??
        IC:STC12C5201AD
****************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sfr ADC_CONTR  = 0xbc;                //ADC控制寄存器
sfr P1ASF         = 0x9d;                        //P1口模拟功能控制寄存器
sfr ADC_RES    = 0xbd;                //ADC转换结果寄存器 高8位
sfr ADC_RESL   = 0Xbe;                //转换结果低2位
sfr AUXR=0x8e ;                       //分频辅助寄存器
sfr P1M1        = 0x91;                        //特殊功能寄存器
sfr P1M0         = 0x92;                        //特殊功能寄存器
#define adc_power         0x80        // ADC转换电源控制
#define adc_flag          0x10        // ADC转换完成标记
#define adc_start         0x08        // ADC转换开始控制
#define        adc_speedll        0x00        // ADC转换速度控制 420个时钟完成
#define        adc_speedl        0x20        // ADC转换速度控制 280个时钟完成
#define        adc_speedh        0x40        // ADC转换速度控制 140个时钟完成
#define        adc_speedhh        0x60        // ADC转换速度控制 70个时钟完成
#define  vdd  3.3                         //vdd基准电压值
uint dat2;
float vin;                
void delay100us();

void init_adc()
{
        P1M0 = 0x00;                  //  设置P1仅做为输入(高阻)   
        P1M1 = 0xff;                //  设置P1仅做为输入(高阻)
        P1ASF=0x02;                        // P1.1        作为模拟功能A/D使用
}

/*** AD通道1中断函数 ***/
void adc_1(void) interrupt 5
{          
            uchar AD_finished=0;                                         //存储 A/D 转换标志
//            ADC_RES = 0;                                                                         //清除之前的A/D转换数据
            ADC_CONTR=adc_power|adc_speedl|adc_start|1;                  //ADC控制寄存器        打开AD转换电源、速度、开始、选通道1
                delay100us();                                                                        //需经过四个CPU时钟延时,
            while (AD_finished ==0 )                                        //等待A/D转换结束
            {
                AD_finished = (ADC_CONTR & 0x10);                         //0001,0000 测试A/D转换结束否
            }
            ADC_CONTR &=!adc_flag;                                      //1110,1111 清 ADC_FLAG 位, 关闭A/D转换,
                dat2=ADC_RES;                                                                        //dat2=ADC 的值
}

main()
{


        init_adc() ;
        ADC_RES = 0;                //ADC_RES清0
        dat2        = 0;                //dat2清0
        vin                = 0;                //vin清0

        ADC_CONTR|=0x80;         //1000 0000开A/D转换电源,
        IE |= 0xa0;                        //开总中断,开AD中断EADC=1
        while(1)
        {
               
                vin=vdd/256*dat2;                                                                //vdd = 3.3V
                if(vin<0.05)                                 P2=0xff;        //1111 1111         全灭
                if((vin>=0.06)&(vin<=0.5))        P2=0xfe;        //1111 1110         led1亮
                if((vin>0.6)&(vin<=1))        P2=0xfd;                //1111 1101         led2亮
                if((vin>1.1)&(vin<=2))        P2=0xfb;                //1111 1011         led3亮
         }

       

}
                               
/*** 延时100us函数 ***/
void delay100us(void)   //误差 0us
{
    uchar a,b;
    for(b=1;b>0;b--)
        for(a=47;a>0;a--);
}

相关帖子

沙发
xiaoliping1945| | 2013-8-24 14:17 | 只看该作者
问题在你的中断里面的函数,能进入中断,表示的是转换完成,可以读取结果寄存器里面的数据, 就直接读取结果就行了,而你进入中断后你没有读取结果,而是又开启了AD转换,它转换时间短的很,你刚要执行别的语句是,又来了中断,进入重点第一步要清除中断标志,你这都放到最后去了。步骤:进入中断,1)清除中断标志  2)读取结果  3)做该做的事。。。。。。。4)打开下一次转换

使用特权

评论回复
板凳
xiaoliping1945| | 2013-8-24 14:19 | 只看该作者
xiaoliping1945 发表于 2013-8-24 14:17
问题在你的中断里面的函数,能进入中断,表示的是转换完成,可以读取结果寄存器里面的数据, 就直接读取结 ...

补充一点,原先你没用中断,用的是查询法,所以能采集电压,你现在改用中断,就不需要再查询了吧,没必要

使用特权

评论回复
地板
xiaoliping1945| | 2013-8-24 14:28 | 只看该作者
补充一点,原先你没用中断,用的是查询法,所以能采集电压,你现在改用中断,就不需要再查询了吧,没必要;把你中断里这样修改:估计能行,我就按下面这么写的,屡试不爽。
/*** AD通道1中断函数 ***/
void adc_1(void) interrupt 5
{         
                          ADC_CONTR &=!ADC_FLAG                           //清除中断标志
             dat2=ADC_RES;                                                //读取结果寄存器值

。。。。。。。。这里 做你想做的。。。。。(或者在主函数里做你想做的 做完后再打开AD转换,即把下面的放到主函数里)
            ADC_RES;     //清除结果寄存器值
            ADC_CONTR=adc_power|adc_speedl|adc_start|1;    //打开转换电源、速度、开始、选通道1
                        delay100us();                                                                        //延时,待电源稳定
       }

使用特权

评论回复
5
opal11|  楼主 | 2013-8-26 21:46 | 只看该作者
多谢楼上详细的解答。

使用特权

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

本版积分规则

个人签名:选对一件事,坚持下去,一定会成功!

10

主题

392

帖子

1

粉丝