打印

STM8 AD值读不准?不知道是什么原因

[复制链接]
9082|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiangfeizi|  楼主 | 2010-10-14 08:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机 STM8S903K3
本人采用单次扫描模式,可以读的到AD值的变化,但是AD值不准
具体来说,测量到AD口的电压为0.65V 理论计算AD值应该为133,但是程序运行中AD转化器读的AD值是46。差别太大了。
程序如下,请大侠们指点问题出在哪?

AD转换程序
void ad_equel_value(void)
{
   uchar a,x,n,m,y;
  ADC_CR1|=0x01;唤醒AD转换器
  ADC_CR2=0X0a;//使能扫描模式,A/D转换为单次扫描模式,数据为右对齐方式。
  ADC_CSR=0X86;//将AD转换结束状态标志清零,且扫描通道为0~6
  ADC_CR1|=0X01;//启动A/D转换器  启动后14个机器周期读AD转换的值
   
  for(a=0;a>=30;a++)//延迟30个机器周期后再读AD值
  {}
  nn++;
   if(nn<60)//计数60次,确定60秒标志,标志置位才求平均值
   {
    flag_1ms=0;//清零1ms标志
      {
       addata_ch_h[0]=ADC_DB0RH;//循环读取 AD0通道的 高位数据
        addata_ch_l[0]=ADC_DB0RL;//循环读取 AD0通道的 低位数据
     addata_ch_h[1]=ADC_DB1RH;//循环读取 AD1通道的 高位数据
        addata_ch_l[1]=ADC_DB1RL;//循环读取 AD1通道的 低位数据
     addata_ch_h[2]=ADC_DB2RH;//循环读取 AD2通道的 高位数据
        addata_ch_l[2]=ADC_DB2RL;//循环读取 AD2通道的 低位数据
     addata_ch_h[3]=ADC_DB3RH;//循环读取 AD3通道的 高位数据
        addata_ch_l[3]=ADC_DB3RL;//循环读取 AD3通道的 低位数据
     addata_ch_h[4]=ADC_DB4RH;//循环读取 AD4通道的 高位数据
        addata_ch_l[4]=ADC_DB4RL;//循环读取 AD4通道的 低位数据
     addata_ch_h[5]=ADC_DB5RH;//循环读取 AD5通道的 高位数据
        addata_ch_l[5]=ADC_DB5RL;//循环读取 AD5通道的 低位数据
     addata_ch_h[6]=ADC_DB6RH;//循环读取 AD6通道的 高位数据
        addata_ch_l[6]=ADC_DB6RL;//循环读取 AD6通道的 低位数据
     }
   for(m=0;m<=6;m++)
     {
    addata_add_ch[m]=addata_add_ch[m]+addata_ch_h[m]*4+addata_ch_l[m]; //AD各通道AD值循环累加
     }
   }
   else//计数60次后求平均值
   {
     nn=0;
    ADC_CR1&=0xfe;//关断AD转换器
    flag_1ms=0;
    for(y=0;y<=6;y++)
    {
     addata_divide_ch[y]=addata_add_ch[y]/60;// 累加值除60得平均值整数部分
       addata_yushu_ch[y]=addata_add_ch[y]%60;//求余数
     if(addata_yushu_ch[y]>=30) //四舍五入
      {
       addata_equel_ch[y]=addata_divide_ch[y]+1;
     }
     else
      {
       addata_equel_ch[y]=addata_divide_ch[y];
     }
      addata_add_ch[y]=0; //将累加的AD值的和清0,准备下一  次AD值的累加
     }
    }
}

主程序:
main()
{
  _asm("sim");  
  clock_inti();
  io_inti();
_asm("rim");
timer6_50us();
   while(1)
   {
   time_flag();
   if(flag_1ms==1)
   {
     ad_equel_value();
    if((addata_equel_ch[4]>50)&&(addata_equel_ch[4]<160))
    {
    BEEP_CSR=0X22;
    }
    else
    {
    PC_ODR|=0x80;
    }
   }
  

  }

}

将门槛设为50点就是点亮灯了,蜂鸣器不叫,郁闷!
沙发
IJK| | 2010-10-14 09:42 | 只看该作者
据说STM8S的AD是很准的,建议LZ自己查查,比如,是否累加环节出错,以及阻抗匹配的问题。

还有,这样是错误的:
for(a=0;a>=30;a++)//延迟30个机器周期后再读AD值

使用特权

评论回复
板凳
xiangfeizi|  楼主 | 2010-10-14 13:40 | 只看该作者
现在还没到累加环节,直接仿真看寄存器的值就是对不上的。阻抗匹配怎么说,是输入设置的问题吗?

使用特权

评论回复
地板
xiangfeizi|  楼主 | 2010-10-14 13:42 | 只看该作者
现在在AD口线出接了个104的滤波电容后,误差明显的放小了很多,在电压值比较小的时候AD比较准,电压值越大,误差越大,最大的误差有25左右,精度还是不够。

使用特权

评论回复
5
IJK| | 2010-10-14 13:43 | 只看该作者
阻抗匹配:MCU的AD的输入阻抗(所需的分辨率下,随分辨率会不同) 应该大于 信号源的输出阻抗

使用特权

评论回复
6
xiangfeizi|  楼主 | 2010-10-14 15:37 | 只看该作者
呵呵 好象真是和阻抗有关系,可调电阻为1K,分压电阻100欧。原来是通过一个4.7K的电阻接入到AD口,AD设置为悬浮输入,读树不准。现在将4.7K的电阻调成510欧,误差最大为3,应该算比较准确的了吧!
多谢指教哈!

使用特权

评论回复
7
jia963801482| | 2011-5-13 12:36 | 只看该作者
stm8s的分辨率为1/1024,若vcc=5v,则分辨率为5mv

使用特权

评论回复
8
ye955| | 2011-5-19 08:38 | 只看该作者
你的程序这么复杂的?我在用的方法是:5V下来接5K热敏电阻,再串个5.1K下地。中点并个104后接端口。读起来温度值非常准!

/*AD转换程序*/
void AD()
{ uint value;
   ADC_CSR = 0x02;    //配置模拟量输入端口
   ADC_CR1 = 0x01;    //开启AD转换
   ADC_CSR &= ~0x80;  // 清除EOC转换结束标志
   ADC_CR1 |= 0x01;   // 开始单次转换
   
   while(!(ADC_CSR&0x80));    // 等待单次转换完成(完成后扫行下面程序)
   
   value = ((int)ADC_DRH<<2); // 先读高8位,默认设置数据左对齐
   value |= ADC_DRL;          // 再读低8位
   value=value>>2;
   TC= AdTab[(value-68)/1];  //测出来的AD值进行反查表,让数码管显示出当前室温
}

使用特权

评论回复
9
yinyangdianzi| | 2011-5-19 13:42 | 只看该作者
学习了。。。。想LZ看齐

使用特权

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

本版积分规则

12

主题

62

帖子

0

粉丝