guowenxue@gmail.com
10 days ago d0a1a87fc922734462d0caecf4b6bba8b936ee8b
ex1.buzzer-music/Board/miscdev.c
@@ -79,7 +79,7 @@
    if( which >= LedMax )
        return ;
    level = status==OFF ? GPIO_PIN_SET : GPIO_PIN_RESET;
    level = status==ON ? leds[which].active : !leds[which].active;
    HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level);
}
@@ -174,13 +174,15 @@
 *+----------------------+
 */
/* gcc 编译器中的 printf 函数将会调用 __io_putchar() 函数,实现最终的字符打印
 * keil编译器中的 printf 函数将会调用 fputc() 函数,实现最终的字符打印
 * 这里我们定义一个宏 PUTCHAR_PROTOTYPE 来兼容这两个编译器所需要的函数原型;
/* gcc 编译器的 printf 将会调用 __io_putchar() 函数,实现最终的字符打印
 * keil编译器的 printf 将会调用 fputc() 函数,实现最终的字符打印
 * 这里我们定义一个宏 PUTCHAR_PROTOTYPE 来兼容两个编译器所需要的函数原型
 *
 * 注意:
 *  1. Keil5 工程需要勾选:Options for Target -> Target -> Use MicroLIB
 *  2. Keil5 的编译器 armclang(AC6) 会定义 __GNUC__ 宏,而旧版 armcc(AC5) 则不会
 */
#if defined(__ARMCC_VERSION) /* MDK ARM Compiler */
FILE __stdout;
FILE __stdin;
#if defined(__ARMCC_VERSION) /*  */
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#elif defined(__GNUC__) /* GCC */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
@@ -268,6 +270,70 @@
    return 0;
}
/* ------------------- Lux 滤波相关参数 ------------------- */
#define LUX_SAMPLE_COUNT   10   /* 每次采集的原始样本数 */
#define LUX_TRIM_COUNT      2   /* 排序后,头尾各丢弃的样本数 */
/**
 * @brief  简单冒泡排序(数据量很小,不追求性能)
 */
static void sort_u32(uint32_t *arr, int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                uint32_t tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}
/**
 * @brief  多次采样光照度ADC值,排序后去掉两端的离群样本,再取平均
 * @param  lux: 输出参数,滤波后的光照度值
 * @retval 0 成功, -1 失败
 */
static int adc_read_lux_filtered(uint32_t *lux)
{
    uint32_t samples[LUX_SAMPLE_COUNT];
    uint32_t sum = 0;
    int valid_count;
    /* 多次采样光照度ADC值 */
    for (int i = 0; i < LUX_SAMPLE_COUNT; i++)
    {
        if (adc_read_channel(ADC_CHANNEL_15, &samples[i]) != 0)
            return -1;
    }
    /* 将多次采样的数据排序 */
    sort_u32(samples, LUX_SAMPLE_COUNT);
    /* 丢弃排序后头尾各 LUX_TRIM_COUNT 个可能的离群值 */
    valid_count = LUX_SAMPLE_COUNT - 2 * LUX_TRIM_COUNT;
    if (valid_count <= 0)
    {
        /* 参数配置不合理时兜底,避免除0 */
        valid_count = LUX_SAMPLE_COUNT;
        for (int i = 0; i < LUX_SAMPLE_COUNT; i++)
            sum += samples[i];
    }
    else
    {
        for (int i = LUX_TRIM_COUNT; i < LUX_SAMPLE_COUNT - LUX_TRIM_COUNT; i++)
            sum += samples[i];
    }
    *lux = sum / valid_count;
    return 0;
}
 /**
 * @brief  采集光照度与噪声值
 * @param  lux:   输出参数,采集到的光照度值
@@ -276,11 +342,11 @@
 */
int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy)
{
    if (adc_read_channel(ADC_CHANNEL_15, lux) != 0)
    if (adc_read_lux_filtered(lux) != 0)
        return -1;
    if (adc_read_noisy_peak(noisy, 50) != 0)
        return -1;
        return -2;
    return 0;
}