📄 adc.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 + -