squn 发表于 2012-5-9 17:16:30

各位大侠,问下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);
}


液晶那块能用,就是我下进去后,显示一个数,关掉电源再打开变另一个了,而且跟输入电压都不一样,这是为什么呢???

liweiqiang668 发表于 2012-5-9 19:58:51


      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,我不太清楚你用的這個型號是否不同,你查一下規格書.

squn 发表于 2012-5-9 20:24:35

liweiqiang668 发表于 2012-5-9 19:58 static/image/common/back.gif
ADC_CONTR&=0xe7;      //不建議這樣停止,我之前就是用這樣,結果轉換到第二通道時,得到的結果三個 ...

ADC_RES*4就相当于ADC_RES<<2,,这样应该没问题,把上面那句改了还是一样的问题、、没给io口电压都会显示值、、正常应该为0啊,万用表测也是零,不知道为什么还会显示出来,而且每次关掉打开都在变化

BXAK 发表于 2012-5-9 20:45:08

悬空AD输入脚就会这样,
如果想悬空时也输出0,接个2M左右的电阻到地,电阻并联10nF左右的瓷片电容,
具体请看此帖的11楼电路图:STC15F204EA简易电压表

squn 发表于 2012-5-9 21:07:28

原来是在单片机上,被别的元器件影响了,换到最小系统板上就可以了、、累啊
页: [1]
查看完整版本: 各位大侠,问下stc12c5a60s2 的ad问题??