共3条
1/1 1 跳转至页
问
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都是关着的,只有在读的时候才去开启,读完之后关闭,
用于按键扫描,
给段汇编写的例子,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都是关着的,只有在读的时候才去开启,读完之后关闭,
用于按键扫描,
共3条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |