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

📄 c8051f020ad.#1

📁 C8051F120 _AD开发过程中的一些代码和文档
💻 #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 + -