muzheyun 发表于 2011-1-18 20:32:37

对STC无语了,AD转换太NC....

今天尝试STC12C5A60S2的AD转换,将以前的STC12C5620的程序改了一下直接用了,结果刚开始所有通道的值都黏在一起(所有P1口8个通道的值等于P1.0通道的值).即使每次转换前对AD进行初始化也不可以,后来看说明书,在AD_CONTR操作后加了延时.转换后倒是正常了,但是所有P1口未用的悬空的脚的转换值都等于第一个悬空的P1脚的值.
voltageV is 4.989746这是VCC,P1.0通道,TL431基准
voltage1 is 0.131566这是第P1.1通道,值正常
voltage2 is 0.126693这是第P1.2通道,值正常
voltage3 is 1.018415这是第P1.3通道,不正常
voltage4 is 1.086634这是第P1.4通道,不正常

最后两个脚用万用表量没有电压,当然也许万用表的内阻较大量不出来(指针表).
虽然按道理说不用的脚应该接地或上拉至VCC,但是也不至于这么离谱.
最可恶的事情还在后面,我将P1口全部配置为高阻输入模式,结果转换出来的值如下
voltageV is 4.931838
voltage1 is 4.898124
voltage2 is 4.927022
voltage3 is 4.927022
voltage4 is 4.927022
全部又是一样,也许本人不才,是不是高阻和开漏模式的程序是不一样.
下面是程序(改来改去,有些注释和语句已经对不上号了)


#include<stc12c5a60s2.h>           //STC12C54系列单片机头文件
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
float VCC;
sbit light=P2^1;
void init()
{
        PCON |= 0x80;                //使能波特率倍速位SMOD
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
        AUXR &= 0xfe;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0f;                //清除定时器1模式位
        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
        TL1 = 0xAF;                //设定定时初值
        TH1 = 0xAF;                //设定定时器重装值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1
        TI=1;
        SM0=0;
        SM1=1;               
}
void delayms(uint xms)                               
{
        uint i,j;
        for(i=xms;i>0;i--)                      //i=xms即延时约xms毫秒
                for(j=110;j>0;j--);
}
void AD_Init()
{
        P1M0=0xff;//0000 1111 设置P1口低4位为开漏模式,用来AD采集
        P1M1=0x00;//0000 1111
        ADC_CONTR=0x80;//1110 0000 开启AD转换器电源,设置最高转换速度
        delayms(100);
}
int GetAD(unsigned char channel) //channel为要取的通道号(0~7)
{
        unsigned char AD_finished=0;
        int result;
        ADC_CONTR|=channel;   //选择AD通道号
        delayms(3);
        ADC_CONTR|=0x08;      //启动AD转换
        while(AD_finished==0) //等待AD转换结束
        {
                AD_finished=(ADC_CONTR&0x10);//查询ADC_FLAG位是否置1
        }
        result=ADC_RES*4+ADC_RESL;//读走AD转换结果,由于ADC_DATA中存储12位中的
        //高8位,当要转换成10进制时,需将ADC_DATA中的数左移2位,即相当于*4
        ADC_CONTR&=0xf7;   //清除转换结束标志
        return (result);    //返回结果给函数
}
float Ad_Av(uchar channel)    //求100次采集电压的平均值
{
        float Val_Av=0;
        uchar num;
        for(num=100;num>0;num--)
        {
                Val_Av+=GetAD(channel);//100次采集求和
        }
        Val_Av/=100.0;            //求平均值
        //Val_Av=Val_Av*5/1024;//单片机电源为5V,求的真实电压值
        return (Val_Av);          //返回给函数
}
void main()
{
        while(1)
        {
                float ad0,ad1,ad2,ad3,ad4;
                init();
                AD_Init();
                ad0=Ad_Av(0);
                VCC=2.49*1024/ad0;
                AD_Init();
                ad1=Ad_Av(1);
                ad1=ad1*VCC/1024;
                AD_Init();
                ad2=Ad_Av(2);
                ad2=ad2*VCC/1024;
               AD_Init();
                ad3=Ad_Av(3);
                ad3=ad3*VCC/1024;
               AD_Init();
                ad4=Ad_Av(4);
                ad4=ad4*VCC/1024;
                printf("voltageV is %f\n",VCC);
                delayms(2000);
                printf("voltage1 is %f\n",ad1);
                delayms(2000);
                printf("voltage2 is %f\n",ad2);
                delayms(2000);
                printf("voltage3 is %f\n",ad3);
                delayms(2000);
                printf("voltage4 is %f\n",ad4);
                delayms(2000);
    }
}

