在开发板的例程中,配有相应的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。
图1 运行结果
但需要指出的是,该采集过程似乎只执行一次就停止了,而不是持续的输出采集结果。
若想得到下一个采集值,就只能再次复位以触发事件来进行采集,见图2所示。
另外,在实际测试时发现板上P14和P15的位置似乎是相互标错了位置!
此外,有些让人不解的是明明所用的是for(i=2;i<8;i++)循环,为何却只采集了3个引脚的模拟信号?莫非所用的是差分式采集?
若该数据采集程序能实现持续的数据采集,则可以为其配置相应的模拟量传感器来感知外部的状态变化,例如使用土壤湿度传感器、气体传感器及压力传感器。
图2 复位获得采集值
例程的编程思想与常规的编程思想差异较大,读其程序就像是在兜圈子,实在令人费解!
感谢分享,继续加油
引用: Jacktang 发表于 2021-11-22 09:25 这个采集过程似乎只执行一次就停止了,不是持续的输出采集结果,这个是怎么原因
这个我个人觉得,是楼主没有看手册哈,应该是没有关闭进入休眠模式那个宏定义
引用: jinglixixi 发表于 2021-11-22 09:52 例程的编程思想与常规的编程思想差异较大,读其程序就像是在兜圈子,实在令人费解!
可能是OSAL的缘故,因为在osal_start这个函数里面是一个死循环,不断的轮询已有的任务。
osal是事件触发型的模拟操作系统。用在蓝牙上面就可以实现低功耗。具体和中断有什么区别我也没弄懂