32H7_海马s5近光可以直接换H7吗

32H7_海马s5近光可以直接换H7吗完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547第16章DSP功能函数-数据拷贝,数据填充和浮点转定点本期教程主要讲解功能函数中的数据拷贝,数据填充和浮点数转换为定点数。目录第16章DSP功能函数-数据拷贝,数据填充和浮点转定点16.1初学者重要提示16….

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

第16章       DSP功能函数-数据拷贝,数据填充和浮点转定点

本期教程主要讲解功能函数中的数据拷贝,数据填充和浮点数转换为定点数。

目录

第16章       DSP功能函数-数据拷贝,数据填充和浮点转定点

16.1 初学者重要提示

16.2 DSP基础运算指令

16.3 数据拷贝(copy)

16.3.1 函数arm_copy_f32

16.3.2 函数arm_copy_q31

16.3.3 函数arm_copy_q15

16.3.4 函数arm_copy_q7

16.3.5 使用举例

16.4 数据填充(Fill)

16.4.1 函数arm_fill_f32

16.4.2 函数arm_fill_q31

16.4.3 函数arm_fill_q15

16.4.4 函数arm_fill_q7

16.4.5 使用举例

16.5 浮点数转定点数(Float to Fix)

16.5.1 函数arm_float_to_q31

16.5.2 函数arm_float_to_q15

16.5.3 函数arm_float_to_q7

16.5.4 使用举例

16.6 实验例程说明(MDK)

16.7 实验例程说明(IAR)

16.8 总结


 

16.1 初学者重要提示

  1.   浮点数的四舍五入处理:http://www.armbbs.cn/forum.php?mod=viewthread&tid=95149
  2.   C库的浮点数四舍五入函数round,roundf,round使用说明:http://www.armbbs.cn/forum.php?mod=viewthread&tid=95156

16.2 DSP基础运算指令

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

16.3 数据拷贝(copy)

这部分函数用于数据拷贝,公式描述如下:

pDst[n] = pSrc[n];   0 <= n < blockSize

16.3.1 函数arm_copy_f32

函数原型:

void arm_copy_f32(

    const float32_t * pSrc,

    float32_t * pDst,

    uint32_t blockSize)

函数描述:

这个函数用于32位浮点数的复制。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是目的数据地址。
  •   第3个参数是复制的个数。

16.3.2 函数arm_copy_q31

函数原型:

void arm_copy_q31(

  const q31_t * pSrc,

        q31_t * pDst,

        uint32_t blockSize)

函数描述:

这个函数用于32位定点数的复制。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是目的数据地址。
  •   第3个参数是复制的个数。

16.3.3 函数arm_copy_q15

函数原型:

void arm_copy_q15(

  const q15_t * pSrc,

        q15_t * pDst,

        uint32_t blockSize)

函数描述:

这个函数用于16位定点数的复制。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是目的数据地址。
  •   第3个参数是复制的个数。

16.3.4 函数arm_copy_q7

函数原型:

void arm_copy_q7(

  const q7_t * pSrc,

        q7_t * pDst,

        uint32_t blockSize)

函数描述:

这个函数用于8位定点数的复制。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是目的数据地址。
  •   第3个参数是复制的个数。

16.3.5 使用举例

程序设计:

