eew_Violet 发表于 2021-5-12 00:40

AT32F421测评

<p><span style="font-size:24px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADC作为片上必备外设有着超高的使用率.虽然一般是10位,12位但在不太严格的场合足够使用.</span></p>

<p><span style="font-size:24px;">雅特力也不例外,其片上内嵌1个12位的ADC&nbsp;,有15个外部通道和3个内部通道(温度传感器、 内部参考电压、和VSSA) ,可以实现单次或扫描转换。支持DMA,模拟看门狗和触发转换.其时钟最高可到28MHz,仅需0.5微秒.</span></p>

<p><span style="font-size:24px;">&nbsp; &nbsp; &nbsp; &nbsp;在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(&amp;GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_3 ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_Init(GPIOA, &amp;GPIO_InitStructure);
       
                /* ADC1 配置 */
        ADC_StructInit(&amp;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, &amp;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) &amp;&amp; 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;">&nbsp; &nbsp; &nbsp; &nbsp; 在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(&amp;ADC_thread,
                            "ADC",
                            ADC_thread_entry,
                            RT_NULL,
                            (rt_uint8_t *)&amp;ADC_stack,
                            sizeof(ADC_stack),
                            5,
                            5);
    if (result == RT_EOK)
    {
      rt_thread_startup(&amp;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;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于rt_kprintf不支持输出浮点数这里就直接输出转换后的值了.</span></p>

<p><span style="font-size:24px;">&nbsp; &nbsp; &nbsp; &nbsp;在配置线程栈大小时候可以先大致给一个,然后在控制台中用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>&nbsp;</p>

<p>&nbsp;</p>

Jacktang 发表于 2021-5-12 07:23

<p>10位的ADC平时足够用了</p>

<p>是的,这个rt_kprintf不支持输出浮点数</p>

<p>期待下来的楼主测评</p>

soso 发表于 2021-5-12 09:09

<p>针对一个外设的评测挺好的,期待后续。</p>

freebsder 发表于 2021-5-12 09:49

<p>谢谢分享,如果有标准AD值和采样之间的精度对比就好了</p>

eew_Violet 发表于 2021-5-16 13:08

freebsder 发表于 2021-5-12 09:49
谢谢分享,如果有标准AD值和采样之间的精度对比就好了

<p>&nbsp;</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>&nbsp;</p>

<p>&nbsp;</p>

<p></p>

freebsder 发表于 2021-5-16 21:33

<p>看起来指标还行,你这表确实没听说过。。。</p>
页: [1]
查看完整版本: AT32F421测评