AT32F421测评
<p><span style="font-size:24px;"> ADC作为片上必备外设有着超高的使用率.虽然一般是10位,12位但在不太严格的场合足够使用.</span></p><p><span style="font-size:24px;">雅特力也不例外,其片上内嵌1个12位的ADC ,有15个外部通道和3个内部通道(温度传感器、 内部参考电压、和VSSA) ,可以实现单次或扫描转换。支持DMA,模拟看门狗和触发转换.其时钟最高可到28MHz,仅需0.5微秒.</span></p>
<p><span style="font-size:24px;"> 在at32_board.c中增加ADC的初始化代码.</span></p>
<pre>
<code>/*
* 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);
}
</code></pre>
<p><span style="font-size:24px;">at32_board.h中声明一下void ADCX_Init(void);然后添加到</span></p>
<pre>
<code>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
}</code></pre>
<p><span style="font-size:24px;"> 在main中初始化线程控制块,及线程入口函数.</span></p>
<pre>
<code> /*
*************************************************************************
* 变量
*************************************************************************
*/
//ADC转换值
uint16_t ADC_value;
/* 定义线程栈4字节对齐 */
ALIGN(RT_ALIGN_SIZE)
/* 定义线程控制块 */
static struct rt_thread ADC_thread;
/* 定义线程栈大小 */
static rt_uint8_t ADC_stack;
/*
*************************************************************************
* 函数声明
*************************************************************************
*/
static void ADC_thread_entry(void *parameter);
/**
* @brief Main program
* @paramNone
* @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,
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);
}
}
</code></pre>
<p><span style="font-size:24px;"> 由于rt_kprintf不支持输出浮点数这里就直接输出转换后的值了.</span></p>
<p><span style="font-size:24px;"> 在配置线程栈大小时候可以先大致给一个,然后在控制台中用ps命令查看一下栈使用率,一般维持在七十多比较好.为了方便截图这里暂时断开连接了.</span></p>
<p><span style="font-size:24px;">旋转电位器可以看到转换值的变化</span></p>
<p></p>
<p></p>
<p><span style="font-size:24px;">硬件连接</span></p>
<p></p>
<p> </p>
<p> </p>
<p>10位的ADC平时足够用了</p>
<p>是的,这个rt_kprintf不支持输出浮点数</p>
<p>期待下来的楼主测评</p>
<p>针对一个外设的评测挺好的,期待后续。</p>
<p>谢谢分享,如果有标准AD值和采样之间的精度对比就好了</p>
freebsder 发表于 2021-5-12 09:49
谢谢分享,如果有标准AD值和采样之间的精度对比就好了
<p> </p>
<p><span style="font-size:24px;">首先说明一下我用的表是手持三位半的国产垃圾表,这种小电压精度还是差点意思的,第一张图是600mv档,第二张图是6v档.其次ADC外部我没加RC所以adc采到的精度也有误差具体多少就不知道了,反正家里是没条件折腾.</span></p>
<p><span style="font-size:24px;">万用表是每秒采集只有几次所以ADC我是采集4次算的平均值.大概600毫秒多一点更新一次.仅供参考.</span></p>
<p> </p>
<p> </p>
<p></p>
<p>看起来指标还行,你这表确实没听说过。。。</p>
页:
[1]