这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » ST7,ADC ST7的ADC问题

共3条 1/1 1 跳转至

ST7,ADC ST7的ADC问题

院士
2006-09-17 18:14:16     打赏
ST7,ADC ST7的ADC问题



关键词: 问题    

院士
2006-12-22 22:43:00     打赏
2楼
ST7系列的ADC转换速度比较快,可是不会触发中断,大家都是怎样设计的呀。 1: 哪位是用DVP3开发的DVP3能仿真ST7F324的ADC吗? 2: DVP3肯定支持ADC324是没有ADC中断的。为了防止中断对ADC的干扰,可以建议在ADC进去是关闭中断,出来在打开。

给段汇编写的例子,C的可以看ST7的库文件里的源代码;

;----------------------------------------------------
;采样函数
;功能:根据采样通道号,连续AD_Sample_Counter次采样,求出采样值的累加和
;入口:R0(采用通道)    
;出口:Sum_1 (LSB)、Sum_2、Sum_3 (HSB)
;使用: A, X、R0、Sum_1、Sum_2、Sum_3
.Sample_X        
    PUSH X
    LD X, #AD_Sample_Counter
.Sample_Startup
    LD A, R0          ;Select ADC Channel
    OR   A, #$20
    SIM
    LD ADCCSR,A    
.Sample_Waitting
    BTJF ADCCSR,#7, Sample_Waitting
    RIM
    LD  A, ADCDRL
    LD  R1, A
    LD  A, ADCDRH
    LD  R2, A    
.Sample_LSB_ADD    
    LD A, Sum_1
    ADD A, R1
    LD Sum_1,A       
.Sample_HSB_ADD
    RCF         
    LD     A,Sum_2
    ADD    A,R2
    LD    Sum_2,A
    LD     A,Sum_3
    ADC    A,#$0
    LD       Sum_3, A
    DEC X
    JRNE Sample_Startup
    POP X
    RET    

使用前要定义IO为AD模式,定义需要联系采样的次数:AD_Sample_Counter,然后将需要采样的通道送给R0,再调用Sample_X函数,出口已经写明了。
采样部分的处理:
    SIM
    LD ADCCSR,A    
.Sample_Waitting
    BTJF ADCCSR,#7, Sample_Waitting
    RIM

我以前写的代码都是这样做的。



3: 我的程序void    adc_init(void)
{
    ADCCSR|=0x40;                    //fadc=4M
    ADCDRH;                        //清ADC标志
}

void    adc_chan(uchar    i)    //选择通道
{
    ADCCSR&=0XF0;
    ADCCSR|=i;
}

uint    adc_read(void)            //读ADC数据
{
    uchar    temp;
    uint    conv_data;
    temp=(uchar)(ADCDRL&0x03);
    conv_data=(uint)ADCDRH;
    conv_data=conv_data<<2;
    conv_data|=temp;
    return(conv_data);
}

void main(void)
{
  PDDR =B1111_1111;
  PDDDR=B1111_1101;
  PDOR =B1111_1101;
  adc_init();
  while(1)
{
   adc_chan(1);
   ADCCSR |= 0x20
   while(ValBit(ADCCSR,7)==0)    {};//就只能到这
   adc_data=adc_read();
  }
} 4: 看别人写的程序有些头痛,呵呵,看客户写的程序太多了因为经常要看客户写的程序,所以……

你的问题是不是在这?
while(ValBit(ADCCSR,7)==0)    {};//就只能到这


一般对于ADC功能使用,会出现问题的地方是(我指软件):IO口的初始化、ADC的初始化、ADC采样读取的方式(ST7要求要先读取低位再读高位,关系到EOC标志的硬件清除)

1、IO的初始化要将ADC功能引脚作为悬浮输入(就是10)模式;
2、初始化ADC,请注意寄存器的读写顺序:
void ADC_Init (Typ_ADC_InitParameter InitValue)
{
    unsigned char Temp;                    /* Only for reading the registers */
    
    ADCCSR  = ADC_DEFAULT;              /* Clear ADC control status register */
    ADCCSR  = (unsigned char)InitValue;        /* Clear the ADC data register*/         
    Temp    = ADCDRH;                                      /* Clear EOC flag*/
    
}


3、选择ADC通道:
void ADC_Select_Channel (unsigned char ADC_AIN)
{
    /* Select the analog channel for the conversion */
    ADCCSR &= ADC_SEL_CHNL1;         
    ADCCSR |= ADC_AIN;                  /* Pass the value of the channel */
}