chenchuan 发表于 2011-1-18 20:47:05

没看太明白,你试图测量悬空的脚的电压?

erxun 发表于 2011-1-18 20:51:44

//AD初始化
P1ASF = 0x20; //P15作为AD口输入
ADC_RES = 0;
ADC_CONTR = ADC_POWER | ADC_SPEEDHH;

/*----------------------------
Get ADC result
----------------------------*/
unsigned char GetADCResult(unsigned char ch)
{
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();                        //Must wait before inquiry
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
    ADC_CONTR &= ~ADC_FLAG;         //Close ADC

    return ADC_RES;               //Return ADC result
}

很好使的。。。。。

erxun 发表于 2011-1-18 21:10:23

楼主的程序啊…可以修改修改的。
读高八位那个,右移两位是不是比乘法要快点呢,
输出结果没必要用浮点数吧,浮点数运算起来资源占用太多。整数运算就行了。LZ对于数值的滤波处理办法也不是很合适。
十位AD,5/1024,分辨电压约为5mV,再加上几个LSB数值跳动、基准源变化,20mV变化算是正常的。

muzheyun 发表于 2011-1-18 21:11:36

就是悬空脚的电压,按说应该接近零,但是转换后的值都1V多了.感觉有点离谱.
erxun 老孟:
程序是官方的吧,我还没有研究,因为懒得再改.

erxun 发表于 2011-1-18 21:23:37

作为AD输入的端口,P1M1 P1M0 是不是设置正确,

muzheyun 发表于 2011-1-18 21:38:01

P1M1=0X00
P1M0=0Xff
8个口全部配置为高阻模式,读出来的值全是5。如果配置为开漏就没有问题,无语。这个程序用起来飘0.1V有点大了,怎么修改都不行,104,334,10微法电容滤波都不行。

shark 发表于 2011-1-18 21:47:35

没看出单片机有啥问题,倒时楼主的基础知识有点问题。

1. 把一个型号的单片机的程序直接装到另外一个型号,还不看说明书,然后要求正确,你试试把Mega48程序放到Mega8里看能行不?

2. 悬空管脚,一般ADC都有极高的输入阻抗,典型是> 10M , 悬空电压值极易受干扰,由于多路切换器和单一采样保持电容的原因,在悬空状态下多路电压一致有啥可奇怪的? 另外,既然悬空,测量或关心它的AD值有什么意义?

