目录

1.实验目标

2.实验准备

3.库函数说明

4.主流程图

5.实验过程

数据计算单元(Data Computing Unit)是一个不借助于CPU的简单处理数据的模块。每个DCU单元具有3个数据寄存器(DATA0、DATA1、DATA2),能够进行2个数据的加减和比较大小,以及窗口比较功能。本产品搭载4个DCU单元,每个单元均可独立完成自身功能。

DCU加法模式计算DATA0和DATA1的和,其中DATA0作为被加数,DATA1作为加数。每次写DATA1寄存器进行一次(DATA0+DATA1)/2的运算,DATA0+DATA1的结果存入DATA0,而(DATA0+DATA1)/2的结果存入DATA2。当DATA0+DATA1结果超过0xFF(8bit模式)或0xFFFF(16bit模式)或0xFFFF_FFFF(32bit模式)时产生标志位并产生中断。

DCU减法模式计算DATA0和DATA1的差,其中DATA0作为被减数,DATA1作为减数。每次写DATA1寄存器进行一次(DATA0-DATA1)/2的运算,DATA0-DATA1的结果存入DATA0,而(DATA0-DATA1)/2的结果存入DATA2。当DATA0-DATA1结果小于0x0(8bit,16bit,32bit模式)时产生标志位并产生中断。

DCU比较模式比较DATA0和DATA1以及DATA0和DATA2的大小,可选择当DATA0大于DATA1,DATA0小于DATA1,DATA0等于DATA1时以及当DATA0大于DATA2,DATA0小于DATA2,DATA0等于DATA2时产生标志位并产生中断。比较模式下可以选择数据开始比较的条件,写DATA0后比较或写任何数据寄存器后比较。

1.实验目标

本实验主要使用DCU的加法、减法、比较功能,通过串口助手查看数据,LED灯点亮表示DCU运算的预期结果。

2.实验准备

硬件搭建:ZW-HC32F460-BZ标准版开发板1套

软件搭建:MDK5.22

3.库函数说明

【DCU初始化函数】

函数原型:en_result_t DCU_Init(M4_DCU_TypeDef *DCUx, const stc_dcu_init_t *pstcInitCfg)

输    入:

DCUx:DCU单元号;

M4_DCU1:DCU单元1;

M4_DCU2:DCU单元2;

M4_DCU3:DCU单元3;

M4_DCU4:DCU单元4;

pstcInitCfg:DCU初始化参数结构体,参照stc_dcu_init_t定义;

输    出:操作成功返回OK;

功    能:初始化DCU相关参数;

举    例:DCU_Init(M4_DCU1, &stcDcuInit);

【DCU写数据Datax函数】

函数原型:en_result_t DCU_WriteDataHalfWord(M4_DCU_TypeDef *DCUx,

en_dcu_data_register_t enDataReg,

uint16_t u16Data)

输    入:

DCUx:DCU单元号;

M4_DCU1:DCU单元1;

M4_DCU2:DCU单元2;

M4_DCU3:DCU单元3;

M4_DCU4:DCU单元4;

enDataReg:DCU数据寄存器结构体,参照en_dcu_data_register_t定义;

u16Data:写入16位数据;

输    出:操作成功返回OK;

功    能:DCU写数据到DATA寄存器;

举    例:DCU_WriteDataHalfWord(M4_DCU1, DcuRegisterData0, 2000u);

DCU_WriteDataByte()和DCU_WriteDataWord()函数与DCU_WriteDataHalfWord()函数功能用法是一样的,只是写入DATA的参数一个8位另一个是32位数据,源代码请查看 "hc32f460_dcu.h"文件。

【DCU读数据Datax函数】

函数原型:uint16_t DCU_ReadDataHalfWord(M4_DCU_TypeDef *DCUx,

en_dcu_data_register_t enDataReg)

输    入:

DCUx:DCU单元号;

M4_DCU1:DCU单元1;

M4_DCU2:DCU单元2;

M4_DCU3:DCU单元3;

M4_DCU4:DCU单元4;

enDataReg:DCU数据寄存器结构体,参照en_dcu_data_register_t定义;

输    出:返回DATA寄存器的值;

功    能:读取数据DATA寄存器值;

举    例:au16Data0Val = DCU_ReadDataHalfWord(M4_DCU1, DcuRegisterData0);

