📄 c8051f020ad.#1
字号:
/*******************************************************************
C8051F120 AD采集 2007.01.08
*******************************************************************/
/************************预定义************************************/
#include <C8051F120.h>
#include <stdio.h>
#include <math.h>
#define ADC0START temppage=SFRPAGE;SFRPAGE=0x00;AD0BUSY=1;SFRPAGE=temppage
/*******************************************************************
定义IO口和变量
/*******************************************************************/
sfr16 ADC0 = 0xbe; //采样结果存贮的地方
unsigned int xdata ADC0_data[8]; //AD采样的结果
unsigned int xdata ADC0_temp[24]; //AD单通道临时采集存放的数据
unsigned int data ADC0_single; //单通道AD采集次数(0-23,24次)
unsigned int data ADC0_Num; //AD完成通道的采集次数8次
bit ADflag; //AD采集完标志
/*******************************************************************
函数声明
*******************************************************************/
unsigned short Average(unsigned short *Adp) //AD采集完24次数据处理函数
void ADC0_ISR(void); //ADC0中断函数声明
void delay_us(int utimer) //us沿时
void delay_ms(int mtimer) // ms沿时
void adc0_source(uchar source) //ADC0通道选择,为adc0_mux()的简化函数
void adc0_mux(uchar type,uchar source) //type 配置测量方式为差动还是单端输入
/********************************************************************
系统初始化函数
********************************************************************/
void Timer_Init()
{
CKCON = 0x10;
TCON = 0x40;
TMOD = 0x20;
TH1 = 0xB8; //用定时器3做为AD0的启动转换标志每100us启动一次采集,
TMR3CN = 0x04; //使用系统时钟12分频做为定时器3的时钟源(24M)
TMR3RLL = 0xd1; //T1使用系统时钟并产生9600的波特率用与UART0
TMR3RLH = 0xFF;
TMR3L = 0xd1;
TMR3H = 0xFF;
}
void ADC_Init()
{
char data SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = SFR_PAGE_0;
ADC0CF = 0x40; //ADC0为定时器3益处采集方式,时钟频率为2.5M,
ADC0CN = 0x04; //增益为1,数据为右对齐方式
AMX0SL=0X00; //选通0通道
AMX0CF=0X00; //全部采用单端输入方式
SFRPAGE = SFRPAGE_SAVE;
}
void Voltage_Reference_Init()
{
REF0CN = 0x03; //ADC0的参考电压来自内部增益
/*
REF0CN = 0x03; //关闭温度传感器, 使用片上VREF,
*/
}
//********************************************************************//
// 系统时钟 //
//=====================================================================//
void SYSCLK_Init(void)
{
int i;
char SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=CONFIG_PAGE; //第F页
OSCXCN=0x67; //启用外部振荡器
for(i=0;i<3000;i++); //等待外部振荡器启振
while(!(OSCXCN & 0x80)) //等待外部振荡器稳定
OSCICN=0x88; //选择外部振荡器为系统时钟源,并允许时钟丢失检测器
//PLL0CN = 0x04;
CLKSEL = 0x01;
SFRPAGE=SFRPAGE_SAVE;
}
/*
// 配置系统时钟使用外部晶振22.1184MHz
void SYSCLK_Init (void)
{
int i; // delay counter
OSCXCN = 0x67; // start external oscillator with
// 22.1184MHz crystal
for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms)
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
}
*/
void Interrupts_Init()
{
EIE2 = 0x02; //允许ADC0中断
/*
EIE2 &= (~0x02); //关闭ADC中断
*/
}
void Init_Device(void)
{
Timer_Init();
ADC_Init();
Voltage_Reference_Init();
Oscillator_Init();
Interrupts_Init();
}
//end init//
/****************************************************************************
主函数定义开始
*****************************************************************************/
void main(void)
{
WDTCN=0xde;
WDTCN=0xad; //关看门狗
Init_Device();
AD0EN=1;
delay_ms(5);
EA=1;
TI0=1;
while(1)
{
if(ADflag==1)
{
ADflag=0;
TMR3CN&=0xFB; //关定时器3
Sjcl(); //处理数据
delay_ms(100);
TMR3CN|=0X04; //开定时器3
}
}
}
/****************************************************************************
ADC0中断处理
****************************************************************************/
void ADC0_ISR(void) interrupt 15
{
ADC0CN&=0xdf;
if(ADC0_single<24)
{
ADC0_data1[ADC0_single] = ADC0;
ADC0_single++; //23+1=24 ;
}
if( ADC0_single==24)
{
ADC0_single=0 ; // ADC0_single=0 ;
ADC0_data[ADC0_Num]=Average(ADC0_data1); //0,1,2,3,4,5,6, 7
if(ADC0_Num<7) //8路 8*24采样完成
{
ADC0_Num ++ ; //选择下一个通道
}
else
{
ADC0_Num=0 ; //清零,走向第一通道
ADflag=1; //完成采样
}
adc0_source(ADC0_Num) ; // 更新通道
}
}
/***************************************************************
单通道采样完成函数
****************************************************************/
unsigned short Average(unsigned short *Adp)
{
uint TempResults[24];
long int m;
char i,j,p;
for(i=0;i<24;i++)
{
TempResults[i]=*Adp;
Adp++;
}
for( i=0; i<23; i++ ) /* 11轮处理 */
{
p=i; /* p记录最小值的下标 */
for ( j=i+1; j<Nu; j++ ) /* 确定本轮最小值的下标p */
if(TempResults[p]>TempResults[j]) p=j;
if ( p!=i ) /* 最小值不是TempResults[i]时才需要TempResults[i]与TempResults[p]交换 */
{
m=TempResults[p];
TempResults[p]=TempResults[i];
TempResults[i]=m;
}
}
m=0;
for (i=2;i<22;i++)
{
m+=TempResults[i];
}
m/=20;
return(m);
}
/****************************************************************************
数据采集完处理函数
****************************************************************************/
void Sjcl(void)
{
delay_ms(10);
}
/*********************************************************************************
子函数定义
**********************************************************************************/
void delay_us(int utimer) //us沿时
{
utimer*=20;//时钟周期调整
for(;utimer>0;utimer--)
_nop_();
}
void delay_ms(int mtimer) //ms沿时
{
for(;mtimer>0;mtimer--)
delay_us(1000);
}
void adc0_mux(uchar type,uchar source) //type 配置测量方式为差动还是单端输入
{
//source 为ADC0通道选择(共有9个通道)
SFRPAGE=0x00;
AMX0CF=type;
AMX0SL=source;
}
void adc0_source(uchar source)
{
//ADC0通道选择,为adc0_mux()的简化函数
SFRPAGE=0x00;
AMX0SL=source;
}
/* 增益
void HVDA_ini(uchar gaind) //高压差动放大器配置
{
SFRPAGE=0x00;
HVA0CN=gaind;
}
*/
/* 轮回扫描
void ADC0_Conver (void)
{
unsigned char m;
unsigned int temp;
char data SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = SFR_PAGE_0;
for(m=0;m<4;m++)
{
AMX0SL = m; // 设置mux到通道
Delay_us(20);
AD0INT = 0; // 清除ADC转换完成标志
AD0BUSY = 1;
while (!AD0INT);
temp = ADC0H;
temp = temp*256+ADC0L;
result[m]=temp; // 读ADC值
}
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -