/*******************************************************************************
* 函数名称:ADC_Init(uint16_t ch,ADC_VREF Vref,ADC_Resolution nBit)
* 功能说明:ADC初始化一个或多个ADC通道
* 参数说明:
uint16_t ch :要初始化的通道
ADCVREF Vref :参考电压
ADC_Resolution nBit :转换精度
* 函数返回:无
********************************************************************************/
void ADC_Init(uint16_t ch,ADC_VREF Vref,ADC_Resolution nBit)
{
ADC12->ENC = DISABLE; //先对该位复位,否则置位后有些寄存器不能再进行操作
uint16_t SREF_RegValue = 0u;
switch(Vref) //选择参考电压
{
case ADC_VREF_1_5V:
REFCTL0 &=~ REFMSTR; //把REF参考电压控制权交给ADC
ADC12->ADCREFON = BIT_SET;
ADC12->REF2_5V = RESET;
SREF_RegValue = ADC12_SREF_1; //使用内部提供的参考电压
break;
case ADC_VREF_2_5V:
REFCTL0 &=~ REFMSTR;
ADC12->ADCREFON = BIT_SET;
ADC12->REF2_5V = BIT_SET;
SREF_RegValue = ADC12_SREF_1; //使用内部提供的参考电压
break;
case ADC_VREF_External:
P5SEL |= BIT0; //VeREF+
P5SEL |= BIT1; //VeREF-
SREF_RegValue = ADC12_SREF_2; //使用外部参考电压
case ADC_VREF_3_3V:
SREF_RegValue = ADC12_SREF_0; //使用电源电压作为参考电压,
break;
default :break;
}
//初始化通道
uint16_t CH_Mask = 0x01;
for(uint8_t CH_Num=0; CH_Num < ADC_CH_NUM; CH_Num++)
{
if(ch & CH_Mask) //要初始化的通道
{
if((CH_Mask & InitialedChannel_Bit) == 0) //如果该通道未被初始化过
{
ADC12->MCTL[InitialedChannel_Num].INCH = CH_Num;
ADC12->MCTL[InitialedChannel_Num].REF = SREF_RegValue;//参考电压选择,通道设置
ADC_Channel_Bit[InitialedChannel_Num] = CH_Mask;//将该通道初始化标志置位 InitialedChannel_Bit |= CH_Mask; //置位已初始化的通道标志位
InitialedChannel_Num ++;//初始化的通道数加1
}
else //如果是之前已经初始化过的通道,则要在这里从新设置一下,只设置通道参考电压
{
ADC12->MCTL[ADC_GetChanelNum((ADC_CHn)CH_Mask)].REF = SREF_RegValue;//改变参考电压
}
}
CH_Mask <<= 1;
}
if(InitialedChannel_Num > 1) //有多个通道时要加上序列通道结束位
{
for(int i=0; i<(InitialedChannel_Num-1); i++) //前面所有通道序列结束位清零
{
ADC12->MCTL[i].EOS = RESET;
}
ADC12->MCTL[InitialedChannel_Num-1].EOS = BIT_SET; //最后一通道加上序列通道转换结束位
}
//一般配置
ADC12->SHT0 = M0_M7_SAMPLE_HOLD_TIME; //0-7通道采样与保持时间
ADC12->SHT1 = M8_M15_SAMPLE_HOLD_TIME;//8-15通道采样与保持时间
ADC12->ON = BIT_SET;/ 采样时间,AD内核开启
ADC12->MSC = BIT_SET;
ADC12->SSEL = ADC12_SSEL_ADC12OSC;//时钟选择
ADC12->SHP = BIT_SET;
//有多个通道时设为序列通道单次转换模式,单个通道时设为单通道单次转换模式
ADC12->CONSEQ = (InitialedChannel_Num > 1) ? BIT_SET : RESET;
//设置ADC精度
ADC12->RES = nBit;
//开启时钟
UCS->MODOSC_REQEN = BIT_SET; //ADC使用的是MODCLK 所以在这里配置该时钟,约5MHz左右
//配置通道为第二功能
if(ch & 0x00ff)
{
GPIO_MultiBits_Init(P6,(ch & 0x00ff),GPI | SEL);
}
if(ch & 0xf000)
{
GPIO_MultiBits_Init(P7,((ch & 0xf000)>>12),GPI | SEL);
}
if(ch & ADC_CH10) //如果使用了温度传感器通道,则开启温度传感器
{
ADC12->TCOFF = RESET;
}
ADC12->ENC = ENABLE; //该位必须在初始化完成后再置位
//DELAY_MS(5); //延时等待参考电压建立
}
这里采样与保持间隔
//宏定义ADC12MEM8 to ADC12MEM15采样与保持时间 0-15
#define M8_M15_SAMPLE_HOLD_TIME 3
//宏定义ADC12MEM0 to ADC12MEM7 采样与保持时间 0-15
#define M0_M7_SAMPLE_HOLD_TIME 3
注意点
1. 初始化后所有通道精度相同,即所有通道转换精度只取决于最后一次配置的精度
2. 所有通道内部参考电压只能使用1.5或2.5V中的一种
使用示例:
ADC_Init(ADC_CH1+ADC_CH3,ADC_VREF_1_5V,ADC_10bit);
//同时初始化两个通道,使用内部提供的1.5V参考电压,10位精度
|