[分享] 【安信可蓝牙开发板PB-02-Kit测评】A/D数据采集及测试

jinglixixi   2021-11-20 10:18 楼主

在开发板的例程中,配有相应的A/D转换程序。为了掌握和学习其编程方法,故对其功能进行了测试。

该例程的主程序为:

int  main(void) 
{    
         // init global configuration of SOC
         int rrn = __return_address();
         g_system_clk = SYS_CLK_XTAL_16M;
         osal_mem_set_heap((osalMemHdr_t *)g_largeHeap, LARGE_HEAP_SIZE);
         init_config();
         hal_pwrmgr_init();
         hal_rfphy_init(); 
         hal_init();
         LOG("%x\n", rrn);
         app_main();    
}

该程序为了功能的实现,又从中调用了函数app_main(),其内容为:

int app_main(void)
{
    /* Initialize the operating system */
    osal_init_system();
    osal_pwrmgr_device( PWRMGR_BATTERY );
    /* Start OSAL */
    osal_start_system(); // No Return from here
    return 0;
}

其实,最终实现数据采集功能的是初始化函数hal_adc_init()和采集处理函数adc_evt(),其A/D数据采集功能则是以事件的方式来实现的。

所涉及的相应函数为:

void hal_adc_init(void) {
    mAdc_init_flg = TRUE;
    hal_pwrmgr_register(MOD_ADCC,NULL,adc_wakeup_hdl);
    clear_adcc_cfg();
}

 

static void adc_evt(adc_Evt_t* pev)
{
         float value = 0;
         int i = 0;
         bool is_high_resolution = FALSE;
         bool is_differential_mode = FALSE;
         if((pev->type != HAL_ADC_EVT_DATA) || (pev->ch < 2))
              return;
         osal_memcpy(adc_debug[pev->ch-2],pev->data,2*(pev->size));
         channel_done_flag |= BIT(pev->ch);
         if(channel_done_flag == adc_cfg.channel)
         {                        
              for(i=2;i<8;i++)
              {
                    if(channel_done_flag & BIT(i)) //2=0010 3=0011  4=0100 5=0101  6=0110 7=0111
                    {
                        is_high_resolution = (adc_cfg.is_high_resolution & BIT(i))?TRUE:FALSE;
                        is_differential_mode = (adc_cfg.is_differential_mode & BIT(i))?TRUE:FALSE;
                        value = hal_adc_value_cal((adc_CH_t) i,adc_debug[i-2], pev->size, is_high_resolution,is_differential_mode);
                               if(i<7)
                                 LOG("P%d %d mv ",(i+9),(int)(value*1000));   // i=2 3 4 5 6
                               else
                                 LOG("P%d %d mv ",(20),(int)(value*1000));    // i=7
                    }
               }
               LOG(" mode:%d \n",adc_cfg.is_continue_mode);
               channel_done_flag = 0;
               if(adc_cfg.is_continue_mode == FALSE)
               {
                    osal_start_timerEx( adcDemo_TaskID, adcMeasureTask_EVT,500);
               }
         }
}

经程序的编译和下载,其执行结果如图1所示。

从结果可以看出,它仅对3个引脚的模拟信号进行了采集,这3个引脚分别为P14、P15和P20。

image-20211120101403-1.png  

图1 运行结果

但需要指出的是,该采集过程似乎只执行一次就停止了,而不是持续的输出采集结果。

若想得到下一个采集值,就只能再次复位以触发事件来进行采集,见图2所示。

另外,在实际测试时发现板上P14和P15的位置似乎是相互标错了位置!

此外,有些让人不解的是明明所用的是for(i=2;i<8;i++)循环,为何却只采集了3个引脚的模拟信号?莫非所用的是差分式采集?

若该数据采集程序能实现持续的数据采集,则可以为其配置相应的模拟量传感器来感知外部的状态变化,例如使用土壤湿度传感器、气体传感器及压力传感器。

image-20211120101403-2.png  

图2 复位获得采集值

回复评论 (5)

这个采集过程似乎只执行一次就停止了,不是持续的输出采集结果,这个是怎么原因

点赞  2021-11-22 09:25

例程的编程思想与常规的编程思想差异较大,读其程序就像是在兜圈子,实在令人费解!

点赞  2021-11-22 09:52

感谢分享,继续加油

点赞  2021-11-22 22:46
引用: Jacktang 发表于 2021-11-22 09:25 这个采集过程似乎只执行一次就停止了,不是持续的输出采集结果,这个是怎么原因

这个我个人觉得,是楼主没有看手册哈,应该是没有关闭进入休眠模式那个宏定义

点赞  2021-11-23 22:48
引用: jinglixixi 发表于 2021-11-22 09:52 例程的编程思想与常规的编程思想差异较大,读其程序就像是在兜圈子,实在令人费解!

可能是OSAL的缘故,因为在osal_start这个函数里面是一个死循环,不断的轮询已有的任务。

osal是事件触发型的模拟操作系统。用在蓝牙上面就可以实现低功耗。具体和中断有什么区别我也没弄懂

点赞  2022-3-24 09:51
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复