请选择 进入手机版 | 继续访问电脑版

 找回密码
 立即注册
查看: 6504|回复: 26

如何测量72MHz以下的外部信号,STC32的144MHz的高速PWM

[复制链接]

该用户从未签到

538

主题

8729

回帖

1万

积分

管理员

积分
14201
发表于 2023-3-14 16:24:47 | 显示全部楼层 |阅读模式
如何测量72MHz以下的外部信号,
STC32的144MHz的高速PWM
STC32G12K128-35MHz-LQFP64/48/32,TSSOP20
STC32G8K64-42MHz-LQFP48/32
STC8H1K08T-33I-TSSOP20/QFN20

高速 144MHz ~ 196MHz 的PWM, 可以捕获外部脉冲信号,可以工作在 144MHz 以上
理论上 STC32G系列可以测量 144MHz/2以下频率的信号
已验证了:
1, 内部 HIRC-12MHz
2, HIRC-12MHz / 10 = 1.2MHz低频 给 STC32G12K128的CPU使用
3, HIRC-12MHz通过 PLL产生144MHz做PWM的时钟源, PWMB组产生 28.8MHz信号源
4, PWMA组侧量 28.8MHz的信号源正确 !
5, 等72MHz信号发生器来测试72MHz

如何测量72MHz的外部信号-1.png

如何测量72MHz的外部信号-2.png
如何测量72MHz的外部信号-3.png






回复 送花

使用道具 举报

该用户从未签到

538

主题

8729

回帖

1万

积分

管理员

积分
14201
 楼主| 发表于 2023-3-14 16:39:21 | 显示全部楼层


STC32G12K128-35I-TSSOP20 管脚图
1.png

STC32G12K128-35I-LQFP32管脚图
2.png

