Arm學(xué)習(xí)筆記--ADC編程
typedef struct
{
__IO uint32_t CR; /*!< Offset: 0x000 A/D Control Register (R/W) */
__IO uint32_t GDR; /*!< Offset: 0x004 A/D Global Data Register (R/W) */
uint32_t RESERVED0;
__IO uint32_t INTEN; /*!< Offset: 0x00C A/D Interrupt Enable Register (R/W) */
__IO uint32_t DR[8]; /*!< Offset: 0x010-0x02C A/D Channel 0..7 Data Register (R/W) */
__I uint32_t STAT; /*!< Offset: 0x030 A/D Status Register (R/ ) */
__IO uint32_t ADTRM;
} LPC_ADC_TypeDef;
void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t rate)
{
uint32_t temp, tmp;
// Turn on power and clock
CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCADC, ENABLE); //開啟ADC功能
ADCx->CR = 0; //控制寄存器初始化
//Enable PDN bit
tmp = ADC_CR_PDN;
// Set clock frequency
temp = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); //設(shè)置時(shí)鐘頻率
/* The APB clock (PCLK_ADC0) is divided by (CLKDIV+1) to produce the clock for
* A/D converter, which should be less than or equal to 12.4MHz.
* A fully conversion requires 31 of these clocks.
* ADC clock = PCLK_ADC0 / (CLKDIV + 1);
* ADC rate = ADC clock / 31;
*/
temp = (temp /(rate * 31)) - 1;
tmp |= ADC_CR_CLKDIV(temp);
ADCx->CR = tmp; //配置了時(shí)鐘頻率
}
/*********************************************************************//**
* @brief ADC interrupt configuration
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] IntType: type of interrupt, should be:
* - ADC_ADINTEN0: Interrupt channel 0
* - ADC_ADINTEN1: Interrupt channel 1
* ...
* - ADC_ADINTEN7: Interrupt channel 7
* - ADC_ADGINTEN: Individual channel/global flag done generate an interrupt
* @param[in] NewState:
* - SET : enable ADC interrupt
* - RESET: disable ADC interrupt
* @return None
**********************************************************************/
void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState)
{
ADCx->INTEN &= ~ADC_INTEN_CH(IntType);
if (NewState){
ADCx->INTEN |= ADC_INTEN_CH(IntType);
}
}
void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState)
{
if (NewState == ENABLE) {
ADCx->CR |= ADC_CR_CH_SEL(Channel);
} else {
ADCx->CR &= ~ADC_CR_CH_SEL(Channel);
}
}
void ADC_IRQHandler(void)
{
adc_value = 0;
if (ADC_ChannelGetStatus(LPC_ADC, TENGHUA_ADC_PREPARED_CHANNEL, ADC_DATA_DONE))
{
adc_value = ADC_ChannelGetData(LPC_ADC, TENGHUA_ADC_PREPARED_CHANNEL);
NVIC_DisableIRQ(ADC_IRQn);
}
}
其實(shí)ADC是很簡(jiǎn)單和基礎(chǔ)的,主要還是掌握好寄存器的使用。
評(píng)論