⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc.c

📁 达盛EL-ARM-830
💻 C
字号:
/*
;************************************************************************************************************
;*				        				北京精仪达盛科技有限公司
;*                                     	     研    发    部
;*
;*                                 	     http://www.techshine.com
;*
;*--------------------------------------------- 文件信息 ----------------------------------------------------                                      
;*
;* 文件名称 : adc.c	
;* 文件功能 : 该文件为S3C2410硬件平台的AD采集函数。
;* 补充说明 : 
;*-------------------------------------------- 最新版本信息 -------------------------------------------------
;* 修改作者 : ARM开发小组
;* 修改日期 : 2004/04/25
;* 版本声明 : V1.0.1
;*-------------------------------------------- 历史版本信息 -------------------------------------------------
;* 文件作者 : ARM开发小组
;* 创建日期 : 2004/04/20
;* 版本声明 : v1.0.0
;*-----------------------------------------------------------------------------------------------------------
;*-----------------------------------------------------------------------------------------------------------
;************************************************************************************************************
;*/
#include "..\..\startup2410\INC\2410addr.h"
#include "..\..\startup2410\INC\target.h"
#include "..\..\startup2410\INC\2410lib.h"

#define isDebug 0  //如果此值是1,可以串口输出信息,此值是0,不输出信息
const int ADCount = 10;
int ArrayDat0[ADCount];
#define AD_BOTTOM 0
#define AD_TOP 1500
#define LCD_YSIZE 235



/*
*************************************************************************************************************
- 函数名称 : Get_AD(unsigned char ch)
- 函数说明 : 得到AD的转换值
- 输入参数 : ch
- 输出参数 : val>>4
*************************************************************************************************************
*/
short Get_AD(unsigned char ch)
{

    /*本段未作任何处理,误差太大
    rADCCON |= 0x1; 		                                                //启动 A/D 转换

	while (rADCCON & 0x1); 		                                                    //避免第一个标志出错

	while (!(rADCCON & 0x8000));                                                      //避免第二个标志出错
	return (rADCDAT0 & 0x03ff);
    */


    /*采样16次,平均处理 
    int i;
    int val=0;  
      
    if(ch>7)  return 0;

    
    for(i=0;i<16;i++)
    {  
        rADCCON |= 0x1; 		                                                //启动 A/D 转换
        rADCCON = rADCCON & 0xffc7 | (ch<<3);
		while (rADCCON & 0x1); 		                                                    //避免第一个标志出错

		while (!(rADCCON & 0x8000));                                                      //避免第二个标志出错
		val += (rADCDAT0 & 0x03ff);
		Delay(10);
		
    }
    return (val>>4);*/

    /*采样4次,平均处理
    int i;
    int val=0;  
      
    if(ch>7)  return 0;

    
    for(i=0;i<4;i++)
    {  
        rADCCON |= 0x1; 		                                                //启动 A/D 转换
        rADCCON = rADCCON & 0xffc7 | (ch<<3);
		while (rADCCON & 0x1); 		                                                    //避免第一个标志出错

		while (!(rADCCON & 0x8000));                                                      //避免第二个标志出错
		val += (rADCDAT0 & 0x03ff);
		Delay(10);
		
    }
    return (val>>2); */
   
    /*采样1次,平均处理 */
    int i;
    int val=0;  
      
    if(ch>7)  return 0;

    
    for(i=0;i<1;i++)
    {  
        rADCCON |= 0x1; 		                                                //启动 A/D 转换
        rADCCON = rADCCON & 0xffc7 | (ch<<3);
		while (rADCCON & 0x1); 		                                                    //避免第一个标志出错

		while (!(rADCCON & 0x8000));                                                      //避免第二个标志出错
		val += (rADCDAT0 & 0x03ff);
		Delay(10);
		
    }
    return (val);
    
    
    /* 取最优点处理,效果不好
    int i;
    int val=0;
    int* p = ArrayDat0;
      
      
    if(ch>7)  return 0;

    
    for(i=0;i<ADCount;i++)
    {  
        rADCCON |= 0x1; 		                                                //启动 A/D 转换

		while (rADCCON & 0x1); 		                                                    //避免第一个标志出错

		while (!(rADCCON & 0x8000));                                                      //避免第二个标志出错
		ArrayDat0[i] = (rADCDAT0 & 0x03ff);
		Delay(1);
		
		
    }
    val = GetDat0(p);
    return (val);
    */
    
    
    
}

/*
*************************************************************************************************************
- 函数名称 : AD_Init(void)
- 函数说明 : AD转换器初始化
- 输入参数 : 无
- 输出参数 : 无
*************************************************************************************************************
*/
void AD_Init(unsigned char ch)
{
    rADCDLY   = (100);	             // ADC Start or Interval Delay 0x100
	rADCTSC   = 0;  //设置成为ADC模式
	rADCCON	= (1<<14)|(49<<6)|(ch<<3)|(0<<2)|(0<<1)|(0);	  //设置ADC控制寄存器
}

