打印

PIC16F877A 双通道AD转换问题

[复制链接]
4105|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangyiyun_1986|  楼主 | 2010-3-13 11:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为何我的转换输出结果会不正确,请帮忙看一看,谢谢,而且连续转换5次再求平均值做为转换结果和连续转换4再求平均值做为转换结果输出的也不一样

//实验目的:熟悉A/D转换
//软件思路:选择RA0做为模拟输入通道;
//          结果只取低8位
//          连续转换5次再求平均值做为转换结果
//          结果送数码管的高低3位显示
//硬件要求:跳线J18接通
//          拨码开关S6全部置ON,S5第4-6位置ON,第1-3位置OFF
//          为不影响结果,其他拨码开关置OFF。
#include<pic.h>              //包含单片机内部资源预定义
__CONFIG(0x1832);        
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
const char TABLE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0X82,0XF8,0X80,0X90};
//定义常数0-9的数据表格
unsigned int ADResult[2],Result;
unsigned char dis_index;
static bit bUpdateDisplay ;
// void ADReadFunc(uchar channel);
             //I/O口初始化函数申明
void  display(int x);       //显示函数申明
union ADData {  unsigned int ADTemp; unsigned char ADBuffer[2]; }ADunion;
unsigned int itime=0,flag=0; /*定时器1中断计数*/
void  DELAY();              //delay函数申明
void  init();               //I/O口初始化函数申明
void  display(int x);       //显示函数申明
void delay()
{ unsigned int j;
for(j=200;--j;);
}
void  DELAY()              //延时程序
    {
     int i;                 //定义整形变量
     for(i=0x100;i--;);     //延时
    }
//初始化函数
void  init()               
  {
   PORTA=0XFF;               
   PORTD=0XFF;               //熄灭所有显示
   TRISA=0X03;                //设置RA0\RA1为输入,其他为输出            
   TRISD=0X00;               //设置D口全为输出
   ADCON1=0X80;              //转换结果左对齐,RA0做模拟输入口,其它做普通I/O
   //ADCON0=0X41;              //系统时钟Fosc/8,选择RA0通道,允许ADC工作
    ADResult[0]=0;
   ADResult[1]=0;
   DELAY();                  //保证采样延时
   }
void display(int x)         
   {
     int  bai,shi,ge,temp;   //定义4个临时变量
     temp=x;                 //暂存AD转换的结果
     bai=temp/0x64;          //求显示的百位
     shi=(temp%0x64)/0xa;    //求显示的十位
     ge=(temp%0x64)%0xa;     //求显示的个位
     PORTD=TABLE[bai];       //查表得百位显示的代码
     PORTA=0x1f;             //RA3输出低电平,点亮百位显示
     DELAY();                //延时一定时间,保证显示亮度
     PORTD=TABLE[shi];       //查表得十位显示的代码
     PORTA=0x2F;             //RA4输出低电平,点亮十位显示
     DELAY();                //延时一定时间,保证亮度
     PORTD=TABLE[ge];        //求个位显示的代码
     PORTA=0x37;             //RA5输出低电平,点亮个位显示
     DELAY();                //延时一定时间,保证亮度
   }
void  init_timer1()
{
  TMR1IF=0;
  TMR1H=0XF8;  //
  TMR1L=0X2F;  //  //定时器赋初值(2ms/一周期1us)
  T1CON=0x00;  //开启定时器1,定时模式1分频
  TMR1IE=1;   //开启定时器1中断
  PEIE=1;
  TMR1ON=1;
  GIE=1;
  
}
//中断函数
void interrupt timer1(void)
{
    TMR1ON=0;
    TMR1IF = 0; //清除TMR1 中断标志
    itime++;
    if((itime>=1000)&&(itime<2000))//定时1sdis_index
    {
     Result=ADResult[1];//ra1 ad转换结果数据刷新显示2
     
    }
    else if(2000==itime)
     itime=0;
   
   else
      {Result=ADResult[0];//Result=ADResult[0]//ra0 ad转换结果数据刷新显示2
            
      }
    //itime=0;
    TMR1H=0xF8;
  
    TMR1L=0x2F;
    bUpdateDisplay=1;
    TMR1ON=1;
  }
//读AD值
void ADReadFunc(unsigned char channel)
{
  int i;                    //定义循环次数控制寄存器
  ADCON0=(channel<<3)|0x41; //fosc/8
  delay();
  for(i=5;i>0;i--)          //求4次转换结果的平均值
  {ADGO=1;
    while(ADGO);
    ADunion.ADBuffer[0]=ADRESL;
    ADunion.ADBuffer[1]=ADRESH;
    ADResult[channel]=ADunion.ADTemp=ADRESH*256+ADRESL;
    ADResult[channel]=ADResult[channel]+ADunion.ADTemp;
   }
   ADResult[channel]=ADResult[channel]/5;       //求5次结果的平均值
   //Result=ADResult[channel];
   //display(ADResult[channel]);        //调用显示函数
}
void  main()               
{
  init_timer1();
  init();
  dis_index = 0;
  while(1)                  //死循环
  {
   ADReadFunc(0);//ra0 ad转换
   delay();
   ADReadFunc(1);  //ra1 ad转换
   delay();//新加

   if(bUpdateDisplay)
      {
       bUpdateDisplay=0;
       display(Result);        //调用显示函数
      }
  }
}
沙发
xxxx7| | 2010-8-19 19:02 | 只看该作者
结果只取低8位..

ADCON1=0X80;              //转换结果左对齐,RA0做模拟输入口,其它做普通I/O

ADResult[channel]=ADunion.ADTemp=ADRESH*256+ADRESL;

明明是10位嘛!!
for(i=5;i>0;i--)          //求4次转换结果的平均值
  {ADGO=1;
    while(ADGO);
    ADunion.ADBuffer[0]=ADRESL;
    ADunion.ADBuffer[1]=ADRESH;
    ADResult[channel]=ADunion.ADTemp=ADRESH*256+ADRESL;
    ADResult[channel]=ADResult[channel]+ADunion.ADTemp;
   }
   ADResult[channel]=ADResult[channel]/5;       //求5次结果的平均值
   //Result=ADResult[channel];
   //display(ADResult[channel]);        //调用显示函数
}
必需保证最低的取样时间
你不加延时吗?

使用特权

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

本版积分规则

0

主题

1

帖子

1

粉丝