板子依旧是英倍特的EK-SAM3S。ADC部分的原理图如下:
PB1是一个复用引脚,在这里被用作AD功能,对应芯片上的AD5。即,使用片内ADC的5通道测VR1上2号引脚的电压。
实验采用了SysTick定时器产生中断方式来采集ADC数据。SysTick中断发生时,开启ADC转换。ADC转换结束时,产生中断,在ADC中断处理函数中读取ADC采集到的数据。转换后,通过UART输出,到PC端显示。
SysTick和ADC的中断处理函数如下:
uint32_t time_stamp = 0;
WEAK void SysTick_Handler( void )
{
uint32_t status;
time_stamp++;
/* simply to get 1s interval*/
if (time_stamp % 1000 == 0) //1秒采集一次ADC数据
{
status = ADC_GetStatus( ADC ) ;
/* if conversion is done*/
if ( (status & ADC_ISR_EOC5) == ADC_ISR_EOC5 )
{
ADC_StartConversion( ADC ) ;//开启ADC转换
}
}
}
/**
* \brief Default SUPC interrupt handler for ADC.
*/
WEAK void ADC_IrqHandler( void )
{
uint32_t status;
status = ADC_GetStatus(ADC);
if ( (status & ADC_ISR_RXBUFF) == ADC_ISR_RXBUFF )
{
conversionDone = 1; //设置转换完成标志
ADC_ReadBuffer( ADC, adc_values, 1 ) ;
}
}
主函数:
int main()
{
int i;
WDT_Disable(WDT);
SysTick_Config(BOARD_MCK / 1000); //配置SysTick
ADC_Initialize(ADC,ID_ADC); //初始化ADC
ADC_cfgFrequency(ADC,15,4);
ADC_check(ADC,BOARD_MCK);
ADC_EnableChannel(ADC,ADC_CHANNEL_5); //使能5号通道 PB1
NVIC_EnableIRQ(ADC_IRQn); //使能ADC中断
ADC_StartConversion(ADC);
ADC_ReadBuffer(ADC,adc_values,BUFFER_SIZE);
ADC_EnableIt(ADC,ADC_IER_RXBUFF);
while(1)
{
while(!conversionDone);//等待转换完成标志
if ( conversionDone )
{
for ( i = 0 ; i < BUFFER_SIZE ; i++ )
{
printf( "Vol:%d mv\r\n", (adc_values[i] * 3300 /4095) ) ; //通过串口输出电压值
}
conversionDone = 0 ;
}
}
}
连上串口线,PC端会看到一些电压数据发过来。转动变阻器,可以看到电压值会不断地变化,变阻器转到底,辉县市0mv和3300mv。说明咱们测量的还凑合了。