Wi-Fi 设备、蜂窝设备、WuKongAI、开发板、TuyaOS 移植等
-
feige2023
- Posts: 38
- Joined: 2024年 May 31日 17:26
【1】tuyaOS版本:3.11.11
【2】问题描述:
将ADC采样频率设置为8000,每次连续采64个数据点。每隔一段时间,通过tkl_adc_read_data读取64个数据点的采样值,用IO,测量采样前后的时间。发现调用tkl_adc_read_data会导致IO阻塞18.5ms左右。
具体参考图片测试。
其中相关的ADC代码如下:
特别说明
1.已经在driver/tkl_adc.c中将ADC_BUF_SIZE_MIN配置为65,能保证ADC连续采64次。
2.哪怕我将ADC配置连续采样数量调整为4,调用tkl_Adc_read_data也需要18.5ms左右
Code: Select all
#define CONFIG_BSP_ADC_SAMPLE_TIMES 64
static uint16_t adc_buf[CONFIG_BSP_ADC_SAMPLE_TIMES];
static int init(void)
{
OPERATE_RET ret;
const TUYA_ADC_BASE_CFG_T adc_cfg={
.ch_list.data = 1<<CONFIG_BSP_ADC_CHANNEL,
.ch_nums = 1,
.width = 12,
.mode = TUYA_ADC_CONTINUOUS,
.type = TUYA_ADC_INNER_SAMPLE_VOL,
.conv_cnt = CONFIG_BSP_ADC_SAMPLE_TIMES,
.freq = 8000,
};
ret = tkl_adc_init(CONFIG_BSP_ADC_NUM,&adc_cfg);
if(ret != OPRT_OK){
ELOG("adc init fail:%d");
return 1;
}else{
ILOG("adc init success");
}
return 0;
}
/// @brief 定时采集
/// @param
static void handler(void)
{
OPERATE_RET ret;
uint32_t adc[CONFIG_BSP_ADC_SAMPLE_TIMES];
bsp_gpio_test_ctrl(3,1);
ret = tkl_adc_read_data(CONFIG_BSP_ADC_NUM,adc,CONFIG_BSP_ADC_SAMPLE_TIMES);
bsp_gpio_test_ctrl(3,0);
if(ret!=OPRT_OK){
ELOG("adc read fail:%d",ret);
return ;
}
for(int i=0;i<CONFIG_BSP_ADC_SAMPLE_TIMES;i++){
adc_buf[i] = (uint16_t)(adc[i]);
}
}
以下是ADC报错的问题,我程序中仅有一个ADC采集任务,会出现偶尔ADC打开失败的问题,请问需要如何解决?
(代码中handler(void)函数体)
-
JSHANG
- Posts: 79
- Joined: 2023年 Jul 9日 17:45
问题1:本地复现,连续采样64个数据是要这么长时间;T1 ADC精度是准确的,不需要你采样多个再计算处理; 是否可以换一种方式,你可以一个一个的采,保存到你的数组里面,采样一次的时间在1ms左右;也可以尝试修改tkl_adc_init函数中的参数:
adc_desc.pre_div = 0;
adc_desc.samp_rate = 0x4; 或 adc_desc.pre_div = 0; adc_desc.samp_rate = 0; 来提高采样频率;
问题2: 报错是因为底层采样中断冲突了导致的,正常的,代码处理过滤掉就可以了。
-
feige2023
- Posts: 38
- Joined: 2024年 May 31日 17:26
问题1
问题1:本地复现,连续采样64个数据是要这么长时间;T1 ADC精度是准确的,不需要你采样多个再计算处理; 是否可以换一种方式,你可以一个一个的采,保存到你的数组里面,采样一次的时间在1ms左右;也可以尝试修改tkl_adc_init函数中的参数:
adc_desc.pre_div = 0;
adc_desc.samp_rate = 0x4; 或 adc_desc.pre_div = 0; adc_desc.samp_rate = 0; 来提高采样频率;
我们是要做本地音频分析的,所以需要8KHZ音频采样数据,这么说,tkl_adc_init传入的TUYA_ADC_BASE_CFG_T 结构体中的freq是没有生效的?并不是按照传入的采样频率采样?
pre_div=0时,是按照8KHZ采样率吗?
能否说明一下adc_desc.prev_div和samp_rate跟实际采样率的关系?
-
JSHANG
- Posts: 79
- Joined: 2023年 Jul 9日 17:45
是的,上面的设置的频率没用;
samp_rate 指的是每间隔N次采样点,完成一次“有效采样”
pre_div 用于控制采样时钟频率; 计算公式: 26M/(pre_div+1)
-
feige2023
- Posts: 38
- Joined: 2024年 May 31日 17:26
是的,上面的设置的频率没用;
samp_rate 指的是每间隔N次采样点,完成一次“有效采样”
pre_div 用于控制采样时钟频率; 计算公式: 26M/(pre_div+1)
非常感谢大佬解答,
我在tkl_adc.c中的库看到配置如下:
adc_desc.pre_div = 4;
adc_desc.samp_rate = 0x8;
采样个数为65,根据您的计算公式:
采样时钟为:26M/5≈0.192us,
假定ADC采样一次需要k个转换周期,
则采样单个通道需要的时间为(单位us):0.192 * 8 * k=1.536 * k(us),采样65次为:65 * 1.536 * k=99.84 * k(us),测量得到的是18.5ms,则k=18.5 * 1000/99.84=185.3≈185,即ADC单次转换周期为185个时钟周期?
这个采样65个点所需的时间是怎么算出来的哈?
或者是否有相关文档进行说明的。
非常感谢大佬。