打印

5410AD串口,为啥自加m次得除m+1 AD值才正常

[复制链接]
1606|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
(1)直接输出AD值是对的。3.1V对应输出9D
(2)AD均值 for(m=0;m<5;m++)        应该自加5次的呀(m=0,1,2,3,4),但是除以5就是不对,3.1V输出C4(3.8V),大了,要除以6。
也试过m<10,还是C4        

/**********************************************************************************************
项目:5410AD AD转换发送给串口
功能:P1.0 AD采样后将值发送给串口
设计:robin_chen559
日期: 2013.12.18
备注:Fosc=11.0592M
**********************************************************************************************/
#include<STC12C5410AD.H>                        //包含头文件
#include <intrins.h>                                        //挂羊头,没啥用

#define uint unsigned int
#define uchar unsigned char


sbit LED_G = P1^6;                                                //指示LED
uint AD_Res=0;

//函数声明
void Delay_MS(uint delay);                                //延时函数声明
void AD_INIT(void);                                            //AD初始化  
float AD_Result(void);                      //AD结果程序

void  InitUart();                       //串口初始化程序
void  Sent_Data(uchar dat);             //串口发送数据

//毫秒延时程序
void Delay_MS(uint delay)
{
uint dy;
while(delay--)
{
for(dy=0;dy<600;dy++);
}
}

//AD初始化
void AD_INIT(void)
{
P1M0 = 0x01;                    // 0000 0001
P1M1 = 0xff;                                         //        1111 1111  P1^0  11开漏模式,AD使用。其余口推挽        
ADC_CONTR|=0x80;                //ADC_CONTR 1000 0000 开启ADC电源
Delay_MS(5);                    //延时1mS待上电稳定                                
}

//AD转换
float AD_Result(void)
{                                                            

uchar m;
ADC_DATA = 0x00;                                    //清除AD转换高8位结果
ADC_LOW2 = 0x00;                                    //清除AD转换低2位结果
for(m=0;m<5;m++)                                        //AD结果5次自加
{
ADC_CONTR |= 0x08;                             // 启动AD转换
Delay_MS(1);                       // 等待输入电压稳定
while(1)                                                    // 等待AD转换完成
{
  if( (ADC_CONTR&0x10) == 0x10 )    //AD_FLAG 为1,跳出循环
  {
   break ;
  }
}
  AD_Res = (AD_Res + ADC_DATA);         
  ADC_CONTR = 0xe0;                 // 清除转换标志位。关闭电源

  }
  AD_Res = AD_Res/6;                                //求5次AD结果均值
  return (AD_Res) ;                 //返回AD转换结果
}

//串口初始化程序
void InitUart()                     // 初始化,定义串口的波特率
{
     PCON = 0x00;                                        //SMOD =0,串口波特率正常
         TMOD = 0x20;                                        //定时器1,模式2,八位自动重装
     SCON = 0x42;                                        //5a,方式1,串行口10位异步通信
     TH1  = 0xFD;                                        //SMOD =0,fd=0xfd,9600波特率
     TL1  = 0xFD;
     TR1  = 1;                                                 //启动定时器
}

//串口数据传送
void  Sent_Data(uchar dat)
{
while (!TI);
TI=0;
SBUF=  AD_Res ;
}

//主程序
void main()
{
   AD_INIT() ;                                    //AD初始化
   InitUart() ;                                          //串口初始化

   while(1)
   {
           AD_Result();                      //AD处理程序
           Sent_Data();              //串口发送AD结果
           LED_G = 0;
           Delay_MS(300);
           LED_G = 1;
           Delay_MS(300);           
   }  
}
(3)自加m,除以m+1或直接输出高八位AD结果

(4)自加m次,除以m,AD值偏大



相关帖子

沙发
airwill| | 2013-12-18 12:59 | 只看该作者
这是算法疏忽

for(m=0;m<5;m++)                                        //AD结果5次自加
{
ADC_CONTR |= 0x08;                             // 启动AD转换
Delay_MS(1);                       // 等待输入电压稳定
while(1)                                                    // 等待AD转换完成
{
  if( (ADC_CONTR&0x10) == 0x10 )    //AD_FLAG 为1,跳出循环
  {
   break ;
  }
}
  AD_Res = (AD_Res + ADC_DATA);         
  ADC_CONTR = 0xe0;                 // 清除转换标志位。关闭电源

  }
  AD_Res = AD_Res/6;                                //求5次AD结果均值
  return (AD_Res) ;                 //返回AD转换结果
}

这里面, 在
for(m=0;m<5;m++)                                        //AD结果5次自加
之前没有清零 AD_Res 导致的.

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
robin_chen559 + 2 很给力!
板凳
ayb_ice| | 2013-12-18 14:55 | 只看该作者
累加之前清零没有

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
robin_chen559 + 2 很给力!
地板
coody| | 2013-12-18 17:49 | 只看该作者
按常规,这中情况下一般会骂STC的啊

使用特权

评论回复
5
robin_chen559|  楼主 | 2013-12-18 17:53 | 只看该作者
airwill 发表于 2013-12-18 12:59
这是算法疏忽

for(m=0;m

恩,的确是这么回事,再循环的时候相当于就多加了一次~~

使用特权

评论回复
6
robin_chen559|  楼主 | 2013-12-18 17:54 | 只看该作者
coody 发表于 2013-12-18 17:49
按常规,这中情况下一般会骂STC的啊

不是吧,应该是自己程序问题,不至于stc啥事的呀~~~

使用特权

评论回复
7
autopccopy| | 2013-12-18 20:10 | 只看该作者
本帖最后由 autopccopy 于 2013-12-18 20:25 编辑
robin_chen559 发表于 2013-12-18 17:54
不是吧,应该是自己程序问题,不至于stc啥事的呀~~~

有人号称在“富士糠”,连STC的ISP下载都没搞定,后来被踢了出来修LED灯箱了。;P;P;P

@coody 你懂的!:)

使用特权

评论回复
8
3htech| | 2013-12-18 21:25 | 只看该作者
请看下面两个算式
avre = 1;
avre ++;
avre  / 2 = 1;

再请看下面
sum = 0;
sum += aver
sum/1 = 1;

仔细看看。

使用特权

评论回复
9
ZG11211| | 2013-12-18 21:53 | 只看该作者
本帖最后由 ZG11211 于 2013-12-18 21:54 编辑

进来学习一下

使用特权

评论回复
10
robin_chen559|  楼主 | 2014-1-3 19:56 | 只看该作者
robin_chen559 发表于 2013-12-18 17:53
恩,的确是这么回事,再循环的时候相当于就多加了一次~~

怪不得之前做太阳能充电,uint结果总有偏差,用float除100次正常,除以100多加一次几乎看不出来了,还是程序结构没想好~~~~

使用特权

评论回复
11
robin_chen559|  楼主 | 2016-3-15 19:54 | 只看该作者
coody 发表于 2013-12-18 17:49
按常规,这中情况下一般会骂STC的啊

:$ 哪好意思涅~~~

使用特权

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

本版积分规则

22

主题

302

帖子

10

粉丝