请问有谁有stc12c5a60s2中文资料单片机datasheet上的ad转换程序应用后,只开p1.0路,采

STC12C5A60S2AD功能的使用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
STC12C5A60S2AD功能的使用
上传于||文档简介
&&对​宏​晶​公​司​生​产​的01​内​核​单​片​机​ ​S​T​C2​CA0​S ​A​D​功​能​的​介​绍
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢STC12C5A60S2单片机的10位AD转换程序
13:49:34来源: 51hei
//**************************************** ***********************************************//
#include"stc12c5a.h" //头文件在STC公司主页上下载
#include"stdio.h"
#include"intrins.h"
//------------------------------------------------------------------------------
void AD_init();
void serial_init();
void delay(unsigned int a);
float AD_work(unsigned char channel);
unsigned int AD_get(unsigned char channel);
//------------------------------------------------------------------------------
void main()
AD_init();&&& //A/D转换初始化
serial_init();&& //串口初始化
&& for(i=0;i<8;i++) //循环发送P1.0-P1.7的转换数值
&&& TI=1;&&& //使用printf函数前须先将发送标志位TI置1
&&& printf("The P1.%bd voltage is %f
",i,AD_work(i));
&&& delay(1000); //延时约1s
//------------------------------------------------------------------------------
unsigned int AD_get(unsigned char channel)
ADC_CONTR=0x88|&&& //开启AD转换 即POWER SPEED1 SPEED0 ADC_FLAG&& ADC_START CHS2 CHS1 CHS0&
_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR&寄存器
while(!(ADC_CONTR&0x10));&&& //等待转换完成
ADC_CONTR&=0xe7;&&&&& //关闭AD转换,ADC_FLAG位由软件清0
return(ADC_RES*4+ADC_RESL);&& //返回AD转换完成的10位数据(16进制)
//------------------------------------------------------------------------------
float AD_work(unsigned char channel)
float AD_&&&& //定义处理后的数值AD_val为
for(i=0;i<100;i++)&
AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
AD_val/=100;
AD_val=(AD_val*5)/1024; //AD的参考电压是上的5v,所以乘5即为实际电压值
return AD_
//------------------------------------------------------------------------------
void delay(unsigned int a) //延时约1ms
while (--a!=0)
for(i=600;i>0;i--);&& //1T单片机i=600,若是12T单片机i=125
//------------------------------------------------------------------------------
void serial_init()
TMOD=0x20;
TL1=0 //设置9600波特率
SCON=0x50; //串口方式1,允许接收
//------------------------------------------------------------------------------
void AD_init()
P1ASF=0 //P1口全部作为模拟功能AD使用
ADC_RES=0;&& //清零转换结果寄存器高8位
ADC_RESL=0; //清零转换结果寄存器低2位
ADC_CONTR=0x80;//开启AD
delay(2);&& //等待1ms,让AD电源稳定
关键字:&&&&
编辑:什么鱼
引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
微信扫一扫加关注 论坛活动 E手掌握
微信扫一扫加关注
芯片资讯 锐利解读
大学堂最新课程
馆内包含了 纵览FRAM、独立FRAM存储器专区、FRAM内置LSI专区三大部分内容。 
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。21ic官方微信-->
后使用快捷导航没有帐号?
查看: 2349|回复: 17
能帮我看下STC12使用自己AD的程序吗?不知道哪里出错了,
&&已结帖(20)
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
#include&stc12.h&
#include&intrins.h&
#define uchar unsigned char
#define uint&&unsigned int
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;
void Lcd1602_Delay1ms(uint c);& & //误差 0us
void LcdWriteCom(uchar com);& &//LCD1602写入8位命令子函数
void LcdWriteData(uchar dat);& &//LCD1602写入8位数据子函数
void LcdInit();& && & //LCD1602初始化子程序
void adInit(void);
unsigned int getAd(unsigned char channel);
unsigned char Num[]=&the AD result :&;
void main()
uint ad,a1,a2,a3,a;
LcdInit();
for(a=0;a&15;a++)
& &LcdWriteData(Num[a]);
& &ad=getAd(0);
& &ad=(ad*5)/1024;
& &a1=ad/100;
& &a2=ad%100/10;
& &a3=ad%10;
& &LcdWriteCom(0x80+0x40);
& &LcdWriteData('0');
& &LcdWriteData(0x30+a2);
& &LcdWriteData(0x30+a3);
void adInit(void)
& && && &P1ASF=0x07; //P1.0/P1.1/P1.2口全部作为模拟功能AD使用
&&P1M0 = 0
& && && &P1M1 = 0
& && && &ADC_RES=0;& &//清零转换结果寄存器高8位
& && &&&ADC_RESL=0; //清零转换结果寄存器低2位
& && &&&ADC_CONTR=0x80;//开启AD电源
& && &&&Lcd1602_Delay1ms(1);& &//等待1ms,让AD电源稳定
unsigned int getAd(unsigned char channel)
& && && & ADC_CONTR=0x88|& & //开启AD转换 即POWER SPEED1 SPEED0 ADC_FLAG& &ADC_START CHS2 CHS1 CHS0
& && && & _nop_();
& & _nop_();
& & _nop_();
& & _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器& && && &
& && && & while(!(ADC_CONTR&0x10));& & //等待转换完成
& && &&&ADC_CONTR&=0xe7;& && &//关闭AD转换,ADC_FLAG位由软件清0
& && && & return(ADC_RES*4+ADC_RESL);& &//返回AD转换完成的10位数据(16进制)
其中我省略了1602显示的函数,那几个子函数没有问题的。 每次给单片机上电,P1口滞空,1602就会显示一个值,但是当采集电压的时候,显示的值又不会改变。
满意回复+20
这个是我用在STC15W404AS上的一个AD读取函数,输入是P11口,晶振6MHZ。在STC15F204EA上也使用过。
uint GetADCResult(void)
ADC_CONT ...
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
我使用的是STC12C5A60S2
主题帖子积分
高级工程师, 积分 7212, 距离下一级还需 788 积分
高级工程师, 积分 7212, 距离下一级还需 788 积分
主题帖子积分
专家等级:结帖率:14%
主题帖子积分
高级工程师, 积分 7212, 距离下一级还需 788 积分
高级工程师, 积分 7212, 距离下一级还需 788 积分
请检查硬件电路,再使用官网的AD例程试试,一定可以。
---人活着就是要改变世界!
----51单片机,单片机中的拖拉机!
主题帖子积分
资深技术员, 积分 330, 距离下一级还需 170 积分
资深技术员, 积分 330, 距离下一级还需 170 积分
主题帖子积分
专家等级:结帖率:50%
主题帖子积分
资深技术员, 积分 330, 距离下一级还需 170 积分
资深技术员, 积分 330, 距离下一级还需 170 积分
本帖最后由 qq 于
17:17 编辑
这个是我用在STC15W404AS上的一个AD读取函数,输入是P11口,晶振6MHZ。在STC15F204EA上也使用过。
uint GetADCResult(void)
& & uint AD_
& & ADC_CONTR=0xC1;& &//开AD电源,设置转换周期为180个时钟,设置P11为ADC通道& && && && && && && &
& & ADC_RES=0x00;& && &&&//高8位清零& &&&
& & ADC_RESL=0x00;& && &//低2位清零
& & _nop_();& && && && && && && &//需要加入几个空操作指令以做延迟
& & _nop_();
& & _nop_();
& & _nop_();
& & ADC_CONTR|=0x9;& && && && && && && && && && && &&&//启动AD转换
& & while ((0x10&ADC_CONTR)!=0x10);& && && & //等待转换完成&&
& & AD_result=(ADC_RES&&2)|(ADC_RESL&0x03);& &//合并高低位数据
& & ADC_CONTR&=0xE7;& && && && && & //清零ADC_FLAG标志位
& & //AD_result=254;& && && && && &//赋值一个固定的数用于检查数码管显示是否正常
& & return& &AD_& && && && & //返回10bit数据
& & 建议给返回值设一个随机的数,用于检查LCD是否能正常显示,再检查AD函数。
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
这个是我用在STC15W404AS上的一个AD读取函数,输入是P11口,晶振6MHZ。在STC15F204EA上也使用过。
uint Get ...
嗯,谢谢,我试试
我想问下 返回值的小数部分该怎么实现显示呢?
主题帖子积分
主题帖子积分
专家等级:结帖率:96%打赏:0.30受赏:91.00
主题帖子积分
wojfsdj 发表于
嗯,谢谢,我试试
我想问下 返回值的小数部分该怎么实现显示呢?
用浮点数类型去计算就可以了。。。
天降大任于斯国也,必先霾其头,灰其脸,黄其皮肤,自一头雾水而出,方知其堪当大任也!
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
ningling_21 发表于
用浮点数类型去计算就可以了。。。
是AD函数就用float吗? 然后就是返回浮点数,再去一个数字一个数字的取?
主题帖子积分
资深工程师, 积分 10580, 距离下一级还需 9420 积分
资深工程师, 积分 10580, 距离下一级还需 9420 积分
主题帖子积分
专家等级:结帖率:100%打赏:0.00受赏:0.10
主题帖子积分
资深工程师, 积分 10580, 距离下一级还需 9420 积分
资深工程师, 积分 10580, 距离下一级还需 9420 积分
也可以用定点计算。
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
coody 发表于
也可以用定点计算。
怎么定点计算呢?&&谢谢
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
这个是我用在STC15W404AS上的一个AD读取函数,输入是P11口,晶振6MHZ。在STC15F204EA上也使用过。
uint Get ...
我显示部分没有问题。
我将P1.1接地会显示000,接5V时,显示 :23&&,接3.3V 显示就是没规律变化的
主题帖子积分
主题帖子积分
专家等级:结帖率:96%打赏:0.30受赏:91.00
主题帖子积分
wojfsdj 发表于
是AD函数就用float吗? 然后就是返回浮点数,再去一个数字一个数字的取?
只是用浮点数计算,返回整型就可以了,例如:返回256,就代表25.6
天降大任于斯国也,必先霾其头,灰其脸,黄其皮肤,自一头雾水而出,方知其堪当大任也!
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
ningling_21 发表于
只是用浮点数计算,返回整型就可以了,例如:返回256,就代表25.6
哦哦,谢谢。
我先测5V的显示的是1023,但是测3.3V的时候就是一直变化的,我该怎么处理呢?
主题帖子积分
主题帖子积分
专家等级:结帖率:96%打赏:0.30受赏:91.00
主题帖子积分
wojfsdj 发表于
哦哦,谢谢。
我先测5V的显示的是1023,但是测3.3V的时候就是一直变化的,我该怎么处理呢? ...
数字滤波处理后,再计算...
天降大任于斯国也,必先霾其头,灰其脸,黄其皮肤,自一头雾水而出,方知其堪当大任也!
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
主题帖子积分
专家等级:结帖率:60%
主题帖子积分
初级技术员, 积分 84, 距离下一级还需 16 积分
初级技术员, 积分 84, 距离下一级还需 16 积分
ningling_21 发表于
数字滤波处理后,再计算...
我用ADC0804直接测量就不会这么跳,但是用STC12自带的就变化范围比较大。
您说的数字滤波处理是怎么弄呢?
主题帖子积分
主题帖子积分
专家等级:结帖率:96%打赏:0.30受赏:91.00
主题帖子积分
wojfsdj 发表于
我用ADC0804直接测量就不会这么跳,但是用STC12自带的就变化范围比较大。
您说的数字滤波处理是怎么弄呢 ...
看看匠人手记里面有篇文章的...
天降大任于斯国也,必先霾其头,灰其脸,黄其皮肤,自一头雾水而出,方知其堪当大任也!
主题帖子积分
初级工程师, 积分 2700, 距离下一级还需 300 积分
初级工程师, 积分 2700, 距离下一级还需 300 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级工程师, 积分 2700, 距离下一级还需 300 积分
初级工程师, 积分 2700, 距离下一级还需 300 积分
wojfsdj 发表于
我用ADC0804直接测量就不会这么跳,但是用STC12自带的就变化范围比较大。
您说的数字滤波处理是怎么弄呢 ...
看这里看这里:/blog-.html
主题帖子积分
资深技术员, 积分 328, 距离下一级还需 172 积分
资深技术员, 积分 328, 距离下一级还需 172 积分
主题帖子积分
专家等级:结帖率:80%
主题帖子积分
资深技术员, 积分 328, 距离下一级还需 172 积分
资深技术员, 积分 328, 距离下一级还需 172 积分
这个肯定可以的,我做过4通道的
主题帖子积分
资深技术员, 积分 409, 距离下一级还需 91 积分
资深技术员, 积分 409, 距离下一级还需 91 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
资深技术员, 积分 409, 距离下一级还需 91 积分
资深技术员, 积分 409, 距离下一级还需 91 积分
看了 但是不知道啊
技术新星奖章
人才类勋章
无冕之王奖章
等级类勋章
奔腾之江水
发帖类勋章
时间类勋章
技术导师奖章
人才类勋章
坚毅之洋流
发帖类勋章
核心会员奖章
等级类勋章
技术领袖奖章
人才类勋章
精英会员奖章
等级类勋章
时间类勋章
湍急之河流
发帖类勋章
技术奇才奖章
人才类勋章
精华达人奖章
等级类勋章
时间类勋章
涓涓之细流
发帖类勋章
热门推荐 /3我快被stc12c5a60s的ad转换虐疯了就是不能正常使用 - 单片机论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
我快被stc12c5a60s的ad转换虐疯了就是不能正常使用
10:09:11  
我是一个自学stc单片机的一开始使用的at公司的89s51后来发现资源可以用的太少了。就开始接触stc的找了一个名气最大的STC12C5A60S串口什么的都一个个被我攻克了。现在遇到一个最大的问题。就是芯片原带的ad转换功能,我几乎是把官网的源代码一个字一个字的抄下了的,结果通过串口输出,但是就是数据不正常。我在要测试的接口上接上电位器,可是结果要么就是最大也就是ff,要么就是最小00我来回检查还几遍也不知道哪里出了问题求高手解决这到底是怎么回事,(注意我主要使用P17口。其他都是悬空的)这是代码
#include&reg51.h&
#include&intrins.h&
#define FOSC L& &//
#define BAUD 9600& & & & & & & &&&//
typedef unsigned char BYTE;//
typedef unsigned int WORD;& & & & //
sfr ADC_CONTR=0xBC;//定义ad转换电源,周期,标致,开启,转换口,数据存储位置
sfr ADC_RES=0xBD;&&// 定义转换完毕数据高高八位数据位置
sfr ADC_LOW2=0xBE;&&//定义转换完毕的低八位数据存放位置
sfr PIASF=0x9D;&&//定义ad转换的总开关位置
#define ADC_POWER& & 0X80&&//
#define ADC_FLAG& &&&0X10&&//
#define ADC_START& & 0X08&&//
#define ADC_SPEEDLL&&0X00&&//主要用来设置转换周期540周期
#define ADC_SEEDL& & 0X20&&// 360周期
#define ADC_SEEDH& & 0X40&&// 180周期
#define ADC_SPEEDHH&&0X60&&// 90个周期
void InitUart();& & & & & & & && &//这个函数主要是用来设置串口的
void Delay(WORD n);&&//这个函数用来延时使用
void SendData(BYTE dat); //这个函数主要用来把就收到的数据通过串口发送出去
void InitADC();& & & & & & & & & & & & // 这个函数为了设置ad转换 电源,周期,标致,开启喂,io等设置
BYTE ch=0;& && && && & //ch主要是为了用于控制那个ad选为下一个转换口
void Delay900ms();
void main()& &// 主函数开始
&&InitUart();&&// 设置串口函数
&&InitADC();& &//& & & & 开始转换函数 .ad转换使用的是中断方式。所以还有一个中断处理函数
&&IE=0XA0;
& & & && & //
&&while(1)
&&void adc_isr() interrupt 5 using 1&&//stc12ad转换中断例程
& &ADC_CONTR&=!ADC_FLAG;//将ad转换完成标志致0. 此位与相与得到的结果会是除了第4位是0其他为让保持原来的数据
& & P2=~P2;
& & P0=~P0;
& & SendData(ch);& && & //将正在转换的ad输入口的名字牌号通过串口输出
& & & & SendData(ADC_RES);&&// 将数据高八位输出通过串口
& & & & SendData(ADC_LOW2); //将数据的低8位通过串口输出
& &&&ch++;
& & & & if(ch&8)
& & & & ch=0;& &//将开启下一个ad转换口
& & Delay900ms(); & & & && &&&//降低转换速度延迟函数
& & & & ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|&&//将最高位的ad转换电源打开。设置波特率,开启转换,设置转换口
& &//=================================================
& &void InitADC()
& & PIASF=0XFF;& && && && && && && && && && && && & //把p1口全部设为ad转换
& & & & ADC_RES=0;& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & && & //把以前的转换结果清零
& & & & ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START| //将最高位的ad转换电源打开。设置波特率,开启转换,设置转换口
& & & & Delay(2);& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&&//适当的延时
& & & & //========================================================
& & & & void InitUart()& & & &&&//初始化函数串口
& & & && && && & SCON=0X5A;
& & & & & & & & & & & &&&TMOD=0X20;
& & & & & & & & & & & &&&TH1=TL1=0XFD;
& & & & & & & & & & & &&&TR1=1;
& & & &&&}
& & & &&&//===========================================
& & & &&&void SendData(BYTE dat)//通过串口把测量的数据发送出去
& & & &&&{
& & & && &while(!TI);
& & & && &TI=0;
& & & && &SBUF=
& & & && &}
&&//====================================================
& & & && &void Delay(WORD n)//延时函数
& & & && &{
& & & && & WORD
& & & && & while(n--)
& & & && & {
& & & && &&&x=5000;
& & & & & & & & while(x--);& &
& & & && &&&}& &
& & & && & }
//==========================================
void Delay900ms()& & & & & & & & //@11.0592MHz& & & && &//这个函数我自己用来降低转换速度的因为ad转换太快了为了观察方便我这个降低速度。大概一秒转换一个ad口。
& & & & unsigned char i, j,
& & & & _nop_();
& & & & _nop_();
& & & & i = 22;
& & & & j = 3;
& & & & k = 227;
& & & & do
& & & & & & & & do
& & & & & & & & {
& & & & & & & & & & & & while (--k);
& & & & & & & & } while (--j);
& & & & } while (--i);
11:07:13  
先转换一个通道试试加滤波电容,如果电阻太大可以加一级运算放大
22:33:03  
先不要用中断法,用查询法试试。一般开启STC的AD转换有两大前提步骤
1.将相应端口设置为高阻态
2.将该端口设置为AD通道
看看你的程序有没有做这两步先
14:07:44  
给你提供一段源程序仅供参考
&&P1M1=0x0c;& & & & //仅ADC2/P12和ADC3/P13高阻输入
&&P1M0=0x00;& & & & //注意CCP1/P10和CCP0/P11不能为高阻输入
&&P1ASF=0x0c;& & & & //ADC2及ADC3为A/D转换通道
&&ADC_CONTR=0xc0;& & & & //ADC上电,180时钟/次,选通ADC0,但AD未启动
&&delay_ms(1);& & & & //延时1ms,等ADC上电稳定
&&CLK_DIV=0;& & & & //实际维持复位初值,其中d5/ADRJ位决定ADC结果格式
&&& & & & & & & & //令ADRJ=0则ADC_RES[7:0]存结果高8位,ADC_RESL[1:0]存结果低2位
//选中通道进行10位ADC转换
#pragma disable
void req_adc(uchar adch)& & & & //请求adc服务
{ ADC_CONTR=0xc8|& & & & //180T/次,10位精度,选通adch通道,启动A/D
&&_nop_();& & & & & & & & & & & & //至少延时4个时钟方能看到ADC_CONTR的变化
&&_nop_();
&&_nop_();
&&_nop_();
&&while(!(ADC_CONTR&0x10));& & & & //检查A/D转换结束标志
&&ADC_CONTR=0xc0|& & & & //停止A/D并清转换结束标志
&&adh=ADC_RES;& & & & & & & & //读高8位转换结果
&&adl=ADC_RESL;& & & & & & & & //读低8位转换结果
18:38:20  
精神可嘉& &不过我也是初学者&&可能是帮不上啥忙了& & 我也对这块单片机表示难以弄懂
12:14:02  
可能是硬件有问题,信号内阻5——10K,是吗
17:20:52  
顶& && && && && && && && && && && && && && && && &&&
助理工程师
13:55:52  
也在研究这个事情希望楼主能早日解决,这两天我也会以及把我做这个的心得和楼主分享交流的
23:41:46  
解决了吗?我可以帮忙哦!
15:07:53  
楼主。。解决了吗
15:09:07  
解决了吗?我可以帮忙哦!
哥。求帮忙。我也是这问题
09:53:24  
本帖最后由 无量寿经 于
09:57 编辑
以下内容来源于《51单片机轻松入门-基于STC15W4K系列》,可直接用于STC12系列,对于STC12系列,可设置IO口高阻模式或开漏模式有利于提高精度,STC15系列无需设置IO口模式。
(26.04 KB, 下载次数: 12)
09:56 上传
点击文件名下载附件
下载积分: 积分 -1 分
#include&STC12C5A.h&& & //包含STC12C5A60S2单片机寄存器定义文件例9-1&&IAP15W4K58S4单片机A/D转换程序,查询方式,测量结果电压值发送到计算机串口助手显示,波特率4MHz,电路如图1-13所示。当使用配套实验板时,需要将跳线帽“AD/串口2”插接到AD处。#include&UART.H&& && && & // 包含IAP15W4K58S4寄存器定义文件 #define VCC 4.970& && && & // 存放用万用表实测的单片机供电电压unsigned int ADC_P11(){& && && && &// 用于软件延时程序& & & &// 用于判断A/D转换结束的标志& & unsigned int AD_Dat=0;&&//10位A/D转换值& & unsigned char T& && &// 临时变量用于将A/D转换出来的2个字节合成一个字节& &&&& & ADC_CONTR|=0x80;& && &&&// 开ADC转换器电源,第一次使用时要打开内部模拟电源& & for (i=0;i&10000;i++);&&// 适当延时等待ADC转换供电稳定,一般延时1ms以内即可,为了缩短& && && && && && && && && & // A/D调用时间,可把这2行剪切到主程序中去。& & P1ASF|=0x02;& && && && &// 选择P1.1作为ADC转换通道,0x02= & && & ADC_CONTR=0xE1;& && && &// 选择P1.1作为ADC转换通道,最高转换速度,清转换完成标志。& & for (i=0;i&1000;i++);&&// 如果是多通道模拟量进行A/D转换,则更换A/D转换通道后要适当延时,// 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内// 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换A/D转换通道,也不需要加延时。& & ADC_CONTR|=0x08;& && &&&// 启动 A/D 转换,ADC_START=1。& & status=0;& & while(status==0)& && &&&// 等待A/D转换结束。& & {& && & status=ADC_CONTR&0x10;& &// 判断ADC_FLAG是否等于1,0x10=B。& & }& & ADC_CONTR&=0xE7;& && &&&// 将ADC_FLAG清0, 0xE7=B,ADC_FLAG=0,ADC_START=0。&&& & AD_Dat = ADC_RES;& && & // 默认高字节高8位。& & AD_Dat &&= 2;& & Tmp = ADC_RESL;& && && &// 默认低字节低2位。& & Tmp &= 0x03;& && && && &// 屏蔽无关位& & AD_Dat |= T& && && & // 高低字节拼接成一个10位数。& & return AD_D}&&void main(void){& && & float V& && && && && && && &// 存放计算出来的外部输入电压& & unsigned int AD& && && & // 存放A/D转换返回的结果& & UART_init();& && && && && && & // 串口初始化4MHz& & printf(&串口初始化完毕&);& & while(1)& & {& && && &&&& && &&&ADvalue=ADC_P11();& && && &// 采样P1.1口模拟输入电压& && &&&Vin=VCC*ADvalue/1023;& &&&// 注意是1023才正确& && &&&printf(&%.3f& & &,Vin);& && &&&& && &&&delay500ms();& & }& && && && && && && && && &&&// 若不用串口显示,此行可设置断点仿真观察结果}实验测试数据如表9-5所示,表中的“参考基准电压”和“输入电压(V)”是使用四位半数字万用表VC86E测量获得的结果, ADC的输入信号是来自10K的可调电位器。& && && && && && && && & 表9-5&&单片机内部ADC实验结果数据表&&参考基准电压&&输入电压(V)串口助手显示电压(V)相对误差<font color="#.970<font color="#.000<font color="#.005<font color="#.005/4.970×100% = 0.1%<font color="#.000<font color="#.011<font color="#.011/4.970×100% = 0.2%<font color="#.000<font color="#.011<font color="#.011/4.970×100% = 0.2%<font color="#.000<font color="#.032<font color="#.032/4.970×100% = 0.6%<font color="#.000<font color="#.018<font color="#.018/4.970×100% = 0.4%<font color="#.970<font color="#.970<font color="#.000/4.970×100% = 0.0%
19:27:13  
发表于 4&天前  
昨天也被这块单片机的AD折腾好久,最后发现是手册里的代码有问题,ADC_CONTR&=!ADC_FLAG;把这一句改成ADC_CONTR&=~ADC_FLAG;就通了。这里其实是要把ADC_FLAG按位取反,而他是取逻辑非
Powered by

我要回帖

更多关于 stc12c5a60s2 的文章

 

随机推荐