打印
[AVR单片机]

mega8A的AD采样问题

[复制链接]
1237|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cherryrain785|  楼主 | 2014-4-14 15:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
采样现象很奇怪,采出来的电流往上升的时候,显示会增加,但是电流值往下降的时候却无法变小,需要放置一会重新插电才会变回原来的数值。
把程序贴上,各位大神帮忙看看什么问题可以吗?我调的快抓狂了。
/*************这是AD的程序*************/
#include "main.h"

extern uint uleakagevalue;
/***********************************************************
** 名    称:void AD_Init(void)
** 功    能:AD初始化
** 入口参数:无
** 出口参数:无
** 使用说明:无
**********************************************************/  
void AD_Init(void)  
{  
    ADCSRA = 0x00; // disable adc
    ACSR = 0x80;   // 禁用模拟比较器
    //参考电压AREF,左对齐,ADC1单端输入   
    ADMUX |= (1<<REFS1)|(1<<REFS0)|(1<<ADLAR) | (1 << MUX0)| (1 << MUX1)| (1 << MUX2);   
    //AD使能, 连续转换,中断关闭,32分频, 6M / 32 = 187.5khz  
   ADCSRA |= (1 << ADEN)|(1 << ADPS2) | (1 << ADPS0)| ( 1<< ADSC);  
//        ADCSRA = 0xCE; // ADC使能,ADC开始转换, 单次转换模式, ADC中断使能
                                       // 64预分频(8M晶振, 125kHz)
}  
lint lSmpAdd=0;
/********************************************
函数名称: GetCurrent
功    能: 电压值
参    数: 无
返回值  : 无
********************************************/
void GetCurrent()
{
    uint i;
        for(i=0;i<5;i++)
                GetADC();
        for(i=0;i<60;i++)   //167等于2个周期,40MS
        {     
                lSmpAdd += GetADC();
                WDR(); //这里喂狗  
               
        }
        uleakagevalue=lSmpAdd/60;//取最大值
        DDRC |= BIT(7);
        PORTC &=~BIT(7);
        Delayms(600);
        DDRC &=~BIT(7);
        Delayms(100);
        lSmpAdd=0;
}
/********************************************
函数名称: GetADC
功    能: 启动ADC,单次转换
参    数: SADnum--AD采样通道号
返回值  : adc--10位AD的转换结果
********************************************/

uint GetADC()
{     
        uint ADvalue=0;
        lint AD_temp1=0,AD_temp2=0;
        //AD开始转换  
    ADCSRA |= (1 << ADSC);
        while((ADCSRA & (1 << ADIF)) == 0)WDR();
        //AD停止转换

    ADCSRA &=~ (1 << ADSC);
        ADvalue = (ADCH<<2);
        ADCSRA|=(1<<ADIF);//写1清除标志位
        ADCH=0;


        /*
        AD_temp1 = ADCL; //一定要先读取低字节
        AD_temp2 = ADCH; //再读取高字节A
        AD_temp1 |= (AD_temp2<<8);
        AD_temp1 = (AD_temp1>>6) & 0x03FF;//10位精度的结果
        ADvalue=AD_temp1;
        */       
        return ADvalue;
}

/******这个是主程序****************/
#include "main.h"
#include "delay.h"
#include "init.h"
#include "disp.h"

#pragma interrupt_handler Key_isr:2
#pragma interrupt_handler Key_isr:3

uchar KeyVal=NULL;
uint uleakagevalue=0;
extern uchar ucDispData[8];
void main(void)
{       

        Delayms(100); //开机延时,稳定内部电源
    WatchDog_Init();
    Port_Init();
        Int_Init();
        init_sm1628();
        AD_Init();
        WDR();
        Disp_8Seg(0,0,0,0,0,0,0,0);
        while(1)
        {       
                GetCurrent();
                DATA_process(uleakagevalue);
                Disp_1Seg(0,ucDispData[0]);
                Disp_1Seg(1,ucDispData[1]);
                Disp_1Seg(2,ucDispData[2]);
                Disp_1Seg(3,ucDispData[3]);
                Delayms(500);
               
            WDR();
        }
}

相关帖子

沙发
airwill| | 2014-4-14 16:50 | 只看该作者
这种情况, 感觉是外部硬件电路信号处理的问题, 最好先验证一下输入电路再调程序.

使用特权

评论回复
板凳
huangxz| | 2014-4-14 19:15 | 只看该作者
先用示波器看看

使用特权

评论回复
地板
dirtwillfly| | 2014-4-14 22:03 | 只看该作者
建议楼主把电路传上来看看

使用特权

评论回复
5
cherryrain785|  楼主 | 2014-4-15 10:07 | 只看该作者


不知道看不看的见。这个是漏电AD和单片机的部分

使用特权

评论回复
6
cherryrain785|  楼主 | 2014-4-15 10:08 | 只看该作者
dirtwillfly 发表于 2014-4-14 22:03
建议楼主把电路传上来看看


麻烦你帮我看一下

使用特权

评论回复
7
cherryrain785|  楼主 | 2014-4-15 10:20 | 只看该作者
huangxz 发表于 2014-4-14 19:15
先用示波器看看

示波器的结果就是一条线。有电压。感觉像是放点放不出去。我用的是峰值检波电路。是不是这个型号的单片机不能用峰值检波??

使用特权

评论回复
8
huangxz| | 2014-4-15 18:05 | 只看该作者
cherryrain785 发表于 2014-4-15 10:20
示波器的结果就是一条线。有电压。感觉像是放点放不出去。我用的是峰值检波电路。是不是这个型号的单片机 ...

所以这个是模拟电路处理的问题,跟单片机没有关系,
建议还是先把模拟部分处理好,再来调程序吧

使用特权

评论回复
评分
参与人数 1威望 +6 收起 理由
qin552011373 + 6
9
cdl511| | 2014-5-22 09:40 | 只看该作者
下来看看,非常感谢!!!

使用特权

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

本版积分规则

1

主题

4

帖子

0

粉丝