DCU_ReadDataByte()和DCU_ReadDataWord()函数与DCU_ReadDataHalfWord()函数功能用法是一样的,只是函数返回来的DATA参数一个8位另一个是32位数据,源代码请查看 "hc32f460_dcu.h"文件。

【DCU获取中断标志位函数】

函数原型:en_flag_status_t DCU_GetIrqFlag(M4_DCU_TypeDef *DCUx, en_dcu_flag_t enFlag)

输    入:

DCUx:DCU单元号;

M4_DCU1:DCU单元1;

M4_DCU2:DCU单元2;

M4_DCU3:DCU单元3;

M4_DCU4:DCU单元4;

enFlag:DCU标志位结构体,请参照en_dcu_flag_t结构体;

输    出:状态标志;

Set:Flag is set.

Reset:Flag is reset or enStatus is invalid.

功    能:获取DCU状态标志位;

举    例:enDcuFlag1 = DCU_GetIrqFlag(M4_DCU1, DcuIntEq1);

【DCU清除中断标志位函数】

函数原型:en_result_t DCU_ClearIrqFlag(M4_DCU_TypeDef *DCUx, en_dcu_flag_t enFlag)

输    入:

DCUx:DCU单元号;

M4_DCU1:DCU单元1;

M4_DCU2:DCU单元2;

M4_DCU3:DCU单元3;

M4_DCU4:DCU单元4;

enFlag:DCU标志位结构体,请参照en_dcu_flag_t结构体;

输    出:操作成功返回OK;

功    能:清除DCU状态标志位;

举    例:enDcuFlag1 = DCU_GetIrqFlag(M4_DCU1, DcuIntEq1);

4.主流程图

DCU的加法、减法、比较功能,使用方法是差不多的,只是在DCU_Init()函数初始时设置DCU的功能不一样。

5.实验过程

【第一步:新建/配置工程】

将工程模板复制到实验目录下,将工程名改为DCU。

勾选FWLibCfg.h配置中的CLK_EN、EFM_EN、GPIO_EN、PWC_EN、SRAM_EN、UTILITY_EN、DCU_EN选项

【第二步:初始化编程】

1)DCU1初始化

在main.c文件中创建DCU1_ADD_Init()函数进行初始化。

static void DCU1_ADD_Init(void){stc_dcu_init_t stcDcuInit;/* Enable peripheral clock */PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DCU1, Enable);/* Initialize DCU */MEM_ZERO_STRUCT(stcDcuInit);stcDcuInit.u32IntSel = 0ul;//无中断stcDcuInit.enIntWinMode = DcuIntInvalid;//没有窗口中断stcDcuInit.enDataSize = DcuDataBit16;//16位数据stcDcuInit.enOperation = DcuOpAdd;//加法模式DCU_Init(M4_DCU1, &stcDcuInit);//DCU初始化函数  }

2)DCU2初始化

在main.c文件中创建DCU2_SUB_Init()函数进行初始化。

static void DCU2_SUB_Init(void){stc_dcu_init_t stcDcuInit;/* Enable peripheral clock */PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DCU2, Enable);/* Initialize DCU */MEM_ZERO_STRUCT(stcDcuInit);stcDcuInit.u32IntSel = 0ul;//无中断stcDcuInit.enIntWinMode = DcuIntInvalid;//没有窗口中断stcDcuInit.enDataSize = DcuDataBit16;//16位数据stcDcuInit.enOperation = DcuOpSub;//减法模式DCU_Init(M4_DCU2, &stcDcuInit);//DCU初始化函数       }

3)DCU3初始化

在main.c文件中创建DCU3_Compare_Init()函数进行初始化。

static void DCU3_Compare_Init(void){stc_dcu_init_t stcDcuInit;/* Enable peripheral clock */PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DCU3, Enable);/* Initialize DCU */MEM_ZERO_STRUCT(stcDcuInit);stcDcuInit.u32IntSel = 0ul;//无中断stcDcuInit.enIntWinMode = DcuIntInvalid;//没有窗口中断stcDcuInit.enDataSize = DcuDataBit8;//8位数据stcDcuInit.enOperation = DcuOpCompare;//比较功能stcDcuInit.enCmpTriggerMode = DcuCmpTrigbyData0;//写入DATA0后比较DCU_Init(M4_DCU3, &stcDcuInit);//DCU初始化函数       }

4)LED初始化

将LED的头文件和源文件添加到工程文件中,根据原理图初始化LED1、LED2、LED3,LED初始化函数请放在HardwareInt()函数中。

