采樣的波動特別大,電壓采樣后轉換成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); //主循環
- }
復制代碼
|