各位大侠,问下stc12c5a60s2 的ad问题??
最近在用stc12c5a60s2做东西,可是用到它的ad是程序不知道怎么回事都不行、程序是根据datasheet写的,各位大侠帮忙看下哈//****************************************STC12C5A60S2 AD转换***********************************************//
#include"stc12c5a60s2.h" //头文件在STC公司主页上下载
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
#include "lcd1602.h"
/*****************************************************************
函数:delayms()
用途:延时xms
传人参数: xms是所需要延时的时间
******************************************************************/
void delayms(unsigned int x)
{
unsigned int y, z;
for(y=x; y>0; y--)
for(z=110; z>0; z--) ;
}
/*****************************************************************
函数: adInit()
用途: 初始化ad端口
******************************************************************/
void adInit(void)
{
P1ASF=0x07; //P1.0/P1.1/P1.2口全部作为模拟功能AD使用
ADC_RES=0; //清零转换结果寄存器高8位
ADC_RESL=0; //清零转换结果寄存器低2位
ADC_CONTR=0x80;//开启AD电源
delayms(1); //等待1ms,让AD电源稳定
}
//------------------------------------------------------------------------------
unsigned int getAd(unsigned char channel)
{
ADC_CONTR=0x88|channel; //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0
_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
// ADC_RES=0xdf;
// ADC_RESL=0xef;
while(!(ADC_CONTR&0x10)); //等待转换完成
ADC_CONTR&=0xe7; //关闭AD转换,ADC_FLAG位由软件清0
return(ADC_RES*4+ADC_RESL); //返回AD转换完成的10位数据(16进制)
}
/*****************************************************************
函数: averageValueVolgate()
用途: 求多次采集电压平均值
传入参数:chan是端口号
返回值:Val_Av是多次采样的电压值平均值
******************************************************************/
float averageValueVolgate(uchar chan)
{
float voltageValue=0;
uchar num;
for(num=100;num>0;num--)
{
voltageValue+=getAd(chan);
}
voltageValue/=100.0;
voltageValue=voltageValue*5.0/1024;
return (voltageValue);
}
/***********************************************************************
主函数
***********************************************************************/
void main()
{
adInit();
lcdInit();
display(0,averageValueVolgate(0));
while(1);
}
/**********************************************************************************
下面是lcd1602的程序可以用
**********************************************************************************/
sbit rs=P3^5;
sbit lcden=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code table[]="0123456789";
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
void write_com(uchar com)
{
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void write_data(uchar date)
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void lcdInit()
{
dula=0;
wela=0;
write_com(0x38);
delay(20);
write_com(0x0f);
delay(20);
write_com(0x06);
delay(20);
write_com(0x01);
delay(20);
}
void display(uchar ch,float vol)
{
int temp = (int)(vol*10);
if(ch==0)
write_com(0x80);
else if(ch==1)
write_com(0x80+8);
else if(ch==2)
write_com(0x80+0x40);
write_data(table);
write_data(':');
write_data(' ');
write_data(table);
write_data(table);
write_data('.');
write_data(table);
}
液晶那块能用,就是我下进去后,显示一个数,关掉电源再打开变另一个了,而且跟输入电压都不一样,这是为什么呢???
ADC_CONTR&=0xe7; //不建議這樣停止,我之前就是用這樣,結果轉換到第二通道時,得到的結果三個通道都一樣,因為這樣會同時打開0,1,2三個通道,后來改為ADC_CONTR&=0x00;就每個通道都正常了.
return(ADC_RES*4+ADC_RESL); //這里不對吧,RES是存放高8位數據,RESL是存放低2位數據,應該是設一個變量uint Temp, 現后return Temp<<2+ADC_RESL 這里我用的是15F204EA,我不太清楚你用的這個型號是否不同,你查一下規格書.
liweiqiang668 发表于 2012-5-9 19:58 static/image/common/back.gif
ADC_CONTR&=0xe7; //不建議這樣停止,我之前就是用這樣,結果轉換到第二通道時,得到的結果三個 ...
ADC_RES*4就相当于ADC_RES<<2,,这样应该没问题,把上面那句改了还是一样的问题、、没给io口电压都会显示值、、正常应该为0啊,万用表测也是零,不知道为什么还会显示出来,而且每次关掉打开都在变化 悬空AD输入脚就会这样,
如果想悬空时也输出0,接个2M左右的电阻到地,电阻并联10nF左右的瓷片电容,
具体请看此帖的11楼电路图:STC15F204EA简易电压表
原来是在单片机上,被别的元器件影响了,换到最小系统板上就可以了、、累啊
页:
[1]