【第三步:DCU1加法功能实现】

在man.c文件中创建DCU1_ADD()函数并声明。

static void DCU1_ADD(void){uint32_t i;en_result_t enTestResult = Ok;uint16_t au16Data0Val[4];uint16_t au16Data1Val[4] = {0, 10, 500, 1000};uint16_t au16Data2Val[4];uint32_t u32CalTimes = sizeof(au16Data1Val)/2u;DCU_WriteDataHalfWord(M4_DCU1, DcuRegisterData0, 0u);//写入Data0数据for (i = 0u; i < u32CalTimes; i++){DCU_WriteDataHalfWord(M4_DCU1, DcuRegisterData1, au16Data1Val[i]);au16Data0Val[i] = DCU_ReadDataHalfWord(M4_DCU1, DcuRegisterData0);au16Data2Val[i] = DCU_ReadDataHalfWord(M4_DCU1, DcuRegisterData2);/* Compare DCU regisger DATA0 && DATA2 value: DATA0 value == 2 * DATA2 value */if (au16Data0Val[i] != (2u * au16Data2Val[i])){enTestResult = Error;break;}else{}}printf("DCU1_ADD\r\nau16Data0Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au16Data0Val[i]);}printf("\r\n");printf("au16Data1Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au16Data1Val[i]);}printf("\r\n"); printf("au16Data2Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au16Data2Val[i]);}printf("\r\n");if (Ok == enTestResult){LedOn(LED1);  /* Test pass && meet the expected */}else{LedOff(LED1);  /* Test fail && don't meet the expected */}}使用DCU写函数写入数据0给DATA0寄存器作初始值,通过for语句,使用DCU写函数把au16Data1Val数组写入到DATA1寄存器中,au16Data0Val和au16Data2Val数组获取计算出的DATA0和DATA2的值,if语句判断DATA2的值是否为DATA0的一半,总共for语句循环4次。计算出的结果不符合我们的预期,LED1熄灭,反之LED点亮,最后打印出3个数组的值。【第四步:DCU2减法功能实现】在man.c文件中创建DCU2_SUB()函数并声明,DCU2的减法思想与加法思想是相同的,这里就不赘述了。计算的结果预期一致LED2点亮,不一致则LED2熄灭,打印最后三个数组值。static void DCU2_SUB(void){uint32_t i;en_result_t enTestResult = Ok;uint16_t au16Data0Val[4];uint16_t au16Data2Val[4];uint16_t au16Data1Val[4] = {0, 10, 500, 1000};uint32_t u32CalTimes = sizeof(au16Data1Val)/2u;DCU_WriteDataHalfWord(M4_DCU2, DcuRegisterData0, 2000u);//写入Data0数据for (i = 0u; i < u32CalTimes; i++){DCU_WriteDataHalfWord(M4_DCU2, DcuRegisterData1, au16Data1Val[i]);au16Data0Val[i] = DCU_ReadDataHalfWord(M4_DCU2, DcuRegisterData0);au16Data2Val[i] = DCU_ReadDataHalfWord(M4_DCU2, DcuRegisterData2);/* Compare DCU regisger DATA0 && DATA2 value: DATA0 value == 2 * DATA2 value */if (au16Data0Val[i] != (2u * au16Data2Val[i])){enTestResult = Error;break;}else{}}printf("DCU2_SUB\r\nau16Data0Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au16Data0Val[i]);}printf("\r\n");printf("au16Data1Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au16Data1Val[i]);}printf("\r\n"); printf("au16Data2Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au16Data2Val[i]);}printf("\r\n");if (Ok == enTestResult){LedOn(LED2);  /* Test pass && meet the expected */}else{LedOff(LED2);  /* Test fail && don't meet the expected */}}

【第五步:DCU3比较功能实现】

在man.c文件中创建DCU2_Compare()函数并声明。

static void DCU3_Compare(void){stc_dcu_init_t stcDcuInit;en_result_t enTestResult = Ok;en_flag_status_t enDcuFlag1 = Reset;en_flag_status_t enDcuFlag2 = Reset;uint8_t au8Data0Val[4] = {00, 22, 44, 88};uint8_t au8Data1Val[4] = {00, 11, 55, 88};uint8_t au8Data2Val[4] = {00, 11, 55, 88}; uint32_t u32CalTimes = sizeof(au8Data1Val);uint32_t i;/* DATA0 = DATA1  &&  DATA0 = DATA2 */DCU_WriteDataByte(M4_DCU3, DcuRegisterData1, au8Data1Val[0]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData2, au8Data2Val[0]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData0, au8Data0Val[0]);enDcuFlag1 = DCU_GetIrqFlag(M4_DCU3, DcuIntEq1);//DATA0 = DATA1enDcuFlag2 = DCU_GetIrqFlag(M4_DCU3, DcuIntEq2);//DATA0 = DATA2if ((Set != enDcuFlag1) || (Set != enDcuFlag2)){enTestResult = Error;}else{}DCU_ClearIrqFlag(M4_DCU3, DcuIntEq1);DCU_ClearIrqFlag(M4_DCU3, DcuIntEq2);/* DATA0 > DATA1  &&  DATA0 > DATA2 */DCU_WriteDataByte(M4_DCU3, DcuRegisterData1, au8Data1Val[1]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData2, au8Data2Val[1]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData0, au8Data0Val[1]);enDcuFlag1 = DCU_GetIrqFlag(M4_DCU3, DcuIntGt1);enDcuFlag2 = DCU_GetIrqFlag(M4_DCU3, DcuIntGt2);if ((Set != enDcuFlag1) || (Set != enDcuFlag2)){enTestResult = Error;}else{}DCU_ClearIrqFlag(M4_DCU3, DcuIntGt1);DCU_ClearIrqFlag(M4_DCU3, DcuIntGt2);/* DATA0 < DATA1  &&  DATA0 < DATA2 */DCU_WriteDataByte(M4_DCU3, DcuRegisterData1, au8Data1Val[2]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData2, au8Data2Val[2]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData0, au8Data0Val[2]);enDcuFlag1 = DCU_GetIrqFlag(M4_DCU3, DcuIntLs1);enDcuFlag2 = DCU_GetIrqFlag(M4_DCU3, DcuIntLs2);if ((Set != enDcuFlag1) || (Set != enDcuFlag2)){enTestResult = Error;}else{}DCU_ClearIrqFlag(M4_DCU3, DcuIntLs1);DCU_ClearIrqFlag(M4_DCU3, DcuIntLs2);/* DATA0 = DATA1  &&  DATA0 = DATA2 */DCU_WriteDataByte(M4_DCU3, DcuRegisterData1, au8Data1Val[3]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData2, au8Data2Val[3]);DCU_WriteDataByte(M4_DCU3, DcuRegisterData0, au8Data0Val[3]);enDcuFlag1 = DCU_GetIrqFlag(M4_DCU3, DcuIntEq1);enDcuFlag2 = DCU_GetIrqFlag(M4_DCU3, DcuIntEq2);if ((Set != enDcuFlag1) || (Set != enDcuFlag2)){enTestResult = Error;}else{}DCU_ClearIrqFlag(M4_DCU3, DcuIntEq1);DCU_ClearIrqFlag(M4_DCU3, DcuIntEq2);printf("DCU3_Compare\r\nau8Data0Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au8Data0Val[i]);}printf("\r\n");printf("au8Data1Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au8Data1Val[i]);}printf("\r\n"); printf("au8Data2Val:");for(i = 0u; i < u32CalTimes; i++){printf("%4d\t",au8Data2Val[i]);}printf("\r\n");if (Ok == enTestResult){LedOn(LED3);  /* Test pass && meet the expected */}else{LedOff(LED3);  /* Test fail && don't meet the expected */}}     

DATA0作为比较源,3个数组传入DCU的3个数据寄存器中,通过获取DCU标志位函数,判断比较结果是否为预期一致,代码中一共比较了4次,预期一致LED3点亮,不一致则LED3熄灭。

【第六步:下载验证】

连接好硬件,编译下载运行该程序,通过串口助手查看数据,观察LED灯的亮灭状态是否与预期一致。

华大HC32F460 DCU实验相关推荐

  1. 华大HC32F460 MPU6050实验

    1.实验目标 本实验主要通过LCD显示MPU6050温度及坐标. 2.实验准备 硬件搭建:ZW-HC32F460-BZ标准版开发板1套 软件搭建:MDK5.22 3.硬件原理 MPU6050的IIC引 ...

  2. 华大HC32F460 SPI 驱动 ST7735S LCD显示器

    华大HC32F460 SPI 驱动 ST7735S LCD显示器 前言: STM32改HC32F460 换芯片后发现SPI硬件驱动不了屏了,这个小问题搞了很久,最后用逻辑分析仪,分析时序,然后解决了, ...

  3. 华大HC32F460串口空闲中断+DMA收发配置,记录一下自己遇到的坑

    华大HC32F460串口空闲中断+DMA收发配置,记录一下自己遇到的坑 华大HC32F460串口空闲中断+DMA收发配置,记录一下自己遇到的坑 注:个人笔记,如有错误,还望谅解. STM32 在STM ...

  4. 华大HC32F460 SDIO TF卡实验

    目录 1.实验目标 2.实验准备 3.硬件原理 4.驱动代码 5.主流程图 6.实验过程 7.实验扩展 1.实验目标 本实验使用SDIOC一线式读取SD卡相关信息并打印到USB-UART,同时将SD卡 ...

  5. 华大HC32F460的BOOT和IAP说明

    今年MCU价格暴涨,打算入坑国产MCU,最近趁着有空加工了一块华大的HC32F460评估板.成品板见图1.拿到新控制器,首先要做的就是编写底层BOOT程序,有了BOOT程序即可随时更新APP不被调试器 ...

  6. 华大HC32F460芯片

    华大半导体有限公司(简称华大半导体)是中国电子信息产业集团有限公司(CEC)整合旗下集成电路企业而组建的专业子集团,成立于2014年5月8日.华大半导体涵盖设计.制造.封装.测试.EDA等领域,是拥有 ...

  7. 华大HC32F460时钟简介

    最近在学习华大的HC32F460单片机,学习单片机就不得不说说单片机的运行时钟,华大这款单片机的时钟有很多的时钟总线,外设都是挂载在时钟线上运行的, HC32F460的时钟其实就是片内时钟和片外时钟两 ...

  8. 华大HC32F460系列填坑之USART

    问题:使用F460官方串口例程,将波特率设置为9600失败. 原因:通过仿真,发现设置波特率返回的错误信息是ErrorInvalidParameter(误差无效参数).分析华大提供的设置波特率函数,发 ...

  9. 华大HC32F460NMI中断实验

    目录 1 实验目标 2 实验准备 3 硬件原理 4 驱动代码 5 主流程图 6 实验过程 1 实验目标 本实验主要通过对外部中断的配置及编程,使用中断的方式实现KEY1控制LED1灯的功能. 2 实验 ...

最新文章

  1. CentOS下命令行和桌面模式的切换方法
  2. 深度学习必备:随机梯度下降(SGD)优化算法及可视化
  3. 2020年快手校招JAVA岗笔试第二题
  4. seci-log1.02日志分析软件版本升级了
  5. Html5 dragdrop
  6. java 操作 ES 的方式 整理总结
  7. 说一下StoreBoard和纯代码编程各有什么好处吧
  8. 数据链路层差错控制——奇偶校验码、循环冗余码和汉明码(海明码)
  9. c语言 中断 局部变量 not allocated,C语言(函数)调用过程(略译)
  10. MDaemon12.X特殊注意事项和新功能
  11. Bailian2684 求阶乘的和【迭代+函数+循环】(POJ NOI0105-34)
  12. 简单的图书馆系统 LibrarySystem(OC模拟)
  13. Mysql支持的数据类型
  14. HQChart使用教程85-股票复权计算
  15. 又有朋友被骗入传销了!
  16. 防止刷新或后退页面重复提交表单
  17. 人民币大写的正确写法
  18. 打造离线版 123D Catch
  19. 使用nexus-3.0.2-02-win64搭建自己的Maven nexus私服
  20. 海关外贸企业大数据风控平台产品应用

热门文章

  1. 原来还有这种操作,libs和jniLibs 还有jni不得不说的关系
  2. 腾讯马拉松之部门竞赛
  3. whatsns内容付费问答系统第三方登录新浪微博配置教程
  4. 数据分析师门槛太高?分享成功转行的三点经验!
  5. 基于matlab频率估计算法对比,包括统计M.Westlund算法,BTDT,CZT,ZOOM-FFT 等的
  6. 第一行代码 Android 第2版 书评
  7. pytorch 半精度half()
  8. 文件权限rwx与数字解释
  9. Laravel 建站随笔
  10. 异步时序逻辑电路设计方法(统一使用上升沿触发的触发器)