打印
[51单片机]

STC12C5A60S2的10位ADC高八位采集

[复制链接]
3050|20
手机看帖
扫描二维码
随时随地手机跟帖
沙发
kk118a| | 2016-8-14 10:20 | 只看该作者
什么叫结果错误,你看看源码对着么,再看看你的计算值

使用特权

评论回复
板凳
mtff|  楼主 | 2016-8-14 10:24 | 只看该作者
kk118a 发表于 2016-8-14 10:20
什么叫结果错误,你看看源码对着么,再看看你的计算值

我预算的结果高八位应该是0x2a,采集出来的值是0x01,不知道哪里错了

使用特权

评论回复
地板
dabing89| | 2016-8-14 10:46 | 只看该作者
mtff 发表于 2016-8-14 10:24
我预算的结果高八位应该是0x2a,采集出来的值是0x01,不知道哪里错了

你这是让我们猜吗?我们是示波器吗?

使用特权

评论回复
5
mtff|  楼主 | 2016-8-14 10:50 | 只看该作者
#include <STC12C5A60S2.h>
#include "intrins.h"

#define FOSC    12000000L
#define BAUD    2400

#define uchar unsigned char
#define uint unsigned int
void SendData(uchar dat);
void Delay(uint xms)
{
                uint i,j;
                for(i=xms;i>0;i--)
                for(j=110;j>0;j--);
}
void AD_Init()
{   P1ASF=0x01;                 //ÉèÖÃP1.0ͨµÀ
          AUXR1&=0x00;                //ÉèADRJ=0
                P1M0=0x00;                  //ÉèP1.0Ϊ¸ß×èģʽ
                P1M1=0x0f;
                ADC_CONTR=0xe0;             //¿ªÆôADCµçÔ´£¬90¸öʱÖÓÖÜÆÚת»»Ò»´Î
                Delay(100);
}


int GetAD()
{
                unsigned char AD_finished=0;
                int result;
                ADC_CONTR|=0x00;             //P1.0ͨµÀ
                ADC_CONTR|=0x08;             //¿ªÆôADCת»»
          Delay(10);
                while(AD_finished==0)        //µÈ´ýADCת»»Íê³É
                {
                AD_finished=(ADC_CONTR&0x10);
                }
                result=(ADC_RES<<2)+ADC_RESL;  //¶Á×ßת»»½á¹û
                SendData(ADC_RES);
                SendData(ADC_RESL);
                SendData(result);
                ADC_CONTR&=0xef;               //ADCת»»½áÊø±ê־λÇåÁã
                return(result);                //·µ»Øת»»½á¹û
}

// float Ad_AV()
// {
//                 float Val_Av=0;
//                 uchar num;
//                 for(num=10;num>0;num--);
//                 {
//                 Val_Av+=GetAD();
//                 }
//                 Val_Av/=10.0;
//                 Val_Av=Val_Av*5000/1024;
//                 return(Val_Av);
// }

void InitUart()
{   

    SCON = 0x5a;                    //8 bit data ,no parity bit
    TMOD = 0x20;                    //T1 as 8-bit auto reload
    TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate
    TR1 = 1;                        //T1 start running
}

void SendData(uchar dat)
{
    while (!TI);                    //Wait for the previous data is sent
    TI = 0;                         //Clear TI flag
    SBUF = dat;                     //Send current data
}
int main()
{   
          float ad1;
          InitUart();

                AD_Init();
          IE=0xA0;
        while(1)
        {
                ad1=GetAD();
                SendData(ad1);
        }

       
}

不好意思,忘记附程序了

使用特权

评论回复
6
dabing89| | 2016-8-14 11:18 | 只看该作者
mtff 发表于 2016-8-14 10:50
#include
#include "intrins.h"

是不是采样频率太快了呢?

使用特权

评论回复
7
dabing89| | 2016-8-14 11:19 | 只看该作者
你知道AD采样有个采样定理,去看看啊,而且这个STC自带的ADC的转换速率是多少呢?数据手册看看啊,应该就是这几个原因,还有可能程序写错了,不过可能性不大

使用特权

评论回复
8
ningling_21| | 2016-8-14 11:29 | 只看该作者
mtff 发表于 2016-8-14 10:50
#include
#include "intrins.h"

输入最大电压时输出ADC数据是不是FF,03 ?

使用特权

评论回复
9
mtff|  楼主 | 2016-8-14 11:46 | 只看该作者
ningling_21 发表于 2016-8-14 11:29
输入最大电压时输出ADC数据是不是FF,03 ?

理论上是ff   03,不过我给的是5V而且经过6:1分压了

使用特权

评论回复
10
mtff|  楼主 | 2016-8-14 11:51 | 只看该作者
dabing89 发表于 2016-8-14 11:19
你知道AD采样有个采样定理,去看看啊,而且这个STC自带的ADC的转换速率是多少呢?数据手册看看啊,应该就是 ...

低两位采的是对的啊,频率不对不应该对不对嘛?