STC32G12K128-35I-LQFP48管脚图
3.png
STC32G12K128-35I-LQFP64管脚图
4.png

  • TA的每日心情
    开心
    2024-1-4 08:56
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    16

    主题

    702

    回帖

    2458

    积分

    超级版主

    积分
    2458
    发表于 2023-3-14 17:41:56 | 显示全部楼层
    STC32G系列单片机的高速PWM可以和CPU工作在不同频率
    STC32G12K128系列CPU最高工作频率可达35MHz
    STC32G8K64系列CPU最高工作频率可达42MHz
    上面两个系列的高级PWM均可工作在144MHz
    系统时钟树配置如下:
    1.png
    范例说明:
    1、时钟说明:由内部IRC产生12MHz的时钟提供给PLL当作PLL输入时钟,PLL锁频到144MHz输出作为高速PWM的时钟源,
         同时144MHz的PLL输出时钟通过CLKDIV进行4或者5分频,产生36MHz或者28.8MHz的时钟提供给CPU当作系统工作频率
    2、PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P2.0口输出频率为28.8MHz,占空比为40%的PWM型号
    3、PWM高速捕获说明:PWMB的CC5和CC6通道配置为捕获输入模式,CC5口P2.0口捕获信号的周期值,CC6从P2.0口捕获信号的占空比
    4、测试说明:最后通过查询方式得到周期值和占空比并从串口送到PC显示
    1. #include "stc32g.h"
    2. #include "stdio.h"
    3. #include "intrins.h"
    4. #define FOSC            12000000UL
    5. #define PLLCLK          144000000UL
    6. #define MCLKDIV         4               //144M/4=36M
    7. //#define MCLKDIV       5               //144M/5=28.8M
    8. #define MCLK            PLLCLK
    9. #define SYSCLK          MCLK/MCLKDIV
    10. #define BAUD            (65536 - SYSCLK/4/115200)
    11. #define MCLK_HIRC       0
    12. #define MCLK_IRC32K     1
    13. #define MCLK_IRC48M     2
    14. #define MCLK_XOSC       3
    15. #define MCLK_X32K       4
    16. #define MCLK_PLL        5
    17. #define MCLK_PLLD2      6
    18. #define MCLK_SEL        MCLK_PLL
    19. #define HSCK_MCLK       0
    20. #define HSCK_PLL        1
    21. #define HSCK_SEL        HSCK_PLL
    22. #define PLL_96M         0
    23. #define PLL_144M        1
    24. #define PLL_SEL         PLL_144M
    25. #define CKMS            0x80
    26. #define HSIOCK          0x40
    27. #define MCK2SEL_MSK     0x0c
    28. #define MCK2SEL_SEL1    0x00
    29. #define MCK2SEL_PLL     0x04
    30. #define MCK2SEL_PLLD2   0x08
    31. #define MCK2SEL_IRC48   0x0c
    32. #define MCKSEL_MSK      0x03
    33. #define MCKSEL_HIRC     0x00
    34. #define MCKSEL_XOSC     0x01
    35. #define MCKSEL_X32K     0x02
    36. #define MCKSEL_IRC32K   0x03
    37. #define ENCKM           0x80
    38. #define PCKI_MSK        0x60
    39. #define PCKI_D1         0x00
    40. #define PCKI_D2         0x20
    41. #define PCKI_D4         0x40
    42. #define PCKI_D8         0x60
    43. void delay()
    44. {
    45.     int i;
    46.    
    47.     for (i=0; i<100; i++);
    48. }
    49. char ReadPWMA(char addr)
    50. {
    51.     char dat;
    52.    
    53.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    54.     HSPWMA_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    55.                                             //HSPWMA_ADDR寄存器的最高位写1,表示读数据
    56.     while (HSPWMA_ADR & 0x80);              //等待当前异步读取完成
    57.     dat = HSPWMA_DAT;                       //读取异步数据
    58.    
    59.     return dat;
    60. }
    61. void WritePWMA(char addr, char dat)
    62. {
    63.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    64.     HSPWMA_DAT = dat;                       //准备需要写入的数据
    65.     HSPWMA_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    66.                                             //HSPWMA_ADDR寄存器的最高位写0,表示写数据
    67. }
    68. char ReadPWMB(char addr)
    69. {
    70.     char dat;
    71.    
    72.     while (HSPWMB_ADR & 0x80);              //等待前一个异步读写完成
    73.     HSPWMB_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    74.                                             //HSPWMB_ADDR寄存器的最高位写1,表示读数据
    75.     while (HSPWMB_ADR & 0x80);              //等待当前异步读取完成
    76.     dat = HSPWMB_DAT;                       //读取异步数据
    77.    
    78.     return dat;
    79. }
    80. void WritePWMB(char addr, char dat)
    81. {
    82.     while (HSPWMB_ADR & 0x80);              //等待前一个异步读写完成
    83.     HSPWMB_DAT = dat;                       //准备需要写入的数据
    84.     HSPWMB_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    85.                                             //HSPWMB_ADDR寄存器的最高位写0,表示写数据
    86. }
    87. void main()
    88. {
    89.     WTST = 0x00;
    90.     P_SW2 = 0x80;
    91.    
    92.     P0M0 = 0x00; P0M1 = 0x00;
    93.     P1M0 = 0x00; P1M1 = 0x00;
    94.     P2M0 = 0x00; P2M1 = 0x00;
    95.     P3M0 = 0x00; P3M1 = 0x00;
    96.     P5M0 = 0x10; P5M1 = 0x00;
    97.    
    98.     SCON = 0x52;
    99.     AUXR = 0x40;
    100.     TMOD = 0x00;
    101.     TL1 = BAUD;
    102.     TH1 = BAUD >> 8;
    103.     TR1 = 1;
    104.    
    105.     //选择PLL输出时钟
    106. #if (PLL_SEL == PLL_96M)
    107.     CLKSEL &= ~CKMS;                        //选择PLL的96M作为PLL的输出时钟
    108. #elif (PLL_SEL == PLL_144M)
    109.     CLKSEL |= CKMS;                         //选择PLL的144M作为PLL的输出时钟
    110. #else
    111.     CLKSEL &= ~CKMS;                        //默认选择PLL的96M作为PLL的输出时钟
    112. #endif
    113.    
    114.     //选择PLL输入时钟分频,保证输入时钟为12M
    115.     USBCLK &= ~PCKI_MSK;
    116. #if (FOSC == 12000000UL)
    117.     USBCLK |= PCKI_D1;                      //PLL输入时钟1分频
    118. #elif (FOSC == 24000000UL)
    119.     USBCLK |= PCKI_D2;                      //PLL输入时钟2分频
    120. #elif (FOSC == 48000000UL)
    121.     USBCLK |= PCKI_D4;                      //PLL输入时钟4分频
    122. #elif (FOSC == 96000000UL)
    123.     USBCLK |= PCKI_D8;                      //PLL输入时钟8分频
    124. #else
    125.     USBCLK |= PCKI_D1;                      //默认PLL输入时钟1分频
    126. #endif
    127.     //启动PLL
    128.     USBCLK |= ENCKM;                        //使能PLL倍频
    129.    
    130.     delay();                                //等待PLL锁频
    131.    
    132.     //选择主时钟源
    133.     CLKDIV = MCLKDIV;                       //主时钟选择高速频率前,必须先设置分频系数,否则程序会当掉
    134.    
    135.     CLKSEL &= ~MCKSEL_MSK;
    136.     CLKSEL &= ~MCK2SEL_MSK;
    137. #if (MCLK_SEL == MCLK_HIRC)
    138.     CLKSEL |= MCKSEL_HIRC;                  //选择内部高速IRC作为主时钟
    139.     CLKSEL |= MCK2SEL_SEL1;                 //选择MCKSEL选择的时钟作为主时钟
    140. #elif (MCLK_SEL == MCLK_IRC32K)
    141.     CLKSEL |= MCKSEL_X32K;                  //选择外部32K作为主时钟
    142.     CLKSEL |= MCK2SEL_SEL1;                 //选择MCKSEL选择的时钟作为主时钟
    143. #elif (MCLK_SEL == MCLK_IRC48M)
    144.     CLKSEL |= MCKSEL_HIRC;                  //选择内部高速IRC作为主时钟
    145.     CLKSEL |= MCK2SEL_IRC48;                //选择内部48M的IRC作为主时钟
    146. #elif (MCLK_SEL == MCLK_XOSC)
    147.     CLKSEL |= MCKSEL_XOSC;                  //选择外部高速晶振作为主时钟
    148.     CLKSEL |= MCK2SEL_SEL1;                 //选择MCKSEL选择的时钟作为主时钟
    149. #elif (MCLK_SEL == MCLK_X32K)
    150.     CLKSEL |= MCKSEL_IRC32K;                //选择内部低速IRC作为主时钟
    151.     CLKSEL |= MCK2SEL_SEL1;                 //选择MCKSEL选择的时钟作为主时钟
    152. #elif (MCLK_SEL == MCLK_PLL)
    153.     CLKSEL |= MCKSEL_HIRC;                  //选择内部高速IRC作为主时钟
    154.     CLKSEL |= MCK2SEL_PLL;                  //选择PLL输出时钟作为主时钟
    155. #elif (MCLK_SEL == MCLK_PLLD2)
    156.     CLKSEL |= MCKSEL_HIRC;                  //选择内部高速IRC作为主时钟
    157.     CLKSEL |= MCK2SEL_PLLD2;                //选择PLL输出时钟2分频后的时钟作为主时钟
    158. #else
    159.     CLKSEL |= MCKSEL_HIRC;                  //默认选择内部高速IRC作为主时钟
    160.     CLKSEL |= MCK2SEL_SEL1;                 //默认选择MCKSEL选择的时钟作为主时钟
    161. #endif
    162.     MCLKOCR = 0x04;                         //系统时钟4分频后输出到P5.4口
    163.     //选择HSPWM/HSSPI时钟
    164. #if (HSCK_SEL == HSCK_MCLK)
    165.     CLKSEL &= ~HSIOCK;                      //HSPWM/HSSPI选择主时钟为时钟源
    166. #elif (HSCK_SEL == HSCK_PLL)
    167.     CLKSEL |= HSIOCK;                       //HSPWM/HSSPI选择PLL输出时钟为时钟源
    168. #else
    169.     CLKSEL &= ~HSIOCK;                      //默认HSPWM/HSSPI选择主时钟为时钟源
    170. #endif
    171.     HSCLKDIV = 0;                           //HSPWM/HSSPI时钟源不分频
    172.    
    173.     HSPWMA_CFG = 0x03;                      //使能PWMA相关寄存器异步访问功能
    174.     HSPWMB_CFG = 0x03;                      //使能PWMB相关寄存器异步访问功能
    175.    
    176.     PWMA_PS = 0x01;                         //PWMA_CC1高速PWM输出到P2.0口
    177.                                             //PWMB_CC5从P2.0口进行捕获
    178.     //通过异步方式设置PWMA/PWMB的相关寄存器
    179.     WritePWMA((char)&PWMA_CCER1, 0x00);
    180.     WritePWMA((char)&PWMA_CCMR1, 0x00);     //CC1为输出模式
    181.     WritePWMA((char)&PWMA_CCMR1, 0x60);     //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
    182.     WritePWMA((char)&PWMA_CCER1, 0x05);     //使能CC1/CC1N上的输出功能
    183.     WritePWMA((char)&PWMA_ENO, 0x03);       //使能PWM信号输出到端口
    184.     WritePWMA((char)&PWMA_BKR, 0x80);       //使能主输出
    185.     WritePWMA((char)&PWMA_CCR1H, 0x00);     //设置输出PWM的占空比
    186.     WritePWMA((char)&PWMA_CCR1L, 0x02);
    187.     WritePWMA((char)&PWMA_ARRH, 0x00);      //设置输出PWM的周期
    188.     WritePWMA((char)&PWMA_ARRL, 0x04);
    189.     WritePWMA((char)&PWMA_CR1, 0x01);       //开始PWM计数
    190.     WritePWMB((char)&PWMB_CCER1, 0x00);
    191.     WritePWMB((char)&PWMB_CCMR1, 0x01);     //CC5为输入模式,且映射到TI5FP5上
    192.     WritePWMB((char)&PWMB_CCMR2, 0x02);     //CC6为输入模式,且映射到TI6FP5上
    193.     WritePWMB((char)&PWMB_CCER1, 0x31);     //使能CC5上的捕获功能(上升沿捕获)
    194.     WritePWMB((char)&PWMB_SMCR, 0x54);      //上升沿复位模式
    195.     WritePWMB((char)&PWMB_CR1, 0x01);       //开始PWM计数
    196.    
    197.     while (1)
    198.     {
    199.         if (ReadPWMB((char)&PWMB_SR1) & 0x02)   //等待捕获完成
    200.         {
    201.             WritePWMB((char)&PWMB_SR1, 0x00);   //清除完成标志
    202.             
    203.             //读取捕获到的周期值
    204.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5H) & 0xff);
    205.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5L) & 0xff);
    206.             printf(" ");
    207.             
    208.             //读取捕获到的占空比值
    209.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6H) & 0xff);
    210.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6L) & 0xff);
    211.             printf("\n");
    212.         }
    213.     }
    214. }
    复制代码

    高速PWM使用PLL时钟实现高速输出和高速捕获功能.zip

    37.21 KB, 下载次数: 125

    该用户从未签到

    538

    主题

    8729

    回帖

    1万

    积分

    管理员

    积分
    14201
     楼主| 发表于 2023-3-14 19:15:52 | 显示全部楼层
    PWM测量外部信号是输入,跟I/O对外的输出速度无关,输入速度可以很快
    I/O的输出也可以做的很快,但就会对外电磁辐射大,
    所以I/O对外输出STC实际加了滤波电路,这限制了I/O对外输出的速度,输出大概28MHz 附近
    这样I/O的输出对外电磁辐射就很小,完美
  • TA的每日心情
    无聊
    2023-11-26 13:41
  • 签到天数: 1 天

    [LV.1]初来乍到

    14

    主题

    85

    回帖

    605

    积分

    高级会员

    积分
    605
    发表于 2023-3-18 09:09:20 | 显示全部楼层
    之前我一直以为I/O口的翻转速度会限制其输入信号的频率,而其翻转频率不能太高。看了本文后感觉I/O口在做输入用时,不需要翻转,就能把输入的信息接受,并进行处理,我去实际测一下看看效果。

    该用户从未签到

    5

    主题

    25

    回帖

    99

    积分

    注册会员

    积分
    99
    发表于 2023-3-20 07:25:42 | 显示全部楼层
    用这个特点能做个啥玩意?

    该用户从未签到

    538

    主题

    8729

    回帖

    1万

    积分

    管理员

    积分
    14201
     楼主| 发表于 2023-3-20 08:53:17 | 显示全部楼层
    能测量频率比较高的外部脉冲

    该用户从未签到

    0

    主题

    4

    回帖

    18

    积分

    新手上路

    积分
    18
    发表于 2023-3-23 11:05:47 | 显示全部楼层
    可以做个逻辑分析仪:lol

    该用户从未签到

    1

    主题

    2

    回帖

    13

    积分

    新手上路

    积分
    13
    发表于 2023-4-2 16:28:49 | 显示全部楼层
    请教一下,测量72M一下信号频率对信号的上升沿或者下降沿时间有没有要求,比如我的待测频率是50M,虽然周期是20nS,但是脉冲宽度只有4nS,这样的频率信号可以测量吗?

    点评

    如果是测频率,可以分频后再测。内部分频也要补超过72MHz的频率,高、低电平均大于7ns才行,4ns不行的。  详情 回复 发表于 2023-8-7 17:12
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    538

    主题

    8729

    回帖

    1万

    积分

    管理员

    积分
    14201
     楼主| 发表于 2023-4-2 16:38:56 | 显示全部楼层
    占空比不是50%的,速度肯定上不来,
    占空比50%, 理想状态,PWM的时钟源是 144MHz, 就可以测量 72MHz 以下
    这个 PLL时钟是:
    1,  PLL锁相环有2级:
         A, 输入时钟频率*8后输出;  
         B, 输入时钟频率*12后输出 !

    2,输入时钟只能在 【8MHz ~ 16MHz】范围;

    3,  所以PLL时钟输出到PWM作为时钟源输入的频率可以在 【64MHz ~ 192MHz】
    回复 支持 反对 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-3-29 00:40 , Processed in 0.074464 second(s), 69 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表