闪烁定义光学闪烁被定义为人造光源的脉动或波动的光现象。
在低频闪烁中,光是可见的(人眼能够察觉光的闪烁)。超过100 hz的光学闪烁对于人眼来说不再可见,但仍然存在,可能对人体产生影响。
大多数类型的人造光源在连接到电力主网(家庭或商业办公室)时会发出闪烁,这主要取决于国家的电力频率,通常是50 hz或60 hz。
由于电流在光源中的交替流动,所有人造光源都会分别在50 hz和60 hz电力主网下发出100 hz或120 hz的闪烁频率。
为了消除可见的闪烁并减少对人体的影响,大多数发光二极管(led)使用脉冲宽度调制(pwm)调光方法,以实现更高的闪烁频率。
vd6283传感器可以检测光的闪烁频率,最高可达2 khz。
最近在弄st的课程,需要样片的可以加群申请:615061293 。
视频教学https://www.bilibili.com/video/bv1fh4y1r7as/
样品申请https://www.wjx.top/vm/ohckxjk.aspx#px#)
源码下载https://download.csdn.net/download/qq_24312945/88394817
开发板设置在手册种给出了,闪烁手册可以查看an5639,资料链接如下。https://www.st.com/content/ccc/resource/technical/document/application_note/group1/9f/7e/8c/ce/36/85/4c/08/dm00776948/files/dm00776948.pdf/jcr:content/translations/en.dm00776948.pdf
在an5639手册中,需要对sb3进行连接。
同时gpio2需要接到mcu的adc通道中。
查看x-nucleo-6283a1手册,可以看到vd6283tx的gpio2连接到mcu的adc端口0-2。
在vd6283tx-satel中,可以看到vd6283tx通过sb3连接到了aflr_1v8。
需要将aflr_1v8接到开发板的a0端口中。
开发板选择这里使用nucleo-f401re 开发板。
iic配置
串口配置
开启x-cube-als软件包
时钟树配置
adc使用定时器触发采样在app_als_adc_utils.c中,定义了adc使用的频率,为8000hz。
定时器的arr设置为10500-1,那么定时器频率为8000hz。
trigger event selection :update event 定时器自动更新。
配置adc检测vd6283tx的gpio2管脚的ad值。
设置触发方式为外部触发,选择刚刚配置的tim2,触发方式为上升沿触发。
开启中断。
keil配置
fft代码配置arm_cortexm4lf_math.lib 库包含了一系列数学函数,特别是适用于基于cortex-m4和cortex-m7处理器的浮点运算单元的优化数学例程。这些例程涵盖了常见的数学运算,如信号处理、滤波、变换等。
arm_math.h 这个头文件包含了cmsis-dsp库的函数声明、宏定义和结构体定义等,可以通过包含这个头文件,使用库中提供的各种数学函数,包括信号处理、滤波、变换等。
添加arm_cortexm4lf_math.lib文件。
同时导入arm_math.h文件。
app_x-cube-als.c由于需要进行fft算法,所以需要添加对应数学头文件。
#define arm_math_cm4#include arm_math.h#include app_als_adc_utils.h添加对应的函数申明。
#define flk_channel (5u)/* * increasing the value of the flk_data_size symbol will increase * processing time, flicker accuracy and memory footprint */#define flk_data_size (1024u)#define fft_size (flk_data_size)/* private variables ---------------------------------------------------------*/static uint8_t is_quit_requested;static uint8_t is_autogain_requested;static int16_t flk_data[flk_data_size];volatile uint8_t als_eventdetected;/* * the fft of a real n-point sequence has even symmetry in the frequency domain. * the second half of the data equals the conjugate of the first half flipped in frequency. * looking at the data, we see that we can uniquely represent the fft using only n/2 complex numbers. * these are packed into the output array in alternating real and imaginary components: * x = { real[0], imag[0], real[1], imag[1], real[2], imag[2] ... real[(n/2)-1], imag[(n/2)-1 } */static arm_rfft_fast_instance_f32 instance_fft;static float32_t fft_in[flk_data_size];static float32_t fft_out_tmp[fft_size];static float32_t fft_out[fft_size/2];/* * the fft of a real n-point sequence has even symmetry in the frequency domain. * the second half of the data equals the conjugate of the first half flipped in frequency. * looking at the data, we see that we can uniquely represent the fft using only n/2 complex numbers. * these are packed into the output array in alternating real and imaginary components: * x = { real[0], imag[0], real[1], imag[1], real[2], imag[2] ... real[(n/2)-1], imag[(n/2)-1 } */static arm_rfft_fast_instance_f32 instance_fft; static void mx_vd6283a1_analogflicker_process(void); static float32_t complex_abs(float32_t real, float32_t complex);static void init_fft(arm_rfft_fast_instance_f32 *instance, uint32_t size);static void perform_fft(arm_rfft_fast_instance_f32 *instance, int16_t *data, float32_t *ffti, float32_t *ffto, uint32_t size);static void find_flk_freq(uint32_t fs, float32_t *ffto, uint32_t *freq, uint8_t skip_dc, uint32_t size);static int32_t flicker_autogain(uint8_t instance, uint32_t *pappliedgain, uint32_t timeoutms);static void display_gain(uint32_t gain);在mx_vd6283a1_luxcct_init()函数中添加init_fft快速傅里叶变换初始化。
static void mx_vd6283a1_luxcct_init(void){ /* initialize virtual com port */ bsp_com_init(com1); printf(vd6283tx lux / cct examplenn); display_commands_banner(); /* initialize arm fft library */ init_fft(&instance_fft, fft_size); status = vd6283a1_light_sensor_init(light_sensor_instance_0); if (status) { printf(vd6283a1_light_sensor_init failedn); while(1); }}初始化完毕之后,添加频率获取函数。
static void mx_vd6283a1_analogflicker_process(void){ uint32_t fs; /* sampling frequency */ uint32_t pos = 0; uint32_t flk_freq = 0; uint32_t index; uint32_t current_gain; uint32_t current_exposure; /* initialize exposure time */ vd6283a1_light_sensor_setexposuretime(light_sensor_instance_0, 100000); vd6283a1_light_sensor_getexposuretime(light_sensor_instance_0, ¤t_exposure); printf(exposure set to %lu usn, (unsigned long)current_exposure); /* initialize gain */ flicker_autogain(light_sensor_instance_0, ¤t_gain, 1); printf(channel %u gain set to, flk_channel); display_gain(current_gain); status = als_adc_start(&fs); if (status) { printf(adc start failedn); while (1); } vd6283a1_light_sensor_startflicker(light_sensor_instance_0, flk_channel, light_sensor_flicker_analog); while (!is_quit_requested) { status = als_adc_get_frame(&flk_data[pos], &index); /* fill the adc frame buffer */ if (status == 0) { pos += adc_frame_size; } /* if the adc frame buffer is full, then process it */ if (pos == flk_data_size) { perform_fft(&instance_fft, flk_data, fft_in, fft_out, fft_size); find_flk_freq(fs, fft_out, &flk_freq, 1, fft_size); pos = 0; /* reset position index */ printf(flicker freq: %4lu hzr, (unsigned long)flk_freq); fflush(stdout); if (is_autogain_requested == 1) { vd6283a1_light_sensor_stopflicker(light_sensor_instance_0); flicker_autogain(light_sensor_instance_0, ¤t_gain, 1); printf(channel %u gain set to, flk_channel); display_gain(current_gain); vd6283a1_light_sensor_startflicker(light_sensor_instance_0, flk_channel, light_sensor_flicker_analog); is_autogain_requested = 0; } } handle_cmd(get_key()); } als_adc_stop(); vd6283a1_light_sensor_stopflicker(light_sensor_instance_0); vd6283a1_light_sensor_deinit(light_sensor_instance_0); printf(quitting the demo...n); while (1);}在mx_x_cube_als_process函数中开启频率获取函数,关闭光强获取函数mx_vd6283a1_luxcct_process。
添加增益设置函数。
/* * @brief find and apply appropriate gain value depending on saturation value * @warning this function mustn't be called when a capture is ongoing */static int32_t flicker_autogain(uint8_t instance, uint32_t *pappliedgain, uint32_t timeoutms){ int32_t res; uint8_t i, j; uint8_t idx = 7; /* start with mid-table value */ const uint8_t sat_limit = 2; uint32_t saturation; /* duplicate 0x42ab to avoid 100x and keep multiples of 2 for array size */ const uint16_t gains[] = { 0x42ab, 0x42ab, 0x3200, 0x2154, 0x1900, 0x10ab, 0x0a00, 0x0723, 0x0500, 0x0354, 0x0280, 0x01ab, 0x0140, 0x0100, 0x00d4, 0x00b5 }; /* clip timeout value */ timeoutms = timeoutms == 0 ? 1 : timeoutms; timeoutms = timeoutms >= 100 ? 100 : timeoutms; for (i = 0; i <= 3; i++) { vd6283a1_light_sensor_setgain(instance, flk_channel, gains[idx]); vd6283a1_light_sensor_getgain(instance, flk_channel, pappliedgain); res = vd6283a1_light_sensor_startflicker(instance, flk_channel, light_sensor_flicker_analog); if (res) return res; /* read saturation value each ms so we can exit early if saturation detected */ for (j = 0; j sat_limit) break; } res = vd6283a1_light_sensor_stopflicker(instance); if (res) return res; /* update index to next value */ if (i) idx += saturation > sat_limit ? 1 < < (i - 1) : -(1 < sat_limit) idx++; } /* clip index if it reaches max value */ if (idx > 15) idx = 15; vd6283a1_light_sensor_setgain(instance, flk_channel, gains[idx]); res = vd6283a1_light_sensor_getgain(instance, flk_channel, pappliedgain); return res;}在下方添加函数的定义。
/* * @brief initilize arm rfft library */static void init_fft(arm_rfft_fast_instance_f32 *instance, uint32_t size){ arm_rfft_fast_init_f32(instance, size);}打印增益函数。
/* * @brief normalize, convert and dislay gain */static void display_gain(uint32_t gain){ uint32_t g = (gain * 100) / 256; printf( %3lu.%02lun, (unsigned long)g / 100, (unsigned long)(g % 100));}执行fft。
/* * @brief perform fft on the input buffer using arm rfft library */static void perform_fft(arm_rfft_fast_instance_f32 *instance, int16_t *flk, float32_t *ffti, float32_t *ffto, uint32_t size){ uint32_t i; uint32_t index = 0; /* copy the adc sampled signal into the fft input buffer * this allows to convert the data from int16_t to float32_t */ for (i = 0; i < size; i++) { ffti[i] = flk[i]; } /* perform the fft on the input buffer: * results are packed in a way so that even indexes contain real values * and odd indexes contain the complex value of each bin. * therefore the fft_output array contains fft_size / 2 bins */ arm_rfft_fast_f32(instance, ffti, fft_out_tmp, 0); /* calculate the magnitude for each bin from the temp fft output buffer */ for (i = 0; i < size; i += 2) { ffto[index] = complex_abs(fft_out_tmp[i], fft_out_tmp[i+1]); if (ffto[index] < 0) ffto[index] = 0; index++; }}查找峰值频率值。
/* * @brief find peak frequency value */static void find_flk_freq(uint32_t fs, float32_t *ffto, uint32_t *freq, uint8_t skip_dc, uint32_t size){ uint32_t i; uint32_t res; uint32_t index_max = 0; uint32_t limit = size / 2; float32_t max_value = -1; /* do not take account of the dc value if the flag skip_dc is set */ skip_dc ? (i = 1) : (i = 0); /* run through the output array to detect the peak */ for (; i max_value) { index_max = i; max_value = ffto[i]; } } /* convert index of the bin into frequency */ res = (index_max * fs) / size; /* return the result if the pointer is valid */ if (freq) { *freq = res; }}计算一个复数的绝对值。
/* * @brief compute absolute value of a complex number */static float32_t complex_abs(float32_t real, float32_t complex){ float32_t res; arm_sqrt_f32(real * real + complex * complex, &res); return res;}需要添加函数arm_cortexm4lf_math.lib 库包含了一系列数学函数,特别是适用于基于cortex-m4和cortex-m7处理器的浮点运算单元的优化数学例程。这些例程涵盖了常见的数学运算,如信号处理、滤波、变换等。
arm_math.h 这个头文件包含了cmsis-dsp库的函数声明、宏定义和结构体定义等,可以通过包含这个头文件,使用库中提供的各种数学函数,包括信号处理、滤波、变换等。
app_als_adc_utils.c功能主要包括启动和停止adc采样,获取采样数据,adc采样速度设置,以及处理相关的硬件中断。
app_als_adc_utils.h是app_als_adc_utils.c对应头文件。
我军无人机装备在角色上华丽变身,应用上多能互补
eID及RFID存在什么差异
骨传导耳机哪个牌子好,骨传导耳机品牌推荐
数字资产量化交易软件开发合约交易所开发
汇流环:优越性能下的关键电力传输元件
VD6283TX环境光传感器驱动开发(4)----移植闪烁频率代码
浅谈rfid射频识别技术的发展历程
人工智能新基建的情况怎么样
蓝牙无线运动耳机哪个牌子好、最适合运动的骨传导耳机
凌力尔特:2012混合动力及电动汽车技术普及率将提升
UDP简易聊天程序搭建方案
软组织成像不只是核磁共振,X光亦能见微知著
盘点2013:土洋厂商竞逐LTE 抢占手机芯片市场
存内计算成为下一代AI芯片的关键 中国半导体的春天未来或将到来
车载HUD(抬头显示器)的起源和发展
5至1.8V转换器无需磁性元件即可工作
LNG储罐裂纹泄漏的治理方法
新能源汽车产能过剩 代工是否有必要?
电源管理芯片企业杰华特微电子发生股东变更
基于BG822CX芯片的MPWC模块的应用研究