ADC作为片上必备外设有着超高的使用率.虽然一般是10位,12位但在不太严格的场合足够使用.
雅特力也不例外,其片上内嵌1个12位的ADC ,有15个外部通道和3个内部通道(温度传感器、 内部参考电压、和VSSA) ,可以实现单次或扫描转换。支持DMA,模拟看门狗和触发转换.其时钟最高可到28MHz,仅需0.5微秒.
在at32_board.c中增加ADC的初始化代码.
/*
* ADC初始化
* 通道3
* PA3
*/
void ADCX_Init(void)
{
RCC_ADCCLKConfig(RCC_APB2CLK_Div6); //ADC时钟6分频
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_ADC1 , ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOA , ENABLE);
GPIO_InitType GPIO_InitStructure;
ADC_InitType ADC_InitStructure;
/* GPIO配置*/
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_3 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ADC1 配置 */
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanMode = DISABLE;
ADC_InitStructure.ADC_ContinuousMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrig = ADC_ExternalTrig_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NumOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC采样通道和采样时间 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_71_5);
//转换完成中断
ADC_INTConfig(ADC1, ADC_INT_EC, ENABLE);
/* 使能 ADC1 */
ADC_Ctrl(ADC1, ENABLE);
/* 校准ADC */
ADC_RstCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
/* 启动ADC转换 */
ADC_SoftwareStartConvCtrl(ADC1, ENABLE);
}
at32_board.h中声明一下void ADCX_Init(void);然后添加到
void rt_hw_board_init()
{
/* System Clock Update */
SystemCoreClockUpdate();
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* 串口1初始化*/
UART_Print_Init(115200);
//ADC初始化
ADCX_Init();
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
在main中初始化线程控制块,及线程入口函数.
/*
*************************************************************************
* 变量
*************************************************************************
*/
//ADC转换值
uint16_t ADC_value;
/* 定义线程栈4字节对齐 */
ALIGN(RT_ALIGN_SIZE)
/* 定义线程控制块 */
static struct rt_thread ADC_thread;
/* 定义线程栈大小 */
static rt_uint8_t ADC_stack[192];
/*
*************************************************************************
* 函数声明
*************************************************************************
*/
static void ADC_thread_entry(void *parameter);
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Main program
* @param None
* @retval None
*/
int main(void)
{
rt_err_t result;
/* 初始化ADC线程控制块 */
result = rt_thread_init(&ADC_thread,
"ADC",
ADC_thread_entry,
RT_NULL,
(rt_uint8_t *)&ADC_stack[0],
sizeof(ADC_stack),
5,
5);
if (result == RT_EOK)
{
rt_thread_startup(&ADC_thread);
}
return 0;
}
static void ADC_thread_entry(void *parameter)
{
while (1)
{
if(ADC_GetINTStatus(ADC1, ADC_INT_EC) != RESET){
ADC_value=ADC_GetConversionValue(ADC1);
rt_kprintf("ADC_value: %d \r\n",ADC_value);
}
rt_thread_mdelay(500);
/* 启动ADC转换 */
ADC_SoftwareStartConvCtrl(ADC1, ENABLE);
}
}
由于rt_kprintf不支持输出浮点数这里就直接输出转换后的值了.
在配置线程栈大小时候可以先大致给一个,然后在控制台中用ps命令查看一下栈使用率,一般维持在七十多比较好.为了方便截图这里暂时断开连接了.
旋转电位器可以看到转换值的变化
硬件连接
|