/*
*********************************************************************************************************
*    函 数 名: DSP_Copy
*    功能说明: 数据拷贝
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void DSP_Copy(void)
{
    float32_t pSrc[10] = {0.6557,  0.0357,  0.8491,  0.9340, 0.6787,  0.7577,  0.7431,  0.3922,  0.6555,  0.1712};
    float32_t pDst[10];
    uint32_t pIndex;
    
    q31_t pSrc1[10];
    q31_t pDst1[10];
    
    q15_t pSrc2[10];
    q15_t pDst2[10];
    
    q7_t pSrc3[10];
    q7_t pDst3[10];
    
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("pSrc[%d] = %f\r\n", pIndex, pSrc[pIndex]);
    }
    arm_copy_f32(pSrc, pDst, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_copy_f32: pDst[%d] = %f\r\n", pIndex, pDst[pIndex]);
    }

    /*****************************************************************/
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        pSrc1[pIndex] = rand();
        printf("pSrc1[%d] = %d\r\n", pIndex, pSrc1[pIndex]);
    }
    arm_copy_q31(pSrc1, pDst1, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_copy_q31: pDst1[%d] = %d\r\n", pIndex, pDst1[pIndex]);
    }
    /*****************************************************************/
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        pSrc2[pIndex] = rand()%32768;
        printf("pSrc2[%d] = %d\r\n", pIndex, pSrc2[pIndex]);
    }
    arm_copy_q15(pSrc2, pDst2, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_copy_q15: pDst2[%d] = %d\r\n", pIndex, pDst2[pIndex]);
    }
    /*****************************************************************/
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        pSrc3[pIndex] = rand()%128;
        printf("pSrc3[%d] = %d\r\n", pIndex, pSrc3[pIndex]);
    }
    arm_copy_q7(pSrc3, pDst3, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_copy_q7: pDst3[%d] = %d\r\n", pIndex, pDst3[pIndex]);
    }
    /*****************************************************************/
    printf("******************************************************************\r\n");
}

 

实验现象(部分截图):

32H7_海马s5近光可以直接换H7吗

16.4 数据填充(Fill)

这部分函数用于数据填充,公式描述如下:

pDst[n] = value;   0 <= n < blockSize

16.4.1 函数arm_fill_f32

函数原型:

void arm_fill_f32(

  float32_t value,

  float32_t * pDst,

  uint32_t blockSize)

函数描述:

这个函数用于填充32位浮点数。

函数参数:

  •   第1个参数是要填充的数值。
  •   第2个参数是要填充的数据地址。
  •   第3个参数是要填充的数据个数。

16.4.2 函数arm_fill_q31

函数原型:

void arm_fill_q31(

  q31_t value,

  q31_t * pDst,

  uint32_t blockSize)

函数描述:

这个函数用于填充32位定点数。

函数参数:

  •   第1个参数是要填充的数值。
  •   第2个参数是要填充的数据地址。
  •   第3个参数是要填充的数据个数。

16.4.3 函数arm_fill_q15

函数原型:

void arm_fill_q15(

  q15_t value,

  q15_t * pDst,

  uint32_t blockSize)

函数描述:

这个函数用于填充16位定点数。

函数参数:

  •   第1个参数是要填充的数值。
  •   第2个参数是要填充的数据地址。
  •   第3个参数是要填充的数据个数。

16.4.4 函数arm_fill_q7

函数原型:

void arm_fill_q7(

  q7_t value,

  q7_t * pDst,

  uint32_t blockSize)

函数描述:

这个函数用于填充8位定点数。

函数参数:

  •   第1个参数是要填充的数值。
  •   第2个参数是要填充的数据地址。
  •   第3个参数是要填充的数据个数。

16.4.5 使用举例

程序设计:

/*
*********************************************************************************************************
*    函 数 名: DSP_Fill
*    功能说明: 数据填充
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void DSP_Fill(void)
{
    float32_t pDst[10];
    uint32_t pIndex;
    q31_t pDst1[10];
    q15_t pDst2[10];
    q7_t pDst3[10];
    

    arm_fill_f32(3.33f, pDst, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_fill_f32: pDst[%d] = %f\r\n", pIndex, pDst[pIndex]);
    }

    /*****************************************************************/
    arm_fill_q31(0x11111111, pDst1, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_fill_q31: pDst1[%d] = %x\r\n", pIndex, pDst1[pIndex]);
    }
    /*****************************************************************/
    arm_fill_q15(0x1111, pDst2, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_fill_q15: pDst2[%d] = %d\r\n", pIndex, pDst2[pIndex]);
    }
    /*****************************************************************/
    arm_fill_q7(0x11, pDst3, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_fill_q7: pDst3[%d] = %d\r\n", pIndex, pDst3[pIndex]);
    }
    /*****************************************************************/
    printf("******************************************************************\r\n");
}

 

实验现象:

32H7_海马s5近光可以直接换H7吗

 

16.5 浮点数转定点数(Float to Fix)

