找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3133|回复: 1
打印 上一主题 下一主题
收起左侧

STC8单片机的AD采样不稳,波动特别大

[复制链接]
回帖奖励 20 黑币 回复本帖可获得 1 黑币奖励! 每人限 5 次
跳转到指定楼层
楼主
ID:514692 发表于 2019-4-24 18:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
采样的波动特别大,电压采样后转换成0-500mm长度,波动的幅度可以达到5mm,这个正常吗?程序如下:
单片机源程序如下:
  1. #define N 12
  2. void ADC_Init(void)
  3. {
  4.          //配置P10口为高阻输入,作为ADC采样引脚
  5.          P1M0= 0X00;                     
  6.          P1M1= 0X01;

  7.          //使用定时器扫描结果
  8.          TMOD= 0x01;                //选择定时器T0 在工作方式1上 即16位定时器
  9.          TH0  = (65536-50000)/256;  //11.592M晶振的一个机器周期接近1us 这里5W就是0.05s
  10.          TL0  = (65536-50000)%256;
  11.          EA   = 1;                   //开启总中断
  12.          ET0  = 1;                   //开启定时器T0
  13.          TR0  = 1;   
  14. }

  15. /*************************************************************************
  16.                           ADC转换函数
  17.   输入:ADC通道0~14数字;      
  18.   输出:ADC转换值
  19. **************************************************************************/
  20. unsigned int ADC_Start(unsigned charChannel)
  21. {                                                                                                                                                                                                                                      
  22.          unsignedchar DIWEI,GAOWEI;                //A/D转换后换算的电压值
  23.          unsignedint trans_result,ADC_Data;

  24.          ADC_RES=0;
  25.          ADC_RESL=0;

  26.          ADC_CONTR  = ADC_POWER;                //打开ADC电源
  27.          ADC_CONTR|= ADC_START;           //开始ADC转换,转换完成后硬件将此位清零
  28.          ADC_CONTR|= Channel;                  //ADC模拟通道选择;可以用整数代替;如:ADC_CONTR = 10;(二进制1010)则选择P0.2引脚;                                                                                                                              

  29.    _nop_(); //Must wait before inquiry ,
  30.    _nop_(); //设置ADC_CONTR寄存器后需加4个CPU时钟周期的延时,才能保证值被写入ADC_CONTR寄存器
  31.    _nop_();
  32.    _nop_();

  33.          //ADC_FLAG转换结束标志位;当ADC完成一次转换后,硬件自动将此位置1,并向CPU发出中断请求;
  34.    while (!(ADC_CONTR & ADC_FLAG));     //等待转换完成,硬件自动将此位置1;
  35.    ADC_CONTR &= ~ADC_FLAG;                                     //软件把ADC_FLAG转换结束标志位清零;等待下次硬件置1


  36.   GAOWEI = ADC_RES; //高8位
  37.          DIWEI= ADC_RESL; //低4位
  38.          trans_result=GAOWEI;
  39.          trans_result=(trans_result<<8)|DIWEI;
  40.          trans_result=trans_result>>4;

  41.    ADC_Data = trans_result;
  42.    return ADC_Data;
  43. }

  44. /*************************************************************************
  45.                           定时器0中断服务函数
  46.                          中断方式扫描ADC转换值
  47. **************************************************************************/

  48. void ADC(void) interrupt 1 using 1
  49. {
  50.          unsignedchar i,j,k,count;
  51.          unsignedint V,V1,temp;
  52.          unsignedlong V2,V3;
  53.          unsignedint value_buf[N];
  54.          TH0= (65536-50000)/256;
  55.          TL0= (65536-50000)%256;
  56.          i++;
  57.     value_buf[ i] = ADC_Start(7);
  58. ]         if(i== (N-1))
  59. {
  60. i = 0;
  61. /***冒泡排序*/
  62. for(j=0;j<N-1;j++)
  63. {
  64. for(k=0;k<N-j;k++)
  65. {
  66. if ( value_buf[k]>value_buf[k+1] )
  67. {
  68. temp = value_buf[k];
  69. value_buf[k] =value_buf[k+1];
  70. value_buf[k+1] = temp;
  71. }
  72. }
  73. }
  74. /**********************************/

  75. for(count=1;count<N-1;count++)
  76. V +=value_buf[count];

  77. V3=(long)V*500/4095;   
  78. V2=(long)V*500/4095/10;      
  79. V1=(unsignedint)((long)V*500/4095)%10;     
  80. printf("\r\n%ld", V3);
  81. printf(",%ld", V2);
  82. printf(".%u",V1);
  83. printf(",%u", V);
  84. V=0;
  85. }




  86. /*************************************************************************
  87. 主函数
  88. **************************************************************************/
  89. void main (void)
  90. {        

  91. UART1_Init();     //UART串口初始化
  92. ADC_Init();                          //ADC初始化函数
  93. ADC_Start(7);     //ADC采集转换函数

  94. while(1);     //主循环
  95. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:514692 发表于 2019-4-26 10:43 | 只看该作者
已找到原因,电压基准波动太大造成的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表