采样的波动特别大,电压采样后转换成0-500mm长度,波动的幅度可以达到5mm,这个正常吗?程序如下:
单片机源程序如下:
- #define N 12
- void ADC_Init(void)
- {
- //配置P10口为高阻输入,作为ADC采样引脚
- P1M0= 0X00;
- P1M1= 0X01;
- //使用定时器扫描结果
- TMOD= 0x01; //选择定时器T0 在工作方式1上 即16位定时器
- TH0 = (65536-50000)/256; //11.592M晶振的一个机器周期接近1us 这里5W就是0.05s
- TL0 = (65536-50000)%256;
- EA = 1; //开启总中断
- ET0 = 1; //开启定时器T0
- TR0 = 1;
- }
- /*************************************************************************
- ADC转换函数
- 输入:ADC通道0~14数字;
- 输出:ADC转换值
- **************************************************************************/
- unsigned int ADC_Start(unsigned charChannel)
- {
- unsignedchar DIWEI,GAOWEI; //A/D转换后换算的电压值
- unsignedint trans_result,ADC_Data;
- ADC_RES=0;
- ADC_RESL=0;
- ADC_CONTR = ADC_POWER; //打开ADC电源
- ADC_CONTR|= ADC_START; //开始ADC转换,转换完成后硬件将此位清零
- ADC_CONTR|= Channel; //ADC模拟通道选择;可以用整数代替;如:ADC_CONTR = 10;(二进制1010)则选择P0.2引脚;
- _nop_(); //Must wait before inquiry ,
- _nop_(); //设置ADC_CONTR寄存器后需加4个CPU时钟周期的延时,才能保证值被写入ADC_CONTR寄存器
- _nop_();
- _nop_();
- //ADC_FLAG转换结束标志位;当ADC完成一次转换后,硬件自动将此位置1,并向CPU发出中断请求;
- while (!(ADC_CONTR & ADC_FLAG)); //等待转换完成,硬件自动将此位置1;
- ADC_CONTR &= ~ADC_FLAG; //软件把ADC_FLAG转换结束标志位清零;等待下次硬件置1
- GAOWEI = ADC_RES; //高8位
- DIWEI= ADC_RESL; //低4位
- trans_result=GAOWEI;
- trans_result=(trans_result<<8)|DIWEI;
- trans_result=trans_result>>4;
- ADC_Data = trans_result;
- return ADC_Data;
- }
- /*************************************************************************
- 定时器0中断服务函数
- 中断方式扫描ADC转换值
- **************************************************************************/
- void ADC(void) interrupt 1 using 1
- {
- unsignedchar i,j,k,count;
- unsignedint V,V1,temp;
- unsignedlong V2,V3;
- unsignedint value_buf[N];
- TH0= (65536-50000)/256;
- TL0= (65536-50000)%256;
- i++;
- value_buf[ i] = ADC_Start(7);
- ] if(i== (N-1))
- {
- i = 0;
- /***冒泡排序*/
- for(j=0;j<N-1;j++)
- {
- for(k=0;k<N-j;k++)
- {
- if ( value_buf[k]>value_buf[k+1] )
- {
- temp = value_buf[k];
- value_buf[k] =value_buf[k+1];
- value_buf[k+1] = temp;
- }
- }
- }
- /**********************************/
- for(count=1;count<N-1;count++)
- V +=value_buf[count];
- V3=(long)V*500/4095;
- V2=(long)V*500/4095/10;
- V1=(unsignedint)((long)V*500/4095)%10;
- printf("\r\n%ld", V3);
- printf(",%ld", V2);
- printf(".%u",V1);
- printf(",%u", V);
- V=0;
- }
- /*************************************************************************
- 主函数
- **************************************************************************/
- void main (void)
- {
- UART1_Init(); //UART串口初始化
- ADC_Init(); //ADC初始化函数
- ADC_Start(7); //ADC采集转换函数
- while(1); //主循环
- }
复制代码
|