||
其实FR5739的ADC和G2553是基本一致的,就是按照手册的寄存器表,然后根据所需要实现的功能进行配置即可。。程序的配置如下:
void ADC10_Init(void)
{
ADC10CTL0 &= ~(ADC10ENC + ADC10ON);//DISABLE ADC CONVERSION
ADC10_IO_Init();
//控制寄存器设置
ADC10CTL0 |= ADC10SHT_5 + ADC10MSC;//ADC10CLK = ADC10SHT_5,MULTIPLE SAMPLE
ADC10CTL1 |= ADC10SHS_0 + ADC10SHP + ADC10SSEL_3 + ADC10CONSEQ_2;//时间触发采样,CLK = SMCLK,REPEAT-SINGLE
ADC10CTL2 |= ADC10RES ;//10 BIT ADC
ADC10MCTL0 |= ADC10SREF_0 +ADC10INCH_3;//VREF = VCC,SAMPLE CHANNEL = CH5
ADC10CTL0 |= ADC10ON + ADC10ENC + ADC10SC; //ENABLE ADC AND START
ADC10IE |= ADC10IE0;
#ifdef DMA_TRANSFER
DMA_Init((uint)ADC_DMA_SA,(uint)ADC_DMA_DA,ADC_DMA_SZ);//初始化DMA,设置为重复的块搬移模式
#endif
_EINT();
}
需要注意的地方在于板子的CH4接触的是NTC温度电阻,而根据电路的设计,需要使能该处的电源,
因此在配置IO的时候,除了使能IO的ADC采样通道功能外,还需要配置P2.7输出高电平。(在此自己还是一直犯了忘记开总中断
初始化配置之后,就要开始对中断进行编写
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISP(void)
{
switch(__even_in_range(ADC10IV,12))
{
case 2:break;
case 4:break;
case 6:break;
case 8:break;
case 10:break;
case 12://CONVERSION IS CONPLETE
{
#ifdef DMA_TRANSFER
*ADC_DMA_SA = ADC10MEM0;
#else
ADCRegResult = ADC10MEM0;
#endif
ADCOverFlag = 1;
DMA1CTL |= DMAREQ;
// ADC10IFG &= ~ADC10IFG0;
}
break;
default: break;
}
__bic_SR_register_on_exit(LPM4_bits);
}
关于中断的函数,用了__even_in_range(ADC10IV,12)的一个函数,在TI的例程里面,查询中断标志的实现大多是采用这一方式,该函数的用法是查询ADC10IV中的0-12的偶数位是否被置位,是的话返回ADC10IV的值。。这样能够提高switch的效率。
还有一个要注意的问题是假如在主函数中进入
模式,那么在除了定时器中断的其余中断函数中,需要退出该低功耗模式,否则下次将无法进入中断。。
最后就是对采样的数据进行处理,换算成电压值
void ADC10_Handle(void)
{
static unsigned char i = 0;//记录
if(Sys50X_ms && ADCOverFlag)//取值时间到,同时采样结束
{
Sys50X_ms = 0;
ADCOverFlag = 0;
#ifdef DMA_TRANSFER
ADCRegSum += *ADC_DMA_DA;
#else
ADCRegSum += ADCRegResult;
#endif
i++;
if(i >= ADCBufLen)
{
i = 0;
ADCRegSum = ADCRegSum>>3;
ADCValue = ADCRegSum*0.003519;
LCD_Write_Float(2,0,ADCValue);
ADCRegSum = 0;//清除总和,重新存值
LED7_TURN;
}
}
}
然后为了也顺便学习DMA,在进行ADC的采样值读取过程中,对DMA也进行了初始化,在程序中加入宏“DMA_TRANSFER”,可根据需要选择是否编译。。