使用特权

评论回复
11
ningling_21| | 2016-8-14 12:12 | 只看该作者
mtff 发表于 2016-8-14 11:46
理论上是ff   03,不过我给的是5V而且经过6:1分压了

5V为何还要分压?

使用特权

评论回复
12
mtff|  楼主 | 2016-8-14 13:40 | 只看该作者

因为我设计的模拟电路部分最高可测30V,调试的时候为了方便测得是5V,但应该不影响啊

使用特权

评论回复
13
ningling_21| | 2016-8-14 14:25 | 只看该作者
mtff 发表于 2016-8-14 13:40
因为我设计的模拟电路部分最高可测30V,调试的时候为了方便测得是5V,但应该不影响啊 ...

可以试试厂家提供的代码

使用特权

评论回复
14
mtff|  楼主 | 2016-8-14 15:24 | 只看该作者
ningling_21 发表于 2016-8-14 14:25
可以试试厂家提供的代码

嗯,我试了一下,结果是一样的,还在调试中

使用特权

评论回复
15
xgliyouquan| | 2016-8-14 20:25 | 只看该作者
以下内容来源于《51单片机轻松入门-基于STC15W4K系列》
使用P1.1口,串口波特率9600,单片机时钟频率22.1184MHz。计算机串口助手显示,文本模式,9600


unsigned int ADC_P11()
{
        unsigned int i;                    // 用于软件延时程序
        unsigned char status;        // 用于判断AD转换结束的标志
        unsigned int AD_Dat=0;  // 10位AD转换值
        unsigned char Tmp;            // 临时变量用于将AD转换出来的2个字节合成一个字节               
        ADC_CONTR|=0x80;              // 开AD转换电源,第一次使用时要打开内部模拟电源
    for (i=0;i<10000;i++);  // 适当延时等待AD转换供电稳定,一般延时1ms以内即可,为了缩短AD
                            // 调用时间,可把这2行剪切到主程序中去。
        P1ASF|=0x02;                        // 选择P1.1作为AD转换通道,0x02= 0000 0010       
        ADC_CONTR=0xE1;         // 选择P1.1作为AD转换通道,最高转换速度,清转换完成标志。
        for (i=0;i<1000;i++);   // 如果是多通道模拟量进行AD转换,则更换AD转换通道后要适当延时,
// 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内
// 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换AD转换通道,也不需要加延时。
        ADC_CONTR|=0x08;        // 启动 A/D 转换,ADC_START=1。
        status=0;
        while(status==0)              // 等待AD转换结束。
        {
            status=ADC_CONTR&0x10;   // 判断ADC_FLAG是否等于1,0x10=0001 0000B。
        }
        ADC_CONTR&=0xE7;             // 将ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。       
        AD_Dat = ADC_RES;                // 默认高字节高8位。
        AD_Dat <<= 2;
        Tmp = ADC_RESL;         // 默认低字节低2位。
        Tmp &= 0x03;            // 屏蔽无关位
        AD_Dat |= Tmp;                // 高低字节拼接成一个10位数。
        return AD_Dat;
}  
void main(void)
{        
        float Vin;                                   // 存放计算出来的外部输入电压
        unsigned int ADvalue;               // 存放AD转换返回的结果
        UART_init();                                   // 串口初始化9600/22.1184MHz
        printf("串口初始化完毕");
        while(1)
        {                         
                ADvalue=ADC_P11();                   // 采样P1.1口模拟输入电压
                Vin=VCC*ADvalue/1023;      // 注意是1023才正确
                printf("%.3f     ",Vin);                
                delay500ms();
        }                              // 若不用串口显示,此行可设置断点仿真观察结果
}

使用特权

评论回复
16
damoyeren| | 2016-8-15 09:21 | 只看该作者
Val_Av/=10.0;
Val_Av=Val_Av*5000/1024;
这个怎么感觉怪怪的

使用特权

评论回复
17
cainiao_123| | 2016-8-15 09:24 | 只看该作者
上图

使用特权

评论回复
18
mtff|  楼主 | 2016-8-15 13:41 | 只看该作者
damoyeren 发表于 2016-8-15 09:21
Val_Av/=10.0;
Val_Av=Val_Av*5000/1024;
这个怎么感觉怪怪的

这个调试的时候已经屏蔽了

使用特权

评论回复
19
mtff|  楼主 | 2016-8-15 14:18 | 只看该作者
damoyeren 发表于 2016-8-15 09:21
Val_Av/=10.0;
Val_Av=Val_Av*5000/1024;
这个怎么感觉怪怪的

调试的时候,屏蔽了,跟这个没关系。

使用特权

评论回复
20
巅峰灬霸煌| | 2017-9-7 02:45 | 只看该作者
建议启动A/D转换后,在A/D转换结束之前,不改变任何I/O口的状态,有利于高精度A/D转换,若能将定时器/串行口/中断系统关闭更好。

使用特权

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

本版积分规则

3

主题

14

帖子

0

粉丝