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


    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'则功能正常。

    1. en_result_t PcaCapTest(void)
    2. {
    3. stc_pca_config_t stcConfig;
    4. stc_pca_capmodconfig_t stcModConfig;
    5. en_result_t enResult = Error;
    6. uint16_t u16InitCntData = 0;
    7. uint16_t u16Cnt = 0;
    8. // GPIO CFG
    9. Gpio_SetFunc_PCA_CH1_P33(1);
    10. Gpio_InitIO(3, 2, GpioDirOut);
    11. Gpio_SetIO(3, 2, TRUE);
    12. stcConfig.enCIDL = IdleGoon; //休眠模式PCA工作
    13. stcConfig.enWDTE = PCAWDTDisable; // wdt功能关闭
    14. stcConfig.enCPS = PCAPCLKDiv8;
    15. stcConfig.pfnPcaCb = PcaInt;
    16. stcModConfig.enECOM = ECOMDisable; //比较器功能禁止
    17. stcModConfig.enCAPP = CAPPEnable; //上升沿捕获
    18. stcModConfig.enCAPN = CAPNEnable; //下降沿捕获
    19. stcModConfig.enMAT = MATDisable; //禁止匹配
    20. stcModConfig.enTOG = TOGDisable;
    21. stcModConfig.enPWM = PCAPWMDisable;
    22. if (Ok != Pca_Init(&stcConfig)) {
    23. enResult = Error;
    24. }
    25. if (Ok != Pca_CapModConfig(Module1, &stcModConfig)) {
    26. enResult = Error;
    27. }
    28. // PCA中断使能
    29. Pca_ClearIntFlag(Module1);
    30. Pca_EnableIrq(Module1);
    31. EnableNvic(PCA_IRQn, 3, TRUE);
    32. Pca_Cnt16Set(u16InitCntData);
    33. Pca_Run();
    34. u16Cnt = 0x100;
    35. while (u16Cnt--)
    36. ;
    37. Gpio_SetIO(3, 2, FALSE); //内部输出低,外接P24产生下降沿中断
    38. //进入中断……
    39. while (1) {
    40. //发生下降沿捕获
    41. if (0x02 == (u32PcaTestFlag & 0x02)) {
    42. u32PcaTestFlag = (u32PcaTestFlag & (~0x02));
    43. u16CcapData[0] = Pca_CapData16Get(Module1);
    44. enResult = Ok;
    45. break;
    46. }
    47. }
    48. u16Cnt = 0x100;
    49. while (u16Cnt--)
    50. ;
    51. Gpio_SetIO(3, 2, TRUE); //内部输出高,外接P24产生上升沿中断
    52. //进入中断……
    53. while (1) {
    54. //发生上升沿捕获
    55. if (0x02 == (u32PcaTestFlag & 0x02)) {
    56. u32PcaTestFlag = (u32PcaTestFlag & (~0x02));
    57. u16CcapData[1] = Pca_CapData16Get(Module1);
    58. enResult = Ok;
    59. break;
    60. }
    61. }
    62. Pca_Stop();
    63. return enResult;
    64. }

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

    pca_cmp_cnt例程

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

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

    1. en_result_t PcaCmpCntTest(void)
    2. {
    3. stc_pca_config_t stcConfig;
    4. stc_pca_capmodconfig_t stcModConfig;
    5. en_result_t enResult = Error;
    6. uint16_t u16InitCntData = 0;
    7. uint16_t u16CcapData = 0xC0;
    8. // INT ENABLE
    9. EnableNvic(PCA_IRQn, 3, TRUE);
    10. Pca_EnableIrq(Module2);
    11. stcConfig.enCIDL = IdleGoon;
    12. stcConfig.enWDTE = PCAWDTDisable;
    13. stcConfig.enCPS = PCAPCLKDiv3;
    14. stcConfig.pfnPcaCb = PcaInt;
    15. stcModConfig.enECOM = ECOMEnable; //允许比较功能
    16. stcModConfig.enCAPP = CAPPDisable;
    17. stcModConfig.enCAPN = CAPNDisable;
    18. stcModConfig.enMAT = MATEnable; //允许匹配
    19. stcModConfig.enTOG = TOGDisable;
    20. stcModConfig.enPWM = PCAPWMDisable;
    21. if (Ok != Pca_Init(&stcConfig)) {
    22. enResult = Error;
    23. }
    24. if (Ok != Pca_CapModConfig(Module2, &stcModConfig)) {
    25. enResult = Error;
    26. }
    27. Pca_CapData16Set(Module2, u16CcapData); //比较捕获寄存器设置
    28. Pca_Cnt16Set(u16InitCntData);
    29. Pca_Run();
    30. //进入中断……
    31. while (1) {
    32. //比较值匹配
    33. if (0x04 == (u32PcaTestFlag & 0x04)) {
    34. u32PcaTestFlag = (u32PcaTestFlag & (~0x04));
    35. Pca_Stop();
    36. enResult = Ok;
    37. break;
    38. }
    39. }
    40. return enResult;
    41. }

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

    pca_pwm例程

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

    1. en_result_t PcaPwmTest(void)
    2. {
    3. stc_pca_config_t stcConfig;
    4. stc_pca_capmodconfig_t stcModConfig;
    5. en_result_t enResult = Ok;
    6. uint8_t u8CcaplData = 0x20;
    7. uint8_t u8CcaphData = 0x40;
    8. uint32_t u32Cnt;
    9. Gpio_SetFunc_PCA_CH0_P34(0);
    10. stcConfig.enCIDL = IdleGoon;
    11. stcConfig.enWDTE = PCAWDTDisable;
    12. stcConfig.enCPS = PCAPCLKDiv32;
    13. stcConfig.pfnPcaCb = PcaInt;
    14. stcModConfig.enECOM = ECOMEnable;
    15. stcModConfig.enCAPP = CAPPDisable;
    16. stcModConfig.enCAPN = CAPNDisable;
    17. stcModConfig.enMAT = MATDisable;
    18. stcModConfig.enTOG = TOGDisable;
    19. stcModConfig.enPWM = PCAPWMEnable;
    20. if (Ok != Pca_Init(&stcConfig)) {
    21. enResult = Error;
    22. }
    23. if (Ok != Pca_CapModConfig(Module0, &stcModConfig)) {
    24. enResult = Error;
    25. }
    26. Pca_CapDataLSet(Module0, u8CcaplData);
    27. Pca_CapDataHSet(Module0, u8CcaphData);
    28. Pca_Run();
    29. // PWM波形输出……
    30. u32Cnt = 0x80000;
    31. while (u32Cnt--) {
    32. ;
    33. }
    34. return enResult;
    35. }

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

    pca_wdt例程

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

    1. en_result_t PcaWdtTest(void)
    2. {
    3. stc_pca_config_t stcConfig;
    4. stc_pca_capmodconfig_t stcModConfig;
    5. en_result_t enResult = Ok;
    6. uint16_t u16CntData = 0;
    7. uint16_t u16CcapData0 = 0x8000;
    8. uint16_t u16CcapData1 = 0x6000;
    9. stcConfig.enCIDL = IdleGoon;
    10. stcConfig.enWDTE = PCAWDTEnable;
    11. stcConfig.enCPS = PCAPCLKDiv32;
    12. stcConfig.pfnPcaCb = PcaInt;
    13. stcModConfig.enECOM = ECOMEnable;
    14. stcModConfig.enCAPP = CAPPDisable;
    15. stcModConfig.enCAPN = CAPNDisable;
    16. stcModConfig.enMAT = MATEnable;
    17. stcModConfig.enTOG = TOGDisable;
    18. stcModConfig.enPWM = PCAPWMDisable;
    19. Pca_Cnt16Set(u16CntData);
    20. Pca_CapData16Set(Module4, u16CcapData0);
    21. if (Ok != Pca_CapModConfig(Module4, &stcModConfig)) {
    22. enResult = Error;
    23. return enResult;
    24. }
    25. if (Ok != Pca_Init(&stcConfig)) {
    26. enResult = Error;
    27. return enResult;
    28. }
    29. Pca_Run();
    30. // WDT:修改为while(1),则不断更新比较值,保持运行;否则复位。
    31. while (1) {
    32. if (0x7000 > Pca_Cnt16Get()) {
    33. Pca_CapData16Set(Module4, u16CcapData0);
    34. } else {
    35. Pca_CapData16Set(Module4, u16CcapData1);
    36. }
    37. }
    38. return enResult;
    39. }

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

  • 相关阅读:
    Davinci 集成NvM协议栈的步骤
    机器人系统 ROS 常用命令行工具
    JAVA在线作业提交系统计算机毕业设计Mybatis+系统+数据库+调试部署
    C++ string 类相关知识
    【C++】红黑树的模拟实现
    深度学习常用激活函数总结
    Vue基础-04
    制糖行业脱色技术A30MP树脂材料
    MATLAB程序设计与应用 2.6 字符串
    DailyPractice.2023.10.14
  • 原文地址:https://blog.csdn.net/andylauren/article/details/126226333