3. 关于万用表, 用指针表,比如MF30/MF500, 输入阻抗是20K/V(一些低端表还达不到这个值),那5V档就是100K,测量悬空引脚(阻抗>10M,相当于把该引脚用100K电阻接地,当然测量结果是接近于0 ,当然和非测量时AD采样值不同,如果要测量,则要在连接着万用表的情况下进行AD采样才有意义。

oufuqiang 发表于 2011-1-18 21:48:13

在楼主程序里没有看到P1ASF?

lylatyou 发表于 2011-1-18 21:51:57

悬空和高阻的电压不定,高阻输入容易受内部元件的不一致性影响和空间辐射噪声的干扰。

你找个低阻抗输出、高精度参考电压芯片,比如REF3025,把输出引脚,用很短的引线拉给AD,采个数据试试看,肯定是很稳的。

ADC的输入阻抗也不是理想的那么高,所以,你给ADC采样的信号阻抗较大的话,最好用运放缓冲一下,这样能够减小线路噪声干扰,降低信号跳动。

JQ_Lin 发表于 2011-1-18 22:15:39

“对STC无语了,AD转换太NC....”,又被忽悠了。
顶楼主的标题!

alengend 发表于 2011-1-18 22:43:02

这。。。 我是不是看错了,引脚悬空的情况下进行AD转换的意义在于什么呢?

380121850 发表于 2011-1-18 23:58:39

回复【7楼】shark
没看出单片机有啥问题,倒时楼主的基础知识有点问题。
1. 把一个型号的单片机的程序直接装到另外一个型号,还不看说明书,然后要求正确,你试试把mega48程序放到mega8里看能行不?
2. 悬空管脚,一般adc都有极高的输入阻抗,典型是&gt; 10m , 悬空电压值极易受干扰,由于多路切换器和单一采样保持电容的原因,在悬空状态下多路电压一致有啥可奇怪的? 另外,既然悬空,测量或关心它的ad值有什么意义?
3. 关于万用表, 用指针表,比如mf30/mf500, 输入阻抗是20k/v(一些低端表还达不到这个值),那5v档就是100k,测量悬空引脚(阻抗&gt;10m,相当于把该引脚用100k电阻接地,当然测量结果是接近于0 ,当然和非测量时ad采样值不同,如果要测量,则要在连接着万用表的情况下进行ad采样才有意义。
-----------------------------------------------------------------------

lyhui2008 发表于 2011-1-19 00:16:01

LZ,NC,鉴定完毕。拉不下屎就怪地球没有吸引力。

wmm20031015 发表于 2011-1-19 00:25:37

AD脚的输入不能悬空,否则所得数据有没任何意义

muzheyun 发表于 2011-1-19 07:58:26

一大早起来发现被踩了这么多脚,不过踩的越多越好。
shark,您好,按道理说我不应该把不同型号的程序混用,不过这两个片子同属STC12系列,我查看过手册,SFR基本是一样的,除了高8位和低2位的寄存器定义不同。
2,我配置的是开漏模式,按道理说此时的引脚应该是被拉到地的,也就是接近0V。所以我认为悬空的管脚有1V的电压是不正常的。
3,万用表我用的是Sanwa的指针表,用0.25档指针也没有反应,当然这个表比MF内阻更高,量不出来也可以理解。
alengend:悬空脚的确没意义。
oufuqiang:没有用P1ASF,直接通过channel修改ADC_CONTR的低三位来实现通道切换。
现在就想搞明白为什么开漏模式采集正确,配置成高阻模式就有问题呢?

lusson 发表于 2011-1-19 08:16:01

我记得端口是要设置成模拟输入吧..即高阻输入.开漏是对输出来说的.

muzheyun 发表于 2011-1-19 08:27:10

STC手册上说高阻开漏均可。

xad74 发表于 2011-1-19 08:32:38

P1M1=0X00
P1M0=0Xff
8个口全部配置为高阻模式,读出来的值全是5
楼主看清了没错了吗
P1M1=0X00
P1M0=0Xff 这是推挽输出
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_612019O6RQBD.jpg
(原文件名:1.jpg)

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_612020FZQ6FB.jpg
(原文件名:2.jpg)

locky_z 发表于 2011-1-19 08:36:39

觉得这里很多人只是掌握单片机的编程,但模拟电路、测量电路的实践真的很少。

还是不要整天摆弄protues这些仿真软件吧,仿真出来后最好用烙铁实践一下,不明白就问,




很鄙视这些动不动就说某某器件、某某手册是NC这类语言,给人的印象就是他本人很自大狂妄,没文化。

banyai 发表于 2011-1-19 08:39:03

开漏模式时,有三极管连接到地,虽然它并不通。与高阻输入模式不一样。

yl604922959 发表于 2011-1-19 08:39:31

呃,不好说啊

haimie 发表于 2011-1-19 08:41:44

呵呵,这个价格也就能这样了,除了那个基准电压是用的电源电压比较那个的话,别的都还好

gongnn 发表于 2011-1-19 08:41:58

回复【19楼】locky_z
觉得这里很多人只是掌握单片机的编程,但模拟电路、测量电路的实践真的很少。
还是不要整天摆弄protues这些仿真软件吧,仿真出来后最好用烙铁实践一下,不明白就问,

很鄙视这些动不动就说某某器件、某某手册是NC这类语言,给人的印象就是他本人很自大狂妄,没文化。
-----------------------------------------------------------------------

支持!

muzheyun 发表于 2011-1-19 08:45:22

的确是推娩,看花眼了,把前面看成P1M0了。
locky_z:你不知道有个单词叫做”标题党“?

erxun 发表于 2011-1-19 08:48:28

15 楼
“2,我配置的是开漏模式,按道理说此时的引脚应该是被拉到地的,也就是接近0V”----------这样的认识很危险

muzheyun 发表于 2011-1-19 09:12:17

那应该怎样理解呢?如果开漏模式不拉到地,那么与高阻模式还有什么区别呢?不解

rigol_fan 发表于 2011-1-19 09:36:48

开漏如果该MOS管导通时才是接地,否则就是接近高阻

lee345 发表于 2011-1-19 09:42:42

建议以后对于标题党封ID算了

shark 发表于 2011-1-19 10:27:07

回复【15楼】muzheyun
2,我配置的是开漏模式,按道理说此时的引脚应该是被拉到地的,也就是接近0v。所以我认为悬空的管脚有1v的电压是不正常的。
------------------------------------
头一次听说开漏模式的引脚是被拉到地的。
你的IO口输出0的时候才是,输出1的时候是高阻。



3,万用表我用的是sanwa的指针表,用0.25档指针也没有反应,当然这个表比mf内阻更高,量不出来也可以理解。
-----------------------------------------------------------------------
看来你不明白万用表尤其是指针表的内阻是啥意思,
简单说吧,测量电压的仪表,内阻越高越好,对线路的影响越小,
一般数字表DCV档约为10M omh, 指针表电压档内阻取决于档位,一般用 XX Komh/V 表示,越大说明表越好,
例如20K/V ,当你调到1V档的时候,它的内阻是20K,调到5V档的时候,它是100K,调到0.25V的时候,内阻只有5K
所以指针表档位越小,内阻越小,对测量线路影响越大,当然如果你的信号源本身内阻很小就无所谓了。

当你用5K的仪表去量一个内阻10M的信号源的时候,得到的
测量电压= 仪表内阻×( 真实电压/(仪表内阻+信号源内阻))=5×(U/(5+10000))=U/2000=0.0005 U

U ---[信号源内阻Ri]----[Uo]
                           |
                           -   
                            ||测量仪表
                            ||
                           -
                           |
GND----------------

muzheyun 发表于 2011-1-19 11:08:25

shark
开漏模式在写0时接地,写1时为高阻。那么在将引脚配置为开漏模式时单片机是将其写1还是写0呢?如果写1就是高阻,写0就是接地,如果啥也不写,那么开漏和高阻还有什么区别,STC为什么要将其分为开漏和高阻两种模式呢?直接就一开漏不就行了,想高阻用软件写1。
万用表的问题我基本不接受,如果我连万用表量电压内阻较高量电流内阻小都不知道那趁早闪人别玩了。

shark 发表于 2011-1-19 11:51:29

回复【30楼】muzheyun
开漏模式在写0时接地,写1时为高阻。那么在将引脚配置为开漏模式时单片机是将其写1还是写0呢?如果写1就是高阻,写0就是接地
----------------------------------------------------------------------
我下个数据页看看先,看看有啥新东西,好久没玩STC了。

PS:
简单看了数据页

我的理解:开漏模式可以输出,也可以输入(当然是先输出1以后)。 高阻模式只能输入,不能输出。当然如果你不输出,那写1然后只输入,开漏和高阻没区别。

数据页: 需要作为AD使用的IO口,要先设P1ASF 当应位为1. (见2楼例子)


-------------
关于万用表,我也保留我的观点,当然你可以保留你的观点。

asmmcu 发表于 2011-1-19 12:10:52

一个月前买了带AD的S T C 片子,一直没心情和时间玩它.....


总感觉没多少动力......

hemjidn 发表于 2011-1-19 12:48:31

高阻就是写什么都高阻OD是写1才高阻这是根本区别。电压表的测量不管接不接受,事实就是事实。

madara 发表于 2011-1-19 12:53:43

GetAD这函数里边写错了

“ADC_CONTR|=0x08;”

你确认这么弄会把正确的AD通道数写进寄存器?

muzheyun 发表于 2011-1-19 13:34:38

我无语了
hemjidn 捱多年:难道我的表述有问题,我的意思是万用表根本不需要说那么多,都是常识了。对于开漏和高阻我也明白了,STC之所以分开写只是告诉用户,这两个状态是开漏的两个状态配置后不能通过软件修改,所以分开写。
madara:那个是启动AD转换语句。写通道也是类似方式,而且我十分确认可以正确写入通道,因为这个程序在STC12c5620上是正常运行的。

rigol_fan 发表于 2011-1-19 13:54:14

sharp说得很正确,楼主别老是一根筋啦

muzheyun 发表于 2011-1-20 07:09:00

重新看了一下手册,P1M1=0X00

P1M0=0Xff
是高阻,而不是推娩,我专门打印的一份,不知道怎么回事。

xml2028 发表于 2011-3-1 22:40:24

记得STC 带AD的单片机上这样说的:AD转换模块说使用的的时钟是内部R/C振荡器所产生的系统时钟,不使用时钟分频寄存器CLK_DIV对系统时钟分频后所产生的供给CPU工作所使用的时钟。

我没有理解到这句话的意思:如果真是这句话这样表述的意思的话,那么STC单片机就不可用了,与AVR差得不晓得好远了,
试问:如果需要用ADC功能时,并且需要使用串口通信时,那么还能使用内部RC振荡器吗?由于温度的影响会造成RC振荡器频率漂移。

xml2028 发表于 2011-3-1 22:40:40

看STC12C5A60S2单片机的DATASHEET时,与AVR单片机比较起来感觉寄存器结构很混乱,这可能是由于他在传统51上增加起来的缘故吧

marshallemon 发表于 2011-3-1 22:47:18

仔细看手册上的P1M0和P1M1的设置,不同的片子定义的地址是不一样的,我就遇到了5204和5608定义是反的

zhuyi25762 发表于 2011-3-1 22:57:00

这么多都说人不喜欢STC,用的人还这么多呀
上面都是用的,呵

zhikai_wu 发表于 2011-3-1 23:26:43

因为STC简单好用方便所以我也在用.搞不懂总有些人爱说人家芯片NC/无语...作为一个用户你喜欢就用.不喜欢就不用就是了嘛.什么叫尊重.和谐点...

catzl7 发表于 2011-3-2 09:02:05

回复【25楼】erxun 老孟
15 楼
“2,我配置的是开漏模式,按道理说此时的引脚应该是被拉到地的,也就是接近0v”----------这样的认识很危险


-----------------------------------------------------------------------

顶...

LM1876 发表于 2011-3-2 09:14:30

回复【42楼】zhikai_wu
因为简单好用方便所以我也在用.搞不懂总有些人爱说人家芯片NC/无语...作为一个用户你喜欢就用.不喜欢就不用就是了嘛.什么叫尊重.和谐点...
-----------------------------------------------------------------------
同意,但要是骂它的广告的话,我想就没人反对了

qianwan 发表于 2011-3-2 09:41:40

鉴定楼主NC

mylogin 发表于 2011-3-2 10:10:36

一般单片机由于多路切换器和单一采样保持电容的原因,输入信号阻抗须要在10K ohms以下,如果开路,采样保持电容上的采样电压无通路放电降压,因此任何雑讯或多路切换器其他通道的泄漏电流会储存在采样保持电容上,因此不会是0V, 悬空的脚的转换值更会被其他脚的输入信号影响, 设成高阻输入当然更无法解决问题,应当是低阻输入,解决方法是10K电阻接地,(或您的指针表)让采样保持电容放电. 如果输入信号阻抗太高也会有类似问题,须要降低转换速率,让采样保持电容有足够充放电时间,大部分单片机都有这问题不足为奇(数字电表高内阻,内部使用的ADC是双斜率ADC,采样保持电容先充电到输入电压,再内部放电到0V,量其放电时间,因此完全不同) .多路切换器输入信号电压如果超过供电电压(高杂讯或接地不良),泄漏电流会严重影响其他通道测量结果.

MZ_Guo 发表于 2011-3-23 11:56:38

我用stc的ad查询方式,测温度一直很稳定也很准,
现在改成ad转换完成中断方式,就乱了,我觉得是我程序的问题,与这片子无关

kupica 发表于 2011-3-23 12:09:57

回头试试,正好手上有芯片

xpxp 发表于 2011-3-23 12:11:16

这个论坛隔段时间就会冒出个针对STC的烧饼,呵呵。

19871212 发表于 2011-3-23 12:36:13

说STC 垃圾的都是些什么人啊?等你知识多点以后再来评论别人的芯片好吧?都还不会用呢!就先评论上了。。。

90999 发表于 2011-3-23 12:39:46

难得见STC对一次..........

jsjjccc 发表于 2011-3-23 13:47:42

http://cache.amobbs.com/bbs_upload782111/files_37/ourdev_624811ROZPA6.jpg
(原文件名:12C5A60S2.jpg)

http://cache.amobbs.com/bbs_upload782111/files_37/ourdev_624812Q11BAX.jpg
(原文件名:2052.jpg)

http://cache.amobbs.com/bbs_upload782111/files_37/ourdev_624813DC5BRD.jpg
(原文件名:NEW_8051.jpg)

http://cache.amobbs.com/bbs_upload782111/files_37/ourdev_624814DEG4XG.jpg
(原文件名:2052_H.jpg)

danceman_uk 发表于 2011-3-24 21:37:16

强帖 MARK

ITOUR 发表于 2011-3-24 21:55:34

学到不少知识

williamrain 发表于 2011-3-24 22:50:09

mark

ncigray 发表于 2011-3-24 23:57:55

唉,真是对DSP无语了,学了一整天了,竟然还精通不了,我就不知道这些设计者怎么设计的,还得做电路,还得写代码,还得。。。

你看人家这些计算器多好用,按几个键,几秒之内就能算一个100以内的加法。

xiaobendan 发表于 2011-3-25 07:25:28

动力?找个项目做做吧,哪怕是只卖几十个的,也能赚点,就有动力了,我用着很好啊

ldj7501 发表于 2011-3-25 08:06:18

mark

nop_linyh 发表于 2011-3-25 11:02:25

跟上学习……

k2866 发表于 2011-3-28 15:39:51

mark

wangguanfu 发表于 2011-3-28 15:48:48

回复【23楼】gongnn 魔法师
回复【19楼】locky_z
觉得这里很多人只是掌握单片机的编程,但模拟电路、测量电路的实践真的很少。
还是不要整天摆弄protues这些仿真软件吧,仿真出来后最好用烙铁实践一下,不明白就问,
很鄙视这些动不动就说某某器件、某某手册是NC这类语言,给人的印象就是他本人很自大狂妄,没文化。
-----------------------------------------------------------------------
支持!
-----------------------------------------------------------------------
支持!

mldmicro 发表于 2012-6-4 11:43:57

说那些话的人不是没文化,是没道德,没修养,一家公司一家公司的产品,不是一出来就没有任何问题,一个新型产品都是要有过度期,虽然在工厂里已经有了各项测试,在市场上也是一种测试,考验,你(也就是乱说乱叫的人)能保证你的产品不一问题,我敢说像你(也就是乱说乱叫的人)这种思想做出去的东西,出多少拉多少回来,卡车拉出去,卡车拉回来!还有,外国公司也不是一开始就能生产好的东西,其实他们也很有问题,也不想想他们的利润是多少,每年要从中国带走多少资金和资源!自己可以感受一下,进了屋子苍蝇都要飞出来,对不起这有些过激了!!!!!!!!!

mldmicro 发表于 2012-6-4 11:46:34

wangguanfu 发表于 2011-3-28 15:48 static/image/common/back.gif
回复【23楼】gongnn 魔法师
回复【19楼】locky_z
觉得这里很多人只是掌握单片机的编程,但模拟电路、测量 ...

大力支持,不懂的时候要虚心!不能乱叫,有损国人形象!

mldmicro 发表于 2012-6-4 11:47:55

xiaobendan 发表于 2011-3-25 07:25 static/image/common/back.gif
动力?找个项目做做吧,哪怕是只卖几十个的,也能赚点,就有动力了,我用着很好啊 ...

支持,谢谢!

yao1 发表于 2012-6-4 12:00:37

本帖最后由 yao1 于 2012-6-4 12:05 编辑

#include"STC12C5A60S2.h"
#include "intrins.H"
#include"1621.h"

#define AD_SPEED 0x60//0110,0000   11   90个时钟周期转换一次

//int filter(unsigned char channel);        //滤波

void Delayms(unsigned int z)        //1ms延迟 内部晶振
{      
      unsigned int x,y;
          for(x=z;x>0;x--)
                  for(y=900;y>0;y--);       
}

void int_ad()
{
      P1ASF=0xF0; //1111 0000, 将 P1.7 ~P1.4置成模拟口   
    P1M1=0xF0; //1111 0000(高阻)//注意:更改ADC通道时须同时将对应的IO接口修改为高阻输入。
    AUXR1&= 0x00;//0000,0000, 令 ADRJ=0:10位A/D 转换结果的高8位放在ADC_RES寄存器, 低2位放在ADC_RESL寄存器
    ADC_CONTR |= 0x80;//1000,0000 打开 A/D 转换电源   
}

//---------------------------------------------------------------------
   
unsigned int get_AD_result(unsigned char channel) //AD转换函数   
{
   unsigned char AD_finished=0;//存储 A/D 转换标志
       ADC_RES = 0;    //高八位
   ADC_RESL = 0;   //低二位
   channel &= 0x1f;//0001,1111 选择ADC转换通道
   ADC_CONTR = AD_SPEED; //定义A/D转换速度
   _nop_();
   ADC_CONTR |= channel; //选择 A/D 当前通道
   _nop_();
   ADC_CONTR |= 0x80;//启动 A/D 电源
   Delayms(1);//延迟 使输入电压达到稳定
   ADC_CONTR |= 0x08; //0000,1000 令 ADC_START = 1, 启动A/D转换,
    // AD_finished = 0;
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   while (AD_finished ==0 )//等待A/D转换结束
   {
      AD_finished = (ADC_CONTR & 0x10); //0001,0000测试A/D转换结束否(转换完成ADC_FLAG=1)
   }
   ADC_CONTR &= 0xE7; //1110,0111 转换完成,清ADC_FLAG 位, 关闭A/D转换,
   //return (ADC_RES); //返回 A/D 高 8 位转换结果
   return ((ADC_RES<<2)+ADC_RESL);//返回A/D转换结果(10位ADC数据高8位在ADC_RES中,低2位在ADC_RESL中)
}       
          

///////////////////////////////////////////////////////////////////////////
         
//---------------------------------------------------------------------
//中位值平均滤波法(又称防脉冲干扰平均滤波法):
//连续采样N次,N一般为奇数,然后把N次采样值按从小到大排队,去掉一个最大值和一个最小值
//然后计算N-2个数据的算术平均值    N值的选取:3~14


int filter(unsigned char channel)
{
      unsigned char i;
                unsigned int idata adc_value;        //AD转换缓冲区       
                unsigned int adc_value_ave=0;
                unsigned int max_value=0,min_value=0,max_index=1,min_index=1;

                for (i=0;i<8;i++) //连续转换8次
      {
            adc_value = get_AD_result(channel); //将单次ADC转换结果放入缓冲区         
         //   delay(10);        //每次转换延迟时间
      }
                for(i=1;i<8;i++) // 去掉第一次测量值
                {
                        adc_value_ave+=adc_value;       
                }
                adc_value_ave/=7; // 去掉一个值外的平均值                                                                          
                for(i=1;i<8;i++) // 计算最大值和最小值索引号 排序
                { //排序 最大值第1位(1) 最小值最后1位(i)
                        if(adc_value>adc_value_ave)//大于平均值
                        {                                                
                                if((adc_value-adc_value_ave)>max_value)                                                                                 
                                {                                 
                                        max_value=adc_value;
                                        max_index=1;
                                }
                        }               
                        else//小于平均值
                        {
                                if((adc_value_ave-adc_value)>min_value)
                                {
                                        min_value=adc_value_ave-adc_value;
                                        min_index=i;
                                }
                        }
                }
                adc_value_ave=0;       
                for(i=1;i<8;i++) // 计算去掉最大值和最小值后的总和
                {
                        if((i!=max_index)&&(i!=min_index))//去掉最大值和最小值
                        {
                                adc_value_ave+=adc_value;       
                        }
                }
                if(max_index!=min_index) // 如果测量值不同
                {
                        adc_value_ave/=5; // 计算平均值
                }
                else        // 如果测量值相同
                {
                        adc_value_ave/=6; // 计算平均值
                }
       
                return adc_value_ave;

}

if(flagAD==1) //1S检测1次
                  {
                      ADC7=filter(7); //待测AD 电池
                       ADC4=filter(4); //基准AD 基准电压2.49V 431
                                    ADC6=filter(6);
                            ADC5=filter(5);
                       
                             V_BAT=3*(V_base*ADC7)/ADC4; //V基准/ADC基准== V测/ADC测
                                                           
                      flagAD=0;
                  }                  
       

cqxubo00 发表于 2012-6-4 15:05:34

这个需要mark一下,备用

BXAK 发表于 2012-6-4 16:12:54

wangguanfu 发表于 2011-3-28 15:48 static/image/common/back.gif
回复【23楼】gongnn 魔法师
回复【19楼】locky_z
觉得这里很多人只是掌握单片机的编程,但模拟电路、测量 ...

顶,玩单片机没模电基础不行

yao1 发表于 2012-6-4 16:22:33

51不能用浮点运算 速度超慢 想看小数点后扩大 如4.865 扩大1000倍4865 你自己知道代表4.865就行若显示把小数点点亮就行了

orson 发表于 2012-6-4 16:57:34

STC感觉现在用的人越来越多,不知道性价比如何!

jun66 发表于 2012-6-4 17:23:57

用过12c56和5a60s2 ad都使用的没啥问题,楼主多看些资料 实在不行跑下官方的程序看看

chengtina 发表于 2012-6-7 11:30:19

这个是否也叫躺着也中枪?

bg8wj 发表于 2012-6-7 11:44:33

你太有菜啦!大哥。ad可以测试悬空脚的啊!

1826772880 发表于 2012-6-7 13:43:35

被忽悠进来了,,

liweiqiang668 发表于 2012-6-9 15:39:36

本帖最后由 liweiqiang668 于 2012-6-9 16:05 编辑

樓主的問題我試過,當用多個通道進行AD時,無法分離每個通道的結果,原因在於結束轉換的語句上(ADC_CONTR&=0xf7)=11110111。切換通道時並沒有將其它通道置0,只是相應通道置1。

sonna 发表于 2012-6-9 16:14:31

现在很多人跟风看见STC标题就开骂,不过开骂比“请教”“求助”什么的管用,回复的人多

wcs1668 发表于 2012-6-9 20:59:12

NC,鉴定完毕。拉不下屎就怪地球没有吸引力。

four_zhg 发表于 2012-6-9 21:06:51

楼主,是你的程序有问题吧,我这边用一切正常,总共用了4个AD通道,读数一切正常。其它P1口的正常用做IO口

zhouyan 发表于 2012-6-10 08:09:02

狂妄自大,别人用没问题,到你手里,动不动就说NC!

liudaolunhui 发表于 2012-6-10 10:52:49

没有电路图呀!!!!!!!不好看程序!!!

LBQ691477940 发表于 2012-6-10 11:19:13

用1片TM7705吧才4元一片 16位AD{:lol:}

cy_ygs 发表于 2012-7-26 14:41:13

不错,学习

jackielau 发表于 2012-7-26 15:14:15

楼主基础太差了,不要随意说什么什么器件不行,设计这个的人比你强多了

jackielau 发表于 2012-7-26 15:17:16

本帖最后由 jackielau 于 2012-7-26 15:24 编辑

其实stc还是可以的,我是说价格
如果你项性能好,可以选别的啊

牛东 发表于 2016-6-24 11:49:31

ADC_CONTR&=0xf7;   //清除转换结束标志    ,标志位是第五位吗???好像是第四位吧????????

fsclub 发表于 2016-6-24 12:02:06

wmm20031015 发表于 2011-1-19 00:25
AD脚的输入不能悬空,否则所得数据有没任何意义

有意义,可以做随机数生成的种子~~{:titter:}

Wisen 发表于 2016-6-24 12:34:17

还可以这样生成随机数{:titter:}
太牛了

klxx68 发表于 2016-6-24 15:43:05

muzheyun 发表于 2011-1-19 09:12
那应该怎样理解呢?如果开漏模式不拉到地,那么与高阻模式还有什么区别呢?不解 ...

建议看书吧,书上非常清楚的。

rh.s 发表于 2016-6-24 20:05:36

mylogin 发表于 2011-3-2 10:10
一般单片机由于多路切换器和单一采样保持电容的原因,输入信号阻抗须要在10K ohms以下,如果开路,采样保持电 ...

这个能看懂

xwkm 发表于 2016-6-25 22:04:26

虽然我对STC印象也不太好,但是楼主的标题明显是在形容自己,而不是STC。

549646150 发表于 2016-7-1 15:07:03

STC的下载器有例程

kebaojun305 发表于 2016-7-1 16:08:56

wmm20031015 发表于 2011-1-19 00:25
AD脚的输入不能悬空,否则所得数据有没任何意义

有意义 可以做随机数{:titter:}

kenshudemayi 发表于 2016-7-1 17:18:32

本帖最后由 kenshudemayi 于 2016-7-1 17:27 编辑

这种事隔段时间就要来一回

549646150 发表于 2016-7-2 10:41:50

支持国货,,话说国内做芯片做到STC这种程度的有几家。。。再说我用AD的时候没问题,就是有点抖,猜想应该是数字电路影响了AD参考电压的问题,有没有遇到同样情况的???

MCUStudent 发表于 2016-7-6 21:56:35

手上有几片,有时间试试。

gagaguojia 发表于 2016-7-7 14:46:38

本人用stc15w408as做ad转换,批量板子2000多块出去了,adc转换都没问题,板子工作环境--室外。
stc12c5a60s2 ad我也用过,没问题,但没批量做过产品

kerrwang1982 发表于 2017-1-10 14:59:48

yao1 发表于 2012-6-4 12:00
#include"STC12C5A60S2.h"
#include "intrins.H"
#include"1621.h"


多谢你的代码,刚试过,好的爽.

用例程痛苦了半天.

TBG3 发表于 2017-1-10 16:32:10

STC的AD线性度怎么样?

jyrpxj 发表于 2017-1-10 16:46:26

对楼主无语了

slf0909061 发表于 2017-1-13 14:13:19

可以直接用下载器里面的程序测试呀,很好用的
页: [1] 2
查看完整版本: 对STC无语了,AD转换太NC....