zoukankan      html  css  js  c++  java
  • 【STM32H7的DSP教程】第15章 DSP统计函数-标准偏差、均方根和方差

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547

    第15章       DSP统计函数-标准偏差、均方根和方差

    本期教程主要讲解统计函数中的标准偏差,均方根和方差的计算。

    15.1 初学者重要提示

    15.2 DSP基础运算指令

    15.3 标准偏差(Standard Deviation)

    15.4 均方根(RMS)

    15.5 方差(Variance)

    15.7 实验例程说明(MDK)

    15.8 实验例程说明(IAR)

    15.9 总结

    15.1 初学者重要提示

    1.   特别注意本章13.5.2小节的问题,定点数求解平方根,本章节几个函数的源码都有调用到求平方根。
    2.   正确理解RMS均方根(重要,推荐必读):http://www.armbbs.cn/forum.php?mod=viewthread&tid=95470

    15.2 DSP基础运算指令

    本章用到的DSP指令在前面章节都已经讲解过。

    15.3 标准偏差(Standard deviation)

    这部分函数用于计算标准偏差,公式描述如下:

    Result = sqrt((sumOfSquares – sum^2 / blockSize) / (blockSize - 1))

    其中:

    sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]

    sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]

     

    15.3.1 函数arm_std_f32

    函数原型:

    void arm_std_f32(

      const float32_t * pSrc,

            uint32_t blockSize,

            float32_t * pResult)

    函数描述:

    这个函数用于求32位浮点数的标准偏差。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出的标准偏差。

    15.3.2 函数arm_std_q31

    函数原型:

    void arm_std_q31(

      const q31_t * pSrc,

            uint32_t blockSize,

            q31_t * pResult)

    函数描述:

    这个函数用于求32位定点数的标准偏差。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出的标准偏差。

    注意事项:

    输入参数是1.31格式的,相乘后输出就是1.31*1.31 = 2.62格式,这种情况下,函数内部使用的64位累加器很容易溢出,并且这个函数不支持饱和运算。

    15.3.3 函数arm_std_q15

    函数原型:

    void arm_std_q31(

      const q31_t * pSrc,

            uint32_t blockSize,

            q31_t * pResult)

    函数描述:

    这个函数用于求15位定点数的标准偏差。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出的标准偏差。

    注意事项:

    输入参数是1.15格式,相乘后的的结果就是1.15*1.15 = 2.30格式,这种情况下,内部64位累加器的的格式就是34.30。最终的输出结果要截取到低15位数据,然后通过饱和运算最终输出数据格式1.15。

    15.3.4 使用举例

    程序设计:

    /*
    *********************************************************************************************************
    *    函 数 名: DSP_Std
    *    功能说明: 求标准偏差
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void DSP_Std(void)
    {
        float32_t pSrc[10] = {0.6557f, 0.0357f, 0.8491f, 0.9340f, 0.6787f, 0.7577f, 0.7431f, 0.3922f, 
    0.6555f, 0.1712f};
        float32_t pResult;
        uint32_t pIndex;
        
        q31_t pSrc1[10];
        q31_t pResult1;
        
        q15_t pSrc2[10];
        q15_t pResult2;
        
        
        arm_std_f32(pSrc, 10, &pResult);
        printf("arm_std_f32 : pResult = %f
    ", pResult);
    
        /*****************************************************************/
        for(pIndex = 0; pIndex < 10; pIndex++)
        {
             pSrc1[pIndex] = rand();
        }
        arm_std_q31(pSrc1, 10, &pResult1);
        printf("arm_std_q31 : pResult = %d
    ", pResult1);
        
        /*****************************************************************/
        for(pIndex = 0; pIndex < 10; pIndex++)
        {
             pSrc2[pIndex] = rand()%32768;
        }
        arm_std_q15(pSrc2, 10, &pResult2);
        printf("arm_std_q15 : pResult = %d
    ", pResult2);
        
        printf("******************************************************************
    ");
    }

    实验现象:

     

    15.4 均方根(RMS)

    这部分函数用于计算标准偏差,公式描述如下:

    Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]) / blockSize));

    15.4.1 函数arm_rms_f32

    函数原型:

    void arm_rms_f32(

      const float32_t * pSrc,

      uint32_t blockSize,

      float32_t * pResult)

    函数描述:

    这个函数用于求32位浮点数的均方根。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出来的均方根。

    15.4.2 函数arm_rms_q31

    函数原型:

    void arm_rms_q31(

      const q31_t * pSrc,

            uint32_t blockSize,

            q31_t * pResult)

    函数描述:

    这个函数用于求32位定点数的均方根。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出来的均方根。

    注意事项:

    输入参数是1.31格式的,相乘后输出就是1.31*1.31 = 2.62格式,这种情况下,函数内部使用的64位累加器很容易溢出,并且这个函数不支持饱和运算

    15.4.3 函数arm_rms_q15

    函数原型:

    void arm_rms_q15(

      const q15_t * pSrc,

            uint32_t blockSize,

            q15_t * pResult)

    函数描述:

    这个函数用于求16位定点数的均方根。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出来的均方根。

    注意事项:

    输入参数是1.15格式,相乘后的的结果就是1.15*1.15 = 2.30格式,这种情况下,内部64位累加器的的格式就是34.30。最终的输出结果要截取到低15位数据,然后通过饱和运算最终输出数据格式1.15。

    15.4.4 使用举例

    程序设计:

    /*
    *********************************************************************************************************
    *    函 数 名: DSP_RMS
    *    功能说明: 求均方根
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void DSP_RMS(void)
    {
        float32_t pSrc[10] = {0.7060f, 0.0318f, 0.2769f, 0.0462f, 0.0971f, 0.8235f, 0.6948f, 0.3171f, 
    0.9502f, 0.0344f};
        float32_t pResult;
        uint32_t pIndex;
        
        q31_t pSrc1[10];
        q31_t pResult1;
        
        q15_t pSrc2[10];
        q15_t pResult2;
        
        
        arm_rms_f32(pSrc, 10, &pResult);
        printf("arm_rms_f32 : pResult = %f
    ", pResult);
    
        /*****************************************************************/
        for(pIndex = 0; pIndex < 10; pIndex++)
        {
             pSrc1[pIndex] = rand();
        }
        arm_rms_q31(pSrc1, 10, &pResult1);
        printf("arm_rms_q31 : pResult = %d
    ", pResult1);
        
        /*****************************************************************/
        for(pIndex = 0; pIndex < 10; pIndex++)
        {
             pSrc2[pIndex] = rand()%32768;
        }
        arm_rms_q15(pSrc2, 10, &pResult2);
        printf("arm_rms_q15 : pResult = %d
    ", pResult2);
        printf("******************************************************************
    ");
    }

    实验现象:

     

    15.5 方差(Variance)

    这部分函数用于计算标准偏差,公式描述如下:

    Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] *

    pSrc[blockSize-1]) / blockSize));

    15.5.1 函数arm_var_f32

    函数原型:

    void arm_var_f32(

               const float32_t * pSrc,

                     uint32_t blockSize,

                     float32_t * pResult)

    函数描述:

    这个函数用于求32位浮点数的方差。

    函数参数:

    •   第1个参数源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是求解出来的方差。

    15.5.2 函数arm_var_q31

    函数原型:

    void arm_var_q31(

      const q31_t * pSrc,

            uint32_t blockSize,

            q31_t * pResult)

    函数描述:

    用于求32位定点数的。

    函数参数:

    •   第1个参数是源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是计算出来的方差。

    注意事项:

    输入参数是1.31格式的,相乘后输出就是1.31*1.31 = 2.62格式,这种情况下,函数内部使用的64位累加器很容易溢出,并且这个函数不支持饱和运算

    15.5.3 函数arm_var_q15

    函数原型:

    void arm_var_q15(

      const q15_t * pSrc,

            uint32_t blockSize,

            q15_t * pResult)

    函数描述:

    用于求16位定点数的方差。

    函数参数:

    •   第1个参数是源数据地址。
    •   第2个参数是源数据个数。
    •   第3个参数是计算出来的方差结果。

    注意事项:

    输入参数是1.15格式,相乘后的的结果就是1.15*1.15 = 2.30格式,这种情况下,内部64位累加器的的格式就是34.30。最终的输出结果要截取到低15位数据,然后通过饱和运算最终输出数据格式1.15。

    15.5.4 使用举例

    程序设计:

    /*
    *********************************************************************************************************
    *    函 数 名: DSP_Var
    *    功能说明: 求方差
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void DSP_Var(void)
    {
        float32_t pSrc[10] = {0.4387f, 0.3816f, 0.7655f, 0.7952f, 0.1869f, 0.4898f, 0.4456f, 0.6463f, 
    0.7094f, 0.7547f};
        float32_t pResult;
        uint32_t pIndex;
        
        q31_t pSrc1[10];
        q31_t pResult1;
        
        q15_t pSrc2[10];
        q15_t pResult2;
        
        
        arm_var_f32(pSrc, 10, &pResult);
        printf("arm_var_f32 : pResult = %f
    ", pResult);
    
        /*****************************************************************/
        for(pIndex = 0; pIndex < 10; pIndex++)
        {
             pSrc1[pIndex] = rand();
        }
        arm_var_q31(pSrc1, 10, &pResult1);
        printf("arm_var_q31 : pResult = %d
    ", pResult1);
        
        /*****************************************************************/
        for(pIndex = 0; pIndex < 10; pIndex++)
        {
             pSrc2[pIndex] = rand()%32768;
        }
        arm_var_q15(pSrc2, 10, &pResult2);
        printf("arm_var_q15 : pResult = %d
    ", pResult2);
        printf("******************************************************************
    ");
    }

    实验现象:

    15.6 Matlab求标准偏差,均方差和方差

    15.6.1 Matlab求标准偏差

    在matlab的命令窗口输入如下命令:

    a = rand(1,10)  %1行10列

    然后再通过命令std获得标准偏差: 

    std(a)

     

    15.6.2 Matlab求均方根

    在matlab的命令窗口输入如下命令:

    a = rand(1,10)  %1行10列

    然后再通过命令rms获得均方根。 

    rms(a)

     

    15.6.3 Matlab求方差

    在matlab的命令窗口输入如下命令:

    a = rand(1,10)  %1行10列

    然后再通过命令var获得方差。 

    var(a)

     

    15.7 实验例程说明(MDK)

    配套例子:

    V7-210_DSP统计运算(标准偏差,均方根和方差)

    实验目的:

    1. 学习统计运算(标准偏差,均方根和方差)

    实验内容:

    1. 启动一个自动重装软件定时器,每100ms翻转一次LED2。
    2. 按下按键K1, DSP求标准偏差。
    3. 按下按键K2, DSP求均方根。
    4. 按下按键K3, DSP求方差。

    使用AC6注意事项

    特别注意附件章节C的问题

    上电后串口打印的信息:

    波特率 115200,数据位 8,奇偶校验位无,停止位 1。

    详见本章的3.5  4.5,5.5小节。

    程序设计:

      系统栈大小分配:

     

      RAM空间用的DTCM:

     

      硬件外设初始化

    硬件外设的初始化是在 bsp.c 文件实现:

    /*
    *********************************************************************************************************
    *    函 数 名: bsp_Init
    *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
    *    形    参:无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    void bsp_Init(void)
    {
        /* 配置MPU */
        MPU_Config();
        
        /* 使能L1 Cache */
        CPU_CACHE_Enable();
    
        /* 
           STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
           - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
           - 设置NVIV优先级分组为4。
         */
        HAL_Init();
    
        /* 
           配置系统时钟到400MHz
           - 切换使用HSE。
           - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
        */
        SystemClock_Config();
    
        /* 
           Event Recorder:
           - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
           - 默认不开启,如果要使能此选项,务必看V7开发板用户手册第8章
        */    
    #if Enable_EventRecorder == 1  
        /* 初始化EventRecorder并开启 */
        EventRecorderInitialize(EventRecordAll, 1U);
        EventRecorderStart();
    #endif
        
        bsp_InitKey();        /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
        bsp_InitTimer();      /* 初始化滴答定时器 */
        bsp_InitUart();    /* 初始化串口 */
        bsp_InitExtIO();    /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */    
        bsp_InitLed();        /* 初始化LED */    
    }

      MPU配置和Cache配置:

    数据Cache和指令Cache都开启。配置了AXI SRAM区(本例子未用到AXI SRAM),FMC的扩展IO区。

    /*
    *********************************************************************************************************
    *    函 数 名: MPU_Config
    *    功能说明: 配置MPU
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void MPU_Config( void )
    {
        MPU_Region_InitTypeDef MPU_InitStruct;
    
        /* 禁止 MPU */
        HAL_MPU_Disable();
    
        /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
        HAL_MPU_ConfigRegion(&MPU_InitStruct);
        
        
        /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x60000000;
        MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;    
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
        
        HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
        /*使能 MPU */
        HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    }
    
    /*
    *********************************************************************************************************
    *    函 数 名: CPU_CACHE_Enable
    *    功能说明: 使能L1 Cache
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void CPU_CACHE_Enable(void)
    {
        /* 使能 I-Cache */
        SCB_EnableICache();
    
        /* 使能 D-Cache */
        SCB_EnableDCache();
    }

      主功能:

    主程序实现如下操作:

    •   启动一个自动重装软件定时器,每100ms翻转一次LED2。
    •   按下按键K1, DSP求标准偏差。
    •   按下按键K2, DSP求均方根。
    •   按下按键K3, DSP求方差。
    /*
    *********************************************************************************************************
    *    函 数 名: main
    *    功能说明: c程序入口
    *    形    参:无
    *    返 回 值: 错误代码(无需处理)
    *********************************************************************************************************
    */
    int main(void)
    {
        uint8_t ucKeyCode;        /* 按键代码 */
        
    
        bsp_Init();        /* 硬件初始化 */
        PrintfLogo();    /* 打印例程信息到串口1 */
    
        PrintfHelp();    /* 打印操作提示信息 */
        
    
        bsp_StartAutoTimer(0, 100);    /* 启动1个100ms的自动重装的定时器 */
    
        /* 进入主程序循环体 */
        while (1)
        {
            bsp_Idle();        /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
    
            /* 判断定时器超时时间 */
            if (bsp_CheckTimer(0))    
            {
                /* 每隔100ms 进来一次 */  
                bsp_LedToggle(2);
            }
    
            ucKeyCode = bsp_GetKey();    /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
            if (ucKeyCode != KEY_NONE)
            {
                switch (ucKeyCode)
                {
                    case KEY_DOWN_K1:            /* K1键按下,求标准偏差 */
                        DSP_Std();
                        break;
                        
                    case KEY_DOWN_K2:            /* K2键按下,求均方根 */
                        DSP_RMS();
                        break;
    
                    case KEY_DOWN_K3:            /* K3键按下,求方差 */
                        DSP_Var();
                        break;
    
                    default:
                        /* 其他的键值不处理 */
                        break;
                }
            }
        }
    }

    15.8 实验例程说明(IAR)

    配套例子:

    V7-210_DSP统计运算(标准偏差,均方根和方差)

    实验目的:

    1. 学习统计运算(标准偏差,均方根和方差)

    实验内容:

    1. 启动一个自动重装软件定时器,每100ms翻转一次LED2。
    2. 按下按键K1, DSP求标准偏差。
    3. 按下按键K2, DSP求均方根。
    4. 按下按键K3, DSP求方差。

    上电后串口打印的信息:

    波特率 115200,数据位 8,奇偶校验位无,停止位 1。

    详见本章的3.5  4.5,5.5小节。

    程序设计:

      系统栈大小分配:

     

      RAM空间用的DTCM:

     

      硬件外设初始化

    硬件外设的初始化是在 bsp.c 文件实现:

    /*
    *********************************************************************************************************
    *    函 数 名: bsp_Init
    *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
    *    形    参:无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    void bsp_Init(void)
    {
        /* 配置MPU */
        MPU_Config();
        
        /* 使能L1 Cache */
        CPU_CACHE_Enable();
    
        /* 
           STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
           - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
           - 设置NVIV优先级分组为4。
         */
        HAL_Init();
    
        /* 
           配置系统时钟到400MHz
           - 切换使用HSE。
           - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
        */
        SystemClock_Config();
    
        /* 
           Event Recorder:
           - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
           - 默认不开启,如果要使能此选项,务必看V7开发板用户手册第8章
        */    
    #if Enable_EventRecorder == 1  
        /* 初始化EventRecorder并开启 */
        EventRecorderInitialize(EventRecordAll, 1U);
        EventRecorderStart();
    #endif
        
        bsp_InitKey();        /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
        bsp_InitTimer();      /* 初始化滴答定时器 */
        bsp_InitUart();    /* 初始化串口 */
        bsp_InitExtIO();    /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */    
        bsp_InitLed();        /* 初始化LED */    
    }

      MPU配置和Cache配置:

    数据Cache和指令Cache都开启。配置了AXI SRAM区(本例子未用到AXI SRAM),FMC的扩展IO区。

    /*
    *********************************************************************************************************
    *    函 数 名: MPU_Config
    *    功能说明: 配置MPU
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void MPU_Config( void )
    {
        MPU_Region_InitTypeDef MPU_InitStruct;
    
        /* 禁止 MPU */
        HAL_MPU_Disable();
    
        /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
        HAL_MPU_ConfigRegion(&MPU_InitStruct);
        
        
        /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x60000000;
        MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;    
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
        
        HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
        /*使能 MPU */
        HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    }
    
    /*
    *********************************************************************************************************
    *    函 数 名: CPU_CACHE_Enable
    *    功能说明: 使能L1 Cache
    *    形    参: 无
    *    返 回 值: 无
    *********************************************************************************************************
    */
    static void CPU_CACHE_Enable(void)
    {
        /* 使能 I-Cache */
        SCB_EnableICache();
    
        /* 使能 D-Cache */
        SCB_EnableDCache();
    }

      主功能:

    主程序实现如下操作:

    •   启动一个自动重装软件定时器,每100ms翻转一次LED2。
    •   按下按键K1, DSP求标准偏差。
    •   按下按键K2, DSP求均方根。
    •   按下按键K3, DSP求方差。
    /*
    *********************************************************************************************************
    *    函 数 名: main
    *    功能说明: c程序入口
    *    形    参:无
    *    返 回 值: 错误代码(无需处理)
    *********************************************************************************************************
    */
    int main(void)
    {
        uint8_t ucKeyCode;        /* 按键代码 */
        
    
        bsp_Init();        /* 硬件初始化 */
        PrintfLogo();    /* 打印例程信息到串口1 */
    
        PrintfHelp();    /* 打印操作提示信息 */
        
    
        bsp_StartAutoTimer(0, 100);    /* 启动1个100ms的自动重装的定时器 */
    
        /* 进入主程序循环体 */
        while (1)
        {
            bsp_Idle();        /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
    
            /* 判断定时器超时时间 */
            if (bsp_CheckTimer(0))    
            {
                /* 每隔100ms 进来一次 */  
                bsp_LedToggle(2);
            }
    
            ucKeyCode = bsp_GetKey();    /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
            if (ucKeyCode != KEY_NONE)
            {
                switch (ucKeyCode)
                {
                    case KEY_DOWN_K1:            /* K1键按下,求标准偏差 */
                        DSP_Std();
                        break;
                        
                    case KEY_DOWN_K2:            /* K2键按下,求均方根 */
                        DSP_RMS();
                        break;
    
                    case KEY_DOWN_K3:            /* K3键按下,求方差 */
                        DSP_Var();
                        break;
    
                    default:
                        /* 其他的键值不处理 */
                        break;
                }
            }
        }
    }

    15.9 总结

    本期教程就跟大家讲这么多,有兴趣的可以深入研究这些函数源码的实现。

  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/armfly/p/12785145.html
Copyright © 2011-2022 走看看