浮点数转Q31公式描述:

pDst[n] = (q31_t)(pSrc[n] * 2147483648);   0 <= n < blockSize。

浮点数转Q15公式描述:

pDst[n] = (q15_t)(pSrc[n] * 32768);   0 <= n < blockSize

浮点数转Q7公式描述:

pDst[n] = (q7_t)(pSrc[n] * 128);   0 <= n < blockSize

16.5.1 函数arm_float_to_q31

函数原型:

void arm_float_to_q31(

  const float32_t * pSrc,

  q31_t * pDst,

  uint32_t blockSize)

函数描述:

这个函数用于将浮点数转换为32位定点数。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是转换后的数据地址。
  •   第3个参数是转换的次数。

注意事项:

  •   这个函数使用了饱和运算。
  •   输出结果的范围是[0x80000000 0x7FFFFFFF]。

16.5.2 函数arm_float_to_q15

函数原型:

void arm_var_q31(

  const q31_t * pSrc,

        uint32_t blockSize,

        q31_t * pResult)

函数描述:

这个函数用于将浮点数转换为16位定点数。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是转换后的数据地址。
  •   第3个参数是转换的次数。

注意事项:

  •   这个函数使用了饱和运算。
  •   输出结果的范围是[0x8000 0x7FFF]。

16.5.3 函数arm_float_to_q7

函数原型:

void arm_float_to_q7(

  const float32_t * pSrc,

  q7_t * pDst,

  uint32_t blockSize)

函数描述:

这个函数用于将浮点数转换为8位定点数。

函数参数:

  •   第1个参数源数据地址。
  •   第2个参数是转换后的数据地址。
  •   第3个参数是转换的次数。

注意事项:

  •   这个函数使用了饱和运算。
  •   输出结果的范围是[0x80 0x7F]。

16.5.4 使用举例

程序设计:

/*
*********************************************************************************************************
*    函 数 名: DSP_FloatToFix
*    功能说明: 浮点数转定点数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void DSP_FloatToFix(void)
{
    float32_t pSrc[10] = {0.6557,  0.0357,  0.8491,  0.9340, 0.6787,  0.7577,  0.7431,  0.3922,  0.6555,
                           0.1712};
    uint32_t pIndex;
    q31_t pDst1[10];
    q15_t pDst2[10];
    q7_t pDst3[10];
    
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("pSrc[%d] = %f\r\n", pIndex, pSrc[pIndex]);
    }
    
    /*****************************************************************/
    arm_float_to_q31(pSrc, pDst1, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_float_to_q31: pDst[%d] = %d\r\n", pIndex, pDst1[pIndex]);
    }
    
    /*****************************************************************/
    arm_float_to_q15(pSrc, pDst2, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_float_to_q15: pDst1[%d] = %d\r\n", pIndex, pDst2[pIndex]);
    }
    
    /*****************************************************************/
    arm_float_to_q7(pSrc, pDst3, 10);
    for(pIndex = 0; pIndex < 10; pIndex++)
    {
        printf("arm_float_to_q7: pDst2[%d] = %d\r\n", pIndex, pDst3[pIndex]);
    }
    /*****************************************************************/
    printf("******************************************************************\r\n");
}

 

实验现象:

32H7_海马s5近光可以直接换H7吗

16.6 实验例程说明(MDK)

配套例子:

V7-211_DSP功能函数(数据拷贝,数据填充和浮点转定点)

实验目的:

  1. 学习功能函数(数据拷贝,数据填充和浮点转定点)

实验内容:

  1. 启动一个自动重装软件定时器,每100ms翻转一次LED2。
  2. 按下按键K1, 串口打印函数DSP_Copy的输出结果。
  3. 按下按键K2, 串口打印函数DSP_Fill的输出结果。
  4. 按下按键K3, 串口打印函数DSP_FloatToFix的输出结果。

使用AC6注意事项

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

上电后串口打印的信息:

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

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

程序设计:

  系统栈大小分配:

32H7_海马s5近光可以直接换H7吗

  RAM空间用的DTCM:

32H7_海马s5近光可以直接换H7吗

  硬件外设初始化