4、检查ADC是否完成:
BOOL ADC_Test_Conversn_Complete (void)
{           
    if(ADCCSR & ADC_EOC)                               /* Check the EOC bit */
    {
        return(TRUE);                  /* Return the status of the EOC flag */
    }else
  {
    return(FALSE);
  }
}


5、读取采样值:
unsigned int ADC_Conversn_Read (void)
{          
    unsigned char Temp;                /* Only for reading the registers */
  unsigned int Conv_Data;            /* for reading the converted data */

    /* Reading the least two bits of conversion from ADCDRL*/
  Temp = (unsigned char)((unsigned char)ADCDRL & (unsigned char)0x03);    
  Conv_Data = ADCDRH;           /* reading the MSB of conversion */
  Conv_Data = Conv_Data<< 2;
  Conv_Data |= Temp;            /* Oring the least two bits with the MSB */
  return(Conv_Data);            /* Returning the Converted data */        
}  


上述就是读ADC的操作顺序了,你可以先对照上面的代码,找找自己的原因。我希望你能够自己找出问题所在,实在搞不明白我再帮你看看代码。


下面代码来自ST7 Library,不过我已经改过了,之前的代码还支持别的系列MCU,因为看上去太累了有用不上,我把用不着的全部都删了。如果需要请自行参考ST7 Lib源文件。

/******************************************************************************
Source File Name : ADC.h  
Author           :
Date First Issued:
********************************Documentation**********************************


********************************Revision History*******************************
_______________________________________________________________________________
Date :         Release:
******************************************************************************/
    
#ifndef ADC_H
#define ADC_H     

#include "..\include\io72324.h"        /* IO registers bit definitions */


/* Enums for ADC Initialisation for different devices */
/*---------------------------------------------------------------------------*/
typedef enum {
    ADC_DEFAULT    = (unsigned char) 0x00,
    ADC_SPEED      = (unsigned char) 0x40,
    ADC_ON         = (unsigned char) 0x20,
    ADC_OFF        = (unsigned char) 0xDF,
    ADC_EOC        = (unsigned char) 0x80,
    ADC_SEL_CHNL1  = (unsigned char) 0xF0,
    ADC_SEL_CHNL2  = (unsigned char) 0xF8    
  }Typ_ADC_InitParameter;

/*---------------------------------------------------------------------------*/
/* MACRO Definations */

#define ADC_Enable() (ADCCSR |= ADC_ON)          /* macro for Enabling the adc */

#define ADC_Disable() (ADCCSR &= ADC_OFF)        /* macro for disabling the adc */

/* macro for reading converted data */  
unsigned int ADC_Conversn_Read (void);                 /* Read the conversion*/

void ADC_Init(Typ_ADC_InitParameter InitValue);             /* Initialize ADC*/

BOOL ADC_Test_Conversn_Complete (void);   /* Wait till conversion is complete*/

void ADC_Select_Channel (unsigned char ADC_AIN);/* Select the desired channel*/

#endif


/******************************************************************************
Source File Name : ADC.c  
Author           :
Date First Issued:
********************************Documentation**********************************


********************************Revision History*******************************
_______________________________________________________________________________
Date :         Release:
******************************************************************************/
#include "..\include\config.h"
#include "..\include\ADC.h"  

/*-----------------------------------------------------------------------------
ROUTINE NAME : ADC_Init
INPUT        : ADC_SPEED (Sets the Clock of ADC)
                             ADC_ONESHOT (Configures the ADC in oneshot mode)
               ADC_AMPLIFIER_ON (Enables the Amplifier)
               ADC_AMPLIFIER_CAL (Calibrates the Amplifier)
                             ADC_DEFAULT (Configures the ADC in Default mode)
OUTPUT       : None.
DESCRIPTION  : ADC peripheral initialisation routine.
COMMENTS     : User has to pass the InitValue from INPUT.More than one
                 INPUT parameters CAN be passed by Logically ORing the INPUTs
-----------------------------------------------------------------------------*/
void ADC_Init (Typ_ADC_InitParameter InitValue)
{
    unsigned char Temp;                    /* Only for reading the registers */
    
    ADCCSR  = ADC_DEFAULT;              /* Clear ADC control status register */
    ADCCSR  = (unsigned char)InitValue;        /* Clear the ADC data register*/         
    Temp    = ADCDRH;                                      /* Clear EOC flag*/
    
}
/* ---------------------------------------------------------------------------
ROUTINE NAME : ADC_Test_Conversn_Complete
INPUT        : None
OUTPUT       : TRUE or FALSE
DESCRIPTION  : Check if the A/D Conversion is complete.
COMMENTS     : This function CAN be looped till the convertion is complete.
----------------------------------------------------------------------------*/
BOOL ADC_Test_Conversn_Complete (void)
{           
    if(ADCCSR & ADC_EOC)                               /* Check the EOC bit */
    {
        return(TRUE);                  /* Return the status of the EOC flag */
    }else
  {
    return(FALSE);
  }
}