/*
***********************************************************************************************************
* 函数名称:  AD2Y(int ady)
* 函数功能:  把AD值转换成Y坐标值
* 输入参数:  ady
* 返回值  :  Y坐标值
***********************************************************************************************************
*/
int AD2Y(int ady) 																// 把AD值转换成坐标值 y
{
	return LCD_YSIZE * (AD_TOP - ady) / (AD_TOP - AD_BOTTOM);
}

/*
*************************************************************************************************************
- 函数名称: void selectsort(int* r,int n)
- 函数功能:选择排序
- 输入参数:r[] is struct rec,n是要排序记录的个数
- 输出参数:无
*************************************************************************************************************
*/
void selectsort(int* r,int n){ //r[] is struct rec,选择排序
    int i,j,k;
    int w;//struct rec
    for(i = 0; i < n - 1; i ++){
        k = i;
        for (j = i + 1; j < n; j ++){
            if (r[j] < r[k])
                k = j;
        }
        if (k != i){
            w=r[i];//交换
            r[i]=r[k];
            r[k]=w;
        }
    }
    #if (isDebug == 1)
        Uart_Printf("Sort::");
        for (i = 0; i < n; i++)
            Uart_Printf("%d, ", r[i]);
        Uart_Printf("  end\n");
    #endif
}

/*
*************************************************************************************************************
- 函数名称: int GetDat0(int* p)
- 函数功能:将采集到的数据进行处理,去除不稳定的抖动值,得到准确的AD转换值
- 输入参数:采集到的数据的指针
- 输出参数:准确的AD转换值
*************************************************************************************************************
*/ 
int GetDat0(int* p){
    int Dat0;
    //const int ADCount = 10;
    int tmp[9];//ADCount - 1
    int i, k, diftag = 0;
    struct ARRAYCMP{
        int difsize;
        int continuecount;
    }ArrayCmp[9];//ADCount - 1

        selectsort(p, ADCount); //将采集到的数据排序(由小到大)
        for (i = 0; i < ADCount - 1; i ++){
            tmp[i] = p[i + 1] - p[i]; //tmp[]存储各点之间的差值
        }
        #if (isDebug == 1)
        Uart_Printf("tmp:\n    ");
        for (i = 0; i < ADCount - 1; i++){
            Uart_Printf("%d,",tmp[i]);
        }
        Uart_Printf("\n");
        #endif
        
        //fill table
        //ArrayCmp是一个表格,表格的第一列存储各点之间的差值,
        //第二列存储相同的点连续存放的个数
        /* 举例:
        tmp[] : 2,0,0,0,2,0,0,2,2
        ArrayCmp[]如下:
        下标	差值	连续个数
        0		2		0
        1		0		2
        2		0		-2
        3		0		-1
        4		2		0
        5		0		1
        6		0		-2
        7		2		1
        */
        ArrayCmp[0].difsize = tmp[0];
        ArrayCmp[0].continuecount = 0;
        k = 0;
        for(i = 1; i < ADCount - 1; i++){
            if ((tmp[i] == tmp[i - 1]) && (diftag == 0)){
                ArrayCmp[i].difsize = tmp[i];
                ArrayCmp[i].continuecount = -2;
                ArrayCmp[i - 1].continuecount = 1;
                diftag = 1;
                k = i - 1;
            }else if ((tmp[i] == tmp[i - 1]) && (diftag == 1)){
                ArrayCmp[i].difsize = tmp[i];
                ArrayCmp[i].continuecount = -1;
                ArrayCmp[k].continuecount += 1;
                diftag = 1;
            }else{ //(tmp[i] != tmp[i - 1])
                ArrayCmp[i].difsize = tmp[i];
                ArrayCmp[i].continuecount = 0;
                diftag = 0;
            }
        }
        
        #if (isDebug == 1)
        Uart_Printf("ArrayCmp:\n    ");
        for (i = 0; i < ADCount - 1; i++){
            Uart_Printf("%d,  %d,  %d\n",i, ArrayCmp[i].difsize, ArrayCmp[i].continuecount);
        }
        Uart_Printf("\n");
        #endif
        //scan table
        //扫描ArrayCmp[]中差值最小且连续个数最多的点的下标
        k = 0;
        for (i = 1; i < ADCount - 1; i++){
            if (ArrayCmp[i].difsize < ArrayCmp[k].difsize)
                k = i;
            else if (ArrayCmp[i].difsize == ArrayCmp[k].difsize){
                if (ArrayCmp[i].continuecount >= ArrayCmp[k].continuecount)
                    k = i;
            }
        }
        Dat0 = p[k];
        
        
    
    return Dat0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -