当前位置:网站首页>CMT2380F32模块开发9-可编程计数阵列 PCA例程

CMT2380F32模块开发9-可编程计数阵列 PCA例程

2022-08-11 05:24:00 andylauren

PCA(可编程计数器阵列 Programmable Counter Array)支持最多 5 个 16 位的捕获/比较模块。该定时/计数器可用作为一个通用的时钟计数/事件计数器的捕获/比较功能。PCA 的每个模块都可以进行独立编程,以提供输入捕捉、输出比较或脉冲宽度调制。另外模块 4 有额外的看门狗定时器模式。

每个模块都可被配置为独立工作,有三种工作方式:边沿触发捕捉、输出比较、8 位脉宽调制。每个模块在系统控制器中都有属于自己的功能寄存器,这些寄存器用于配置模块的工作方式和与模块交换数据。

PCA 8 位脉宽调制功能
脉宽调制是一种使用程序来控制波形占空比,周期,相位的技术。5 个 PCA 模块都可以被独立地用于在对应PCA 的 CAP/CMP[x] 引脚产生脉宽调制(PWM)输出,脉冲宽度为 8 位分辨率。

pca_cap例程

本样例对展示PCA对外部上升/下降沿的捕获功能,捕获到沿时产生中断。用跳线连接P33(CAP1)与P32(沿输出),在main函数while(1)处设置断点。运行。程序到断点处停止,此时观察"u8TestFlag"的值,若为'0'则功能正常。

en_result_t PcaCapTest(void)
{
    stc_pca_config_t stcConfig;
    stc_pca_capmodconfig_t stcModConfig;
    en_result_t enResult = Error;
    uint16_t u16InitCntData = 0;
    uint16_t u16Cnt = 0;

    // GPIO CFG
    Gpio_SetFunc_PCA_CH1_P33(1);
    Gpio_InitIO(3, 2, GpioDirOut);
    Gpio_SetIO(3, 2, TRUE);

    stcConfig.enCIDL = IdleGoon;       //休眠模式PCA工作
    stcConfig.enWDTE = PCAWDTDisable;  // wdt功能关闭
    stcConfig.enCPS = PCAPCLKDiv8;

    stcConfig.pfnPcaCb = PcaInt;

    stcModConfig.enECOM = ECOMDisable;  //比较器功能禁止
    stcModConfig.enCAPP = CAPPEnable;   //上升沿捕获
    stcModConfig.enCAPN = CAPNEnable;   //下降沿捕获
    stcModConfig.enMAT = MATDisable;    //禁止匹配
    stcModConfig.enTOG = TOGDisable;
    stcModConfig.enPWM = PCAPWMDisable;

    if (Ok != Pca_Init(&stcConfig)) {
        enResult = Error;
    }
    if (Ok != Pca_CapModConfig(Module1, &stcModConfig)) {
        enResult = Error;
    }

    // PCA中断使能
    Pca_ClearIntFlag(Module1);
    Pca_EnableIrq(Module1);
    EnableNvic(PCA_IRQn, 3, TRUE);

    Pca_Cnt16Set(u16InitCntData);
    Pca_Run();

    u16Cnt = 0x100;
    while (u16Cnt--)
        ;
    Gpio_SetIO(3, 2, FALSE);  //内部输出低,外接P24产生下降沿中断

    //进入中断……
    while (1) {
        //发生下降沿捕获
        if (0x02 == (u32PcaTestFlag & 0x02)) {
            u32PcaTestFlag = (u32PcaTestFlag & (~0x02));
            u16CcapData[0] = Pca_CapData16Get(Module1);
            enResult = Ok;
            break;
        }
    }

    u16Cnt = 0x100;
    while (u16Cnt--)
        ;
    Gpio_SetIO(3, 2, TRUE);  //内部输出高,外接P24产生上升沿中断
    //进入中断……
    while (1) {
        //发生上升沿捕获
        if (0x02 == (u32PcaTestFlag & 0x02)) {
            u32PcaTestFlag = (u32PcaTestFlag & (~0x02));
            u16CcapData[1] = Pca_CapData16Get(Module1);
            enResult = Ok;
            break;
        }
    }

    Pca_Stop();

    return enResult;
}

通过普通IO P32的拉高拉低模拟出上升下降沿,触发PCA边沿捕捉。

pca_cmp_cnt例程

本样例对展示PCA的比较计数功能,当计数值达到设定的比较值时,产生中断,停止计数。

在main函数while(1)处设置断点。运行。程序到断点处停止,此时观察"u8TestFlag"的值,若为'0'则功能正常。