/* ----------------------------------------------------------------------------
ROUTINE NAME : ADC_Select_Channel
INPUT        : ADC_AIN (Channel no.)
OUTPUT       : None
DESCRIPTION  : Selects Analog input channel 0,1,2,3........15
COMMENTS     : ADC_AIN depends upon the device used
----------------------------------------------------------------------------*/
void ADC_Select_Channel (unsigned char ADC_AIN)
{
    /* Select the analog channel for the conversion */
    ADCCSR &= ADC_SEL_CHNL1;         
    ADCCSR |= ADC_AIN;                  /* Pass the value of the channel */
}
/* ----------------------------------------------------------------------------
ROUTINE NAME : ADC_Conversn_Read
INPUT        : None
OUTPUT       : unsigned integer (converted data from Data registers)
DESCRIPTION  : Read the Conversion from the data register
COMMENTS     : It returns OUTPUT,depending upon the device selceted
----------------------------------------------------------------------------*/
unsigned int ADC_Conversn_Read (void)
{          
    unsigned char Temp;                /* Only for reading the registers */
  unsigned int Conv_Data;            /* for reading the converted data */

    /* Reading the least two bits of conversion from ADCDRL*/
  Temp = (unsigned char)((unsigned char)ADCDRL & (unsigned char)0x03);    
  Conv_Data = ADCDRH;           /* reading the MSB of conversion */
  Conv_Data = Conv_Data<< 2;
  Conv_Data |= Temp;            /* Oring the least two bits with the MSB */
  return(Conv_Data);            /* Returning the Converted data */        
}               


/******************************* END OF FILE *******************************/



/******************************************************************************
Source File Name : Config.h  
Author           :
Date First Issued:
********************************Documentation**********************************


********************************Revision History*******************************
_______________________________________________________________________________
Date :         Release:
******************************************************************************/  

#ifndef    CONFIG_H
#define    CONFIG_H

#include "..\include\io72324.h"        /* IO registers bit definitions */

/*********************User Customizable Part**********************************/

/*-------------------------------define Fcpu---------------------------------*/
#define Fcpu ((unsigned long) 8000000)                                      
#define Fosc2 ((unsigned long) 8000000)

/*----------------------------Enumerated data type---------------------------*/
#ifndef enum_type
#define enum_type
typedef enum{
    FALSE  = (unsigned char) 0x00,
    TRUE   = !(FALSE)
}BOOL;
#endif

/*---------------------Macros for Assembly instructions----------------------*/   
#define EnableInterrupts {_asm ("RIM");}  
#define DisableInterrupts {_asm ("SIM");}
#define NOP {_asm ("NOP");}
#define WaitforInterrupt {_asm ("WFI");}



#define AREA 0x00     /* The area of bits begins at address 0x10. */                   
#define BitClr(BIT)  ( *((unsigned char *) (AREA+BIT/8)) &= (~(1<<(7-BIT%8))) )
#define BitSet(BIT)  ( *((unsigned char *) (AREA+BIT/8)) |=   (1<<(7-BIT%8))  )
#define BitVal(BIT)  ( *((unsigned char *) (AREA+BIT/8)) & (1<<(7-BIT%8)) )


#endif    CONFIG_H


/****************************End of User Part*********************************/
















5: 我已经对比你的程序没什么不同呀 6: 其实ST的AD很简单啊一个转换只需8us,datasheet说的,测试(软仿真)也很快,差不多就那个时间

首先设通道,然后启动转换,检测标志是否完成,然后读数据,关闭即可,

用ST的软仿真平台也可以调试的,

推荐ST7的软仿真平台,很好使,基本的功能都可以测试,包括时间等。 7: 又看了一下小鱼儿和程序,和我自己的在差别差别在于:我在正常情况下AD都是关着的,只有在读的时候才去开启,读完之后关闭,

用于按键扫描,

专家
2022-08-04 23:14:55     打赏
3楼

谢谢分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]