数据计算单元(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后比较或写任何数据寄存器后比较。
将工程模板复制到实验目录下,将工程名改为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 = DATA1
enDcuFlag2 = DCU_GetIrqFlag(M4_DCU3, DcuIntEq2);//DATA0 = DATA2
if ((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熄灭。
|