en_result_t PcaCmpCntTest(void)
{
    stc_pca_config_t stcConfig;
    stc_pca_capmodconfig_t stcModConfig;
    en_result_t enResult = Error;
    uint16_t u16InitCntData = 0;
    uint16_t u16CcapData = 0xC0;

    // INT ENABLE
    EnableNvic(PCA_IRQn, 3, TRUE);
    Pca_EnableIrq(Module2);

    stcConfig.enCIDL = IdleGoon;
    stcConfig.enWDTE = PCAWDTDisable;
    stcConfig.enCPS = PCAPCLKDiv3;

    stcConfig.pfnPcaCb = PcaInt;

    stcModConfig.enECOM = ECOMEnable;  //允许比较功能
    stcModConfig.enCAPP = CAPPDisable;
    stcModConfig.enCAPN = CAPNDisable;
    stcModConfig.enMAT = MATEnable;  //允许匹配
    stcModConfig.enTOG = TOGDisable;
    stcModConfig.enPWM = PCAPWMDisable;

    if (Ok != Pca_Init(&stcConfig)) {
        enResult = Error;
    }
    if (Ok != Pca_CapModConfig(Module2, &stcModConfig)) {
        enResult = Error;
    }

    Pca_CapData16Set(Module2, u16CcapData);  //比较捕获寄存器设置
    Pca_Cnt16Set(u16InitCntData);
    Pca_Run();

    //进入中断……
    while (1) {
        //比较值匹配
        if (0x04 == (u32PcaTestFlag & 0x04)) {
            u32PcaTestFlag = (u32PcaTestFlag & (~0x04));
            Pca_Stop();
            enResult = Ok;
            break;
        }
    }

    return enResult;
}

当捕获计数值与设置的计数值相同的时候就会触发中断,程序继续向下运行。

pca_pwm例程

本样例展示PCA的PWM功能。用示波器观察P34(CMP0),在main函数while(1)处设置断点。运行,观察波形,持续一段时间后停止。程序到断点处停止,此时观察"u8TestFlag"的值,若为'0'则功能正常。

en_result_t PcaPwmTest(void)
{
    stc_pca_config_t stcConfig;
    stc_pca_capmodconfig_t stcModConfig;
    en_result_t enResult = Ok;
    uint8_t u8CcaplData = 0x20;
    uint8_t u8CcaphData = 0x40;
    uint32_t u32Cnt;

    Gpio_SetFunc_PCA_CH0_P34(0);

    stcConfig.enCIDL = IdleGoon;
    stcConfig.enWDTE = PCAWDTDisable;
    stcConfig.enCPS = PCAPCLKDiv32;

    stcConfig.pfnPcaCb = PcaInt;

    stcModConfig.enECOM = ECOMEnable;
    stcModConfig.enCAPP = CAPPDisable;
    stcModConfig.enCAPN = CAPNDisable;
    stcModConfig.enMAT = MATDisable;
    stcModConfig.enTOG = TOGDisable;
    stcModConfig.enPWM = PCAPWMEnable;

    if (Ok != Pca_Init(&stcConfig)) {
        enResult = Error;
    }
    if (Ok != Pca_CapModConfig(Module0, &stcModConfig)) {
        enResult = Error;
    }

    Pca_CapDataLSet(Module0, u8CcaplData);
    Pca_CapDataHSet(Module0, u8CcaphData);
    Pca_Run();

    // PWM波形输出……
    u32Cnt = 0x80000;
    while (u32Cnt--) {
        ;
    }

    return enResult;
}

通过Pca_CapDataLSet和Pca_CapDataHSet设置计数周期和低电平周期。输出pwm非常方便。

pca_wdt例程

本样例展示PCA的WDT功能,在达到定时值时如果没有及时设定比较值(喂狗),则发生系统复位,反之则系统正常运行。

en_result_t PcaWdtTest(void)
{
    stc_pca_config_t stcConfig;
    stc_pca_capmodconfig_t stcModConfig;
    en_result_t enResult = Ok;
    uint16_t u16CntData = 0;
    uint16_t u16CcapData0 = 0x8000;
    uint16_t u16CcapData1 = 0x6000;

    stcConfig.enCIDL = IdleGoon;
    stcConfig.enWDTE = PCAWDTEnable;
    stcConfig.enCPS = PCAPCLKDiv32;

    stcConfig.pfnPcaCb = PcaInt;

    stcModConfig.enECOM = ECOMEnable;
    stcModConfig.enCAPP = CAPPDisable;
    stcModConfig.enCAPN = CAPNDisable;
    stcModConfig.enMAT = MATEnable;
    stcModConfig.enTOG = TOGDisable;
    stcModConfig.enPWM = PCAPWMDisable;

    Pca_Cnt16Set(u16CntData);
    Pca_CapData16Set(Module4, u16CcapData0);

    if (Ok != Pca_CapModConfig(Module4, &stcModConfig)) {
        enResult = Error;
        return enResult;
    }
    if (Ok != Pca_Init(&stcConfig)) {
        enResult = Error;
        return enResult;
    }

    Pca_Run();

    // WDT:修改为while(1),则不断更新比较值,保持运行;否则复位。
    while (1) {
        if (0x7000 > Pca_Cnt16Get()) {
            Pca_CapData16Set(Module4, u16CcapData0);
        } else {
            Pca_CapData16Set(Module4, u16CcapData1);
        }
    }
    return enResult;
}

这个代码按照注释测试就行了,就是个喂狗的一种方式。

原网站

版权声明
本文为[andylauren]所创,转载请带上原文链接,感谢
https://blog.csdn.net/andylauren/article/details/126226333