硬件外设的初始化是在 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_Copy的输出结果
  •   按下按键K2, 串口打印函数DSP_Fill的输出结果
  •   按下按键K3, 串口打印函数DSP_FloatToFix的输出结果
/*
*********************************************************************************************************
*    函 数 名: 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_Copy();
                    break;
                    
                case KEY_DOWN_K2:            /* K2键按下,数据填充 */
                    DSP_Fill();
                    break;

                case KEY_DOWN_K3:            /* K3键按下,浮点转定点 */
                    DSP_FloatToFix();
                    break;

                default:
                    /* 其他的键值不处理 */
                    break;
            }
        }
    }
}

 

16.7 实验例程说明(IAR)

配套例子:

V7-211_DSP功能函数(数据拷贝,数据填充和浮点转定点)

实验目的:

  1. 学习功能函数(数据拷贝,数据填充和浮点转定点)

实验内容:

  1. 启动一个自动重装软件定时器,每100ms翻转一次LED2。
  2. 按下按键K1, 串口打印函数DSP_Copy的输出结果。
  3. 按下按键K2, 串口打印函数DSP_Fill的输出结果。
  4. 按下按键K3, 串口打印函数DSP_FloatToFix的输出结果。

上电后串口打印的信息:

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

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

程序设计:

  系统栈大小分配:

32H7_海马s5近光可以直接换H7吗

  RAM空间用的DTCM:

32H7_海马s5近光可以直接换H7吗

  硬件外设初始化

硬件外设的初始化是在 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_Copy的输出结果
  •   按下按键K2, 串口打印函数DSP_Fill的输出结果
  •   按下按键K3, 串口打印函数DSP_FloatToFix的输出结果
/*
*********************************************************************************************************
*    函 数 名: 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_Copy();
                    break;
                    
                case KEY_DOWN_K2:            /* K2键按下,数据填充 */
                    DSP_Fill();
                    break;

                case KEY_DOWN_K3:            /* K3键按下,浮点转定点 */
                    DSP_FloatToFix();
                    break;

                default:
                    /* 其他的键值不处理 */
                    break;
            }
        }
    }
}

 

16.8 总结

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

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196344.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • spring中使用form标签「建议收藏」

    在jsp头部包含:按如下方式编写表单:              111                    222                    333                    444

    2022年4月11日
    50
  • Ubuntu命令备忘

    Ubuntu命令备忘

    2021年7月29日
    55
  • powerdesigner导入sql生成表_oracle导入sql

    powerdesigner导入sql生成表_oracle导入sql在实际工作中,一张表,我们可能需要在Mysql数据库中建表,又要在Oracle数据库中建表。表中每个字段的数据类型、中文注释、是否可为NULL问题,非常影响我们建表的效率。本篇文章,以Oracle数据库表为源表,通过PowerDesigner工具将其转化成Mysql数据库建表语句。1、以oracle_to_student(学生表)为例,Oracle数据库中建表语句如下所示。…

    2022年9月8日
    4
  • windows10更新报错0x80240fff_windows10易升有什么用

    windows10更新报错0x80240fff_windows10易升有什么用win10更新错误0x8000ffff处理方法:1.同时按下Windows键和R键,打开运行,输入services.msc;2.找到WindowsUpdate服务项,右键选择禁用;3.打开c:\windows\SoftwareDistribution\datastore,删除datastore和和Download两个文件夹下的所有文件;4.按照1和2的步骤开启WindowsUpdate服务,重新检查更新;如果不行用下法试试:右键点击开始——命令提示符(管理员),输入以下命令尝试修复。dism

    2022年9月25日
    2
  • clion永久激活码2021(注册激活)

    (clion永久激活码2021)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月26日
    1.2K
  • iozone使用简介

    iozone使用简介iozone 使用简介 iozone www iozone org 是一个文件系统的 benchmark 工具 可以测试不同的操作系统中文件系统的读写性能 可以测试 Read write re read re write readbackward readstrided fread fwrite randomread pread mmap aio read aio write 等等不同的模式下的硬盘的性能 命令详情 aAutomode AAuto2mode b

    2025年9月1日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号