我們緊接着 學習KEA之ADC之一:基本介紹 來看看ADC的查詢方式。
需求:
-
讀取AD7(PTB3), AD12(PTF4), AD14(PTF6),並轉換成 mV, 範圍是0 - 5000mV,這三個輸入都是電壓大概是2.157V, 2.146V, 2.144V。
-
基本配置:時鐘來自bus_clock, 20MHz, Single模式, Software trigger,10-bit mode operation
例程:
#include "derivative.h" /* include peripheral declarations SSKEAZN64M2 */
void Clk_Init(void);
uint32_t adcResultInMv7 = 0;
uint32_t adcResultInMv12 = 0;
uint32_t adcResultInMv14 = 0;
int main(void)
{
Clk_Init();
init_ADC();
adcResultInMv7 = ADC_Read(7);
adcResultInMv12 = ADC_Read(12);
adcResultInMv14 = ADC_Read(14);
for(;;)
{
}
return 0;
}
/***********************************************************************************************
*
* @brief CLK_Init - Initialize Core Clock to 40MHz, Bus Clock to 20MHz
* @param none
* @return none
*
************************************************************************************************/
void Clk_Init(void)
{
ICS_C1|= ICS_C1_IRCLKEN_MASK; /* Enable the internal reference clock*/
ICS_C3 = 0x50; /* Reference clock frequency = 31.25 kHz*/
while(!(ICS_S & ICS_S_LOCK_MASK)); /* Wait for PLL lock, now running at 40 MHz (1024*39.0625 kHz) */
ICS_C2 |= ICS_C2_BDIV(1) ; /* BDIV=b001, Bus clock = 20 MHz*/
ICS_S |= ICS_S_LOCK_MASK ; /* Clear Loss of lock sticky bit */
}
void init_GPIO(void)
{
GPIOA_PDDR |= 1<<PTD2; /* Port D2: Data Direction= output */
GPIOA_PIDR &= 1<<PTD2; /* Port D2: Input Disable= 1 (default) */
}
void init_ADC(void) {
SIM_SCGC |= SIM_SCGC_ADC_MASK; /* Enable bus clock in ADC*/
ADC_SC3 |= ADC_SC3_ADICLK(0b00); /* Bus clock selected, 20 MHz*/
ADC_SC2 |= 0x00; /* Software Conversion trigger, disable compare function*/
ADC_SC2 |= ADC_SC2_REFSEL(0b01); /* Select VDD and VSS as voltage reference source*/
ADC_SC1 = 0 ; /* Enable ADC by setting ADCH bits as low*/
ADC_SC1 &= ~ADC_SC1_ADCO_MASK; /* Single mode operation */
ADC_APCTL1 |= ADC_APCTL1_ADPC(1<<7 | 1<<12 | 1<<14); /* Channel selection */
ADC_SC3 |= ADC_SC3_MODE(0b01); /* 10-bit mode operation */
}
uint32_t ADC_Read(char channel)
{
ADC_SC1 &= ~ADC_SC1_ADCH_MASK; /* Clear any prior ADCH bits*/
ADC_SC1 |= ADC_SC1_ADCH(channel); /* Select channel to read */
while(!(ADC_SC1 & ADC_SC1_COCO_MASK)); /* Wait conversion to complete */
//return ADC_R;
return (uint32_t) ((5000*ADC_R)/0x3FF); /* Convert result to mv for 0-5V range */
}
上面程序的仿真結果如下:
如果啓用12位的ADC採樣,結果就更準確了:
void init_ADC(void) {
SIM_SCGC |= SIM_SCGC_ADC_MASK; /* Enable bus clock in ADC*/
ADC_SC3 |= ADC_SC3_ADICLK(0b00); /* Bus clock selected, 20 MHz*/
ADC_SC2 |= 0x00; /* Software Conversion trigger, disable compare function*/
ADC_SC2 |= ADC_SC2_REFSEL(0b01); /* Select VDD and VSS as voltage reference source*/
ADC_SC1 = 0 ; /* Enable ADC by setting ADCH bits as low*/
ADC_SC1 &= ~ADC_SC1_ADCO_MASK; /* Single mode operation */
ADC_APCTL1 |= ADC_APCTL1_ADPC(1<<7 | 1<<12 | 1<<14); /* Channel selection */
ADC_SC3 |= ADC_SC3_MODE(0b10); /* 12-bit mode operation */
}
uint32_t ADC_Read(char channel)
{
ADC_SC1 &= ~ADC_SC1_ADCH_MASK; /* Clear any prior ADCH bits*/
ADC_SC1 |= ADC_SC1_ADCH(channel); /* Select channel to read */
while(!(ADC_SC1 & ADC_SC1_COCO_MASK)); /* Wait conversion to complete */
//return ADC_R;
return (uint32_t) ((5000*ADC_R)/0xFFF); /* Convert result to mv for 0-5V range */
}