找回密码
 立即注册
楼主: ad***

硬件三角函数运算器, 硬件浮点运算器, 追风剑-STC32F12K64-56MHz,FOC方案征集

[复制链接]
  • TA的每日心情
    开心
    2024-4-29 10:31
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    16

    主题

    717

    回帖

    2548

    积分

    超级版主

    积分
    2548
    发表于 2023-6-13 20:09:17 | 显示全部楼层
    250MHz时钟源 PWM,  STC32F12K54-56MHz
    ——高速PWM应用1:  高速PWM输出
    ——高速PWM应用2:捕获外部高速脉宽(查询方式)
    ——高速PWM应用3:捕获外部高速脉宽(中断方式)


    高速PWM应用2: 捕获外部高速脉宽(查询方式)
    高速PWM可使用内建500MHz高速HPLL作为时钟源【输出高速PWM】/【捕获外部高速脉宽】
    (注:500MHz的HPLL时钟2分频输出50%占空比的PLL输出时钟可作为高速PWM的时钟源)
    1. /*************  功能说明    **************
    2. 时钟说明:由内部IRC产生24MHz的时钟分频为6M提供给HPLL当作HPLL输入时钟,PLL锁频到246MHz输出作为高速PWM的时钟源,
    3. PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P2.0口输出频率为24.6MHz,占空比为20%的PWM型号
    4. PWM高速捕获说明:PWMB的CC5和CC6通道配置为捕获输入模式,CC5口P2.0口捕获信号的周期值,CC6从P2.0口捕获信号的占空比
    5. 测试说明:最后通过查询方式得到周期值和占空比并从串口送到PC显示
    6. 下载时, 选择默认IRC时钟 24MHz。
    7. ******************************************/
    8. #include "stc32g.h"
    9. #include "stdio.h"
    10. #define FOSC            24000000UL
    11. #define BAUD            (65536 - FOSC/4/115200)
    12. #define HSCK_MCLK       0
    13. #define HSCK_PLL        1
    14. #define HSCK_SEL        HSCK_PLL
    15. #define HSIOCK          0x40
    16. #define ENHPLL          0x80
    17. #define HPLLDIV_52      0x00
    18. #define HPLLDIV_54      0x01
    19. #define HPLLDIV_56      0x02
    20. #define HPLLDIV_58      0x03
    21. #define HPLLDIV_60      0x04
    22. #define HPLLDIV_62      0x05
    23. #define HPLLDIV_64      0x06
    24. #define HPLLDIV_66      0x07
    25. #define HPLLDIV_68      0x08
    26. #define HPLLDIV_70      0x09
    27. #define HPLLDIV_72      0x0A
    28. #define HPLLDIV_74      0x0B
    29. #define HPLLDIV_76      0x0C
    30. #define HPLLDIV_78      0x0D
    31. #define HPLLDIV_80      0x0E
    32. #define HPLLDIV_82      0x0F
    33. #define ENCKM           0x80
    34. #define PCKI_MSK        0x60
    35. #define PCKI_D1         0x00
    36. #define PCKI_D2         0x20
    37. #define PCKI_D4         0x40
    38. #define PCKI_D8         0x60
    39. void delay()
    40. {
    41.     int i;
    42.     for (i=0; i<100; i++);
    43. }
    44. char ReadPWMA(char addr)
    45. {
    46.     char dat;
    47.    
    48.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    49.     HSPWMA_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    50.                                             //HSPWMA_ADDR寄存器的最高位写1,表示读数据
    51.     while (HSPWMA_ADR & 0x80);              //等待当前异步读取完成
    52.     dat = HSPWMA_DAT;                       //读取异步数据
    53.    
    54.     return dat;
    55. }
    56. void WritePWMA(char addr, char dat)
    57. {
    58.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    59.     HSPWMA_DAT = dat;                       //准备需要写入的数据
    60.     HSPWMA_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    61.                                             //HSPWMA_ADDR寄存器的最高位写0,表示写数据
    62. }
    63. char ReadPWMB(char addr)
    64. {
    65.     char dat;
    66.    
    67.     while (HSPWMB_ADR & 0x80);              //等待前一个异步读写完成
    68.     HSPWMB_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    69.                                             //HSPWMB_ADDR寄存器的最高位写1,表示读数据
    70.     while (HSPWMB_ADR & 0x80);              //等待当前异步读取完成
    71.     dat = HSPWMB_DAT;                       //读取异步数据
    72.    
    73.     return dat;
    74. }
    75. void WritePWMB(char addr, char dat)
    76. {
    77.     while (HSPWMB_ADR & 0x80);              //等待前一个异步读写完成
    78.     HSPWMB_DAT = dat;                       //准备需要写入的数据
    79.     HSPWMB_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    80.                                             //HSPWMB_ADDR寄存器的最高位写0,表示写数据
    81. }
    82. int main()
    83. {
    84.     EAXFR = 1;
    85.    
    86.     P0M0 = 0; P0M1 = 0;
    87.     P1M0 = 0; P1M1 = 0;
    88.     P2M0 = 0; P2M1 = 0;
    89.     P3M0 = 0; P3M1 = 0;
    90.     P4M0 = 0; P4M1 = 0;
    91.     P5M0 = 0; P5M1 = 0;
    92.    
    93.     SCON = 0x52;
    94.     AUXR = 0x40;
    95.     TMOD = 0x00;
    96.     TL1 = BAUD;
    97.     TH1 = BAUD >> 8;
    98.     TR1 = 1;
    99.     //选择HPLL输入时钟分频,保证输入时钟为6M
    100.     USBCLK &= ~PCKI_MSK;
    101. #if (FOSC == 6000000UL)
    102.     USBCLK |= PCKI_D1;                      //PLL输入时钟1分频
    103. #elif (FOSC == 12000000UL)
    104.     USBCLK |= PCKI_D2;                      //PLL输入时钟2分频
    105. #elif (FOSC == 24000000UL)
    106.     USBCLK |= PCKI_D4;                      //PLL输入时钟4分频
    107. #elif (FOSC == 48000000UL)
    108.     USBCLK |= PCKI_D8;                      //PLL输入时钟8分频
    109. #else
    110.     USBCLK |= PCKI_D4;                      //默认PLL输入时钟4分频
    111. #endif
    112.     //设置HPLL的除频系数
    113. //    HPLLCR = HPLLDIV_52;                  //F_HPLL=6M*52/2=156M
    114. //    HPLLCR = HPLLDIV_54;                  //F_HPLL=6M*54/2=162M
    115. //    HPLLCR = HPLLDIV_56;                  //F_HPLL=6M*56/2=168M
    116. //    HPLLCR = HPLLDIV_58;                  //F_HPLL=6M*58/2=174M
    117. //    HPLLCR = HPLLDIV_60;                  //F_HPLL=6M*60/2=180M
    118. //    HPLLCR = HPLLDIV_62;                  //F_HPLL=6M*62/2=186M
    119. //    HPLLCR = HPLLDIV_64;                  //F_HPLL=6M*64/2=192M
    120. //    HPLLCR = HPLLDIV_66;                  //F_HPLL=6M*66/2=198M
    121. //    HPLLCR = HPLLDIV_68;                  //F_HPLL=6M*68/2=204M
    122. //    HPLLCR = HPLLDIV_70;                  //F_HPLL=6M*70/2=210M
    123. //    HPLLCR = HPLLDIV_72;                  //F_HPLL=6M*72/2=216M
    124. //    HPLLCR = HPLLDIV_74;                  //F_HPLL=6M*74/2=222M
    125. //    HPLLCR = HPLLDIV_76;                  //F_HPLL=6M*76/2=228M
    126. //    HPLLCR = HPLLDIV_78;                  //F_HPLL=6M*78/2=234M
    127. //    HPLLCR = HPLLDIV_80;                  //F_HPLL=6M*80/2=240M
    128.     HPLLCR = HPLLDIV_82;                    //F_HPLL=6M*82/2=246M
    129.     //启动HPLL
    130.     HPLLCR |= ENHPLL;                       //使能HPLL
    131.     delay();                                //等待HPLL时钟稳定
    132.     //选择HSPWM/HSSPI时钟
    133. #if (HSCK_SEL == HSCK_MCLK)
    134.     CLKSEL &= ~HSIOCK;                      //HSPWM/HSSPI选择主时钟为时钟源
    135. #elif (HSCK_SEL == HSCK_PLL)
    136.     CLKSEL |= HSIOCK;                       //HSPWM/HSSPI选择PLL输出时钟为时钟源
    137. #else
    138.     CLKSEL &= ~HSIOCK;                      //默认HSPWM/HSSPI选择主时钟为时钟源
    139. #endif
    140.     HSCLKDIV = 0;                           //HSPWM/HSSPI时钟源不分频
    141.    
    142.     HSPWMA_CFG = 0x03;                      //使能PWMA相关寄存器异步访问功能
    143.    
    144.    
    145.     HSPWMA_CFG = 0x03;                      //使能PWMA相关寄存器异步访问功能
    146.     HSPWMB_CFG = 0x03;                      //使能PWMB相关寄存器异步访问功能
    147.    
    148.     PWMA_PS = 0x01;                         //PWMA_CC1高速PWM输出到P2.0口
    149.                                             //PWMB_CC5/PWMB_CC6从P2.0口进行捕获
    150.                                             //注意:PWMA_PS和PWMB_PS属于I/O控制寄存器,不能使用异步方式进行读写
    151.     //通过异步方式设置PWMA/PWMB的相关寄存器
    152.     WritePWMA((char)&PWMA_CCER1, 0x00);
    153.     WritePWMA((char)&PWMA_CCMR1, 0x00);     //CC1为输出模式
    154.     WritePWMA((char)&PWMA_CCMR1, 0x60);     //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
    155.     WritePWMA((char)&PWMA_CCER1, 0x05);     //使能CC1/CC1N上的输出功能
    156.     WritePWMA((char)&PWMA_ENO, 0x01);       //使能PWM信号输出到端口
    157.     WritePWMA((char)&PWMA_BKR, 0x80);       //使能主输出
    158.     WritePWMA((char)&PWMA_CCR1H, 0x00);     //设置输出PWM的占空比
    159.     WritePWMA((char)&PWMA_CCR1L, 0x02);
    160.     WritePWMA((char)&PWMA_ARRH, 0x00);      //设置输出PWM的周期
    161.     WritePWMA((char)&PWMA_ARRL, 0x09);
    162.     WritePWMA((char)&PWMA_CR1, 0x01);       //开始PWM计数
    163.     WritePWMB((char)&PWMB_CCER1, 0x00);
    164.     WritePWMB((char)&PWMB_CCMR1, 0x01);     //CC5为输入模式,且映射到TI5FP5上
    165.     WritePWMB((char)&PWMB_CCMR2, 0x02);     //CC6为输入模式,且映射到TI6FP5上
    166.     WritePWMB((char)&PWMB_CCER1, 0x31);     //使能CC5上的捕获功能(上升沿捕获)
    167.     WritePWMB((char)&PWMB_SMCR, 0x54);      //上升沿复位模式
    168.     WritePWMB((char)&PWMB_CR1, 0x01);       //开始PWM计数
    169.    
    170.     while (1)
    171.     {
    172.         if (ReadPWMB((char)&PWMB_SR1) & 0x02)   //等待捕获完成
    173.         {
    174.             WritePWMB((char)&PWMB_SR1, 0x00);   //清除完成标志
    175.             
    176.             //读取捕获到的周期值
    177.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5H) & 0xff);
    178.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5L) & 0xff);
    179.             printf(" ");
    180.             
    181.             //读取捕获到的占空比值
    182.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6H) & 0xff);
    183.             printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6L) & 0xff);
    184.             printf("\n");
    185.         }
    186.     }
    187. }
    复制代码

    PWM使用HPLL时钟(高速捕获-查询方式).zip

    36.2 KB, 下载次数: 24

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-29 10:31
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    16

    主题

    717

    回帖

    2548

    积分

    超级版主

    积分
    2548
    发表于 2023-6-13 20:15:33 | 显示全部楼层
    250MHz时钟源 PWM,  STC32F12K54-56MHz
    ——高速PWM应用1:  高速PWM输出
    ——高速PWM应用2:捕获外部高速脉宽(查询方式)
    ——高速PWM应用3:捕获外部高速脉宽(中断方式)


    高速PWM应用3: 捕获外部高速脉宽(中断方式)
    高速PWM可使用内建500MHz高速HPLL作为时钟源【输出高速PWM】/【捕获外部高速脉宽】
    (注:500MHz的HPLL时钟2分频输出50%占空比的PLL输出时钟可作为高速PWM的时钟源)
    1. /*************  功能说明    **************
    2. 时钟说明:由内部IRC产生24MHz的时钟分频为6M提供给HPLL当作HPLL输入时钟,PLL锁频到246MHz输出作为高速PWM的时钟源,
    3. PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P2.0口输出频率为24.6MHz,占空比为20%的PWM型号
    4. PWM高速捕获说明:PWMB的CC5和CC6通道配置为捕获输入模式,CC5口P2.0口捕获信号的周期值,CC6从P2.0口捕获信号的占空比
    5. 测试说明:最后通过中断方式得到周期值和占空比并从串口送到PC显示(注意要避免中断与主循环同时调用相同函数)
    6. 下载时, 选择默认IRC时钟 24MHz。
    7. ******************************************/
    8. #include "stc32g.h"
    9. #include "stdio.h"
    10. #define FOSC            24000000UL
    11. #define BAUD            (65536 - FOSC/4/115200)
    12. #define HSCK_MCLK       0
    13. #define HSCK_PLL        1
    14. #define HSCK_SEL        HSCK_PLL
    15. #define HSIOCK          0x40
    16. #define ENHPLL          0x80
    17. #define HPLLDIV_52      0x00
    18. #define HPLLDIV_54      0x01
    19. #define HPLLDIV_56      0x02
    20. #define HPLLDIV_58      0x03
    21. #define HPLLDIV_60      0x04
    22. #define HPLLDIV_62      0x05
    23. #define HPLLDIV_64      0x06
    24. #define HPLLDIV_66      0x07
    25. #define HPLLDIV_68      0x08
    26. #define HPLLDIV_70      0x09
    27. #define HPLLDIV_72      0x0A
    28. #define HPLLDIV_74      0x0B
    29. #define HPLLDIV_76      0x0C
    30. #define HPLLDIV_78      0x0D
    31. #define HPLLDIV_80      0x0E
    32. #define HPLLDIV_82      0x0F
    33. #define ENCKM           0x80
    34. #define PCKI_MSK        0x60
    35. #define PCKI_D1         0x00
    36. #define PCKI_D2         0x20
    37. #define PCKI_D4         0x40
    38. #define PCKI_D8         0x60
    39. void delay()
    40. {
    41.     int i;
    42.     for (i=0; i<100; i++);
    43. }
    44. char ReadPWMA(char addr)
    45. {
    46.     char dat;
    47.    
    48.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    49.     HSPWMA_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    50.                                             //HSPWMA_ADDR寄存器的最高位写1,表示读数据
    51.     while (HSPWMA_ADR & 0x80);              //等待当前异步读取完成
    52.     dat = HSPWMA_DAT;                       //读取异步数据
    53.    
    54.     return dat;
    55. }
    56. void WritePWMA(char addr, char dat)
    57. {
    58.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    59.     HSPWMA_DAT = dat;                       //准备需要写入的数据
    60.     HSPWMA_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    61.                                             //HSPWMA_ADDR寄存器的最高位写0,表示写数据
    62. }
    63. char ReadPWMB(char addr)
    64. {
    65.     char dat;
    66.    
    67.     while (HSPWMB_ADR & 0x80);              //等待前一个异步读写完成
    68.     HSPWMB_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    69.                                             //HSPWMB_ADDR寄存器的最高位写1,表示读数据
    70.     while (HSPWMB_ADR & 0x80);              //等待当前异步读取完成
    71.     dat = HSPWMB_DAT;                       //读取异步数据
    72.    
    73.     return dat;
    74. }
    75. void WritePWMB(char addr, char dat)
    76. {
    77.     while (HSPWMB_ADR & 0x80);              //等待前一个异步读写完成
    78.     HSPWMB_DAT = dat;                       //准备需要写入的数据
    79.     HSPWMB_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    80.                                             //HSPWMB_ADDR寄存器的最高位写0,表示写数据
    81. }
    82. int main()
    83. {
    84.     EAXFR = 1;
    85.    
    86.     P0M0 = 0; P0M1 = 0;
    87.     P1M0 = 0; P1M1 = 0;
    88.     P2M0 = 0; P2M1 = 0;
    89.     P3M0 = 0; P3M1 = 0;
    90.     P4M0 = 0; P4M1 = 0;
    91.     P5M0 = 0; P5M1 = 0;
    92.    
    93.     SCON = 0x52;
    94.     AUXR = 0x40;
    95.     TMOD = 0x00;
    96.     TL1 = BAUD;
    97.     TH1 = BAUD >> 8;
    98.     TR1 = 1;
    99.     //选择HPLL输入时钟分频,保证输入时钟为6M
    100.     USBCLK &= ~PCKI_MSK;
    101. #if (FOSC == 6000000UL)
    102.     USBCLK |= PCKI_D1;                      //PLL输入时钟1分频
    103. #elif (FOSC == 12000000UL)
    104.     USBCLK |= PCKI_D2;                      //PLL输入时钟2分频
    105. #elif (FOSC == 24000000UL)
    106.     USBCLK |= PCKI_D4;                      //PLL输入时钟4分频
    107. #elif (FOSC == 48000000UL)
    108.     USBCLK |= PCKI_D8;                      //PLL输入时钟8分频
    109. #else
    110.     USBCLK |= PCKI_D4;                      //默认PLL输入时钟4分频
    111. #endif
    112.     //设置HPLL的除频系数
    113. //    HPLLCR = HPLLDIV_52;                  //F_HPLL=6M*52/2=156M
    114. //    HPLLCR = HPLLDIV_54;                  //F_HPLL=6M*54/2=162M
    115. //    HPLLCR = HPLLDIV_56;                  //F_HPLL=6M*56/2=168M
    116. //    HPLLCR = HPLLDIV_58;                  //F_HPLL=6M*58/2=174M
    117. //    HPLLCR = HPLLDIV_60;                  //F_HPLL=6M*60/2=180M
    118. //    HPLLCR = HPLLDIV_62;                  //F_HPLL=6M*62/2=186M
    119. //    HPLLCR = HPLLDIV_64;                  //F_HPLL=6M*64/2=192M
    120. //    HPLLCR = HPLLDIV_66;                  //F_HPLL=6M*66/2=198M
    121. //    HPLLCR = HPLLDIV_68;                  //F_HPLL=6M*68/2=204M
    122. //    HPLLCR = HPLLDIV_70;                  //F_HPLL=6M*70/2=210M
    123. //    HPLLCR = HPLLDIV_72;                  //F_HPLL=6M*72/2=216M
    124. //    HPLLCR = HPLLDIV_74;                  //F_HPLL=6M*74/2=222M
    125. //    HPLLCR = HPLLDIV_76;                  //F_HPLL=6M*76/2=228M
    126. //    HPLLCR = HPLLDIV_78;                  //F_HPLL=6M*78/2=234M
    127. //    HPLLCR = HPLLDIV_80;                  //F_HPLL=6M*80/2=240M
    128.     HPLLCR = HPLLDIV_82;                    //F_HPLL=6M*82/2=246M
    129.     //启动HPLL
    130.     HPLLCR |= ENHPLL;                       //使能HPLL
    131.     delay();                                //等待HPLL时钟稳定
    132.     //选择HSPWM/HSSPI时钟
    133. #if (HSCK_SEL == HSCK_MCLK)
    134.     CLKSEL &= ~HSIOCK;                      //HSPWM/HSSPI选择主时钟为时钟源
    135. #elif (HSCK_SEL == HSCK_PLL)
    136.     CLKSEL |= HSIOCK;                       //HSPWM/HSSPI选择PLL输出时钟为时钟源
    137. #else
    138.     CLKSEL &= ~HSIOCK;                      //默认HSPWM/HSSPI选择主时钟为时钟源
    139. #endif
    140.     HSCLKDIV = 0;                           //HSPWM/HSSPI时钟源不分频
    141.    
    142.     HSPWMA_CFG = 0x03;                      //使能PWMA相关寄存器异步访问功能
    143.     HSPWMB_CFG = 0x07;                      //使能PWMB相关寄存器异步访问功能,并使能异步模式的PWMB中断
    144.    
    145.     PWMA_PS = 0x01;                         //PWMA_CC1高速PWM输出到P2.0口
    146.                                             //PWMB_CC5/PWMB_CC6从P2.0口进行捕获
    147.                                             //注意:PWMA_PS和PWMB_PS属于I/O控制寄存器,不能使用异步方式进行读写
    148.     //通过异步方式设置PWMA/PWMB的相关寄存器
    149.     WritePWMA((char)&PWMA_CCER1, 0x00);
    150.     WritePWMA((char)&PWMA_CCMR1, 0x00);     //CC1为输出模式
    151.     WritePWMA((char)&PWMA_CCMR1, 0x60);     //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
    152.     WritePWMA((char)&PWMA_CCER1, 0x05);     //使能CC1/CC1N上的输出功能
    153.     WritePWMA((char)&PWMA_ENO, 0x01);       //使能PWM信号输出到端口
    154.     WritePWMA((char)&PWMA_BKR, 0x80);       //使能主输出
    155.     WritePWMA((char)&PWMA_CCR1H, 0x00);     //设置输出PWM的占空比
    156.     WritePWMA((char)&PWMA_CCR1L, 0x02);
    157.     WritePWMA((char)&PWMA_ARRH, 0x00);      //设置输出PWM的周期
    158.     WritePWMA((char)&PWMA_ARRL, 0x09);
    159.     WritePWMA((char)&PWMA_CR1, 0x01);       //开始PWM计数
    160.     WritePWMB((char)&PWMB_CCER1, 0x00);
    161.     WritePWMB((char)&PWMB_CCMR1, 0x01);     //CC5为输入模式,且映射到TI5FP5上
    162.     WritePWMB((char)&PWMB_CCMR2, 0x02);     //CC6为输入模式,且映射到TI6FP5上
    163.     WritePWMB((char)&PWMB_CCER1, 0x31);     //使能CC5上的捕获功能(上升沿捕获)
    164.     WritePWMB((char)&PWMB_SMCR, 0x54);      //上升沿复位模式
    165.     WritePWMB((char)&PWMB_CR1, 0x01);       //开始PWM计数
    166.     WritePWMB((char)&PWMB_IER, 0x02);       //使能CC5捕获中断
    167.    
    168.     EA = 1;
    169.    
    170.     while (1);
    171. }
    172. void PWMB_ISR() interrupt 27
    173. {
    174.     if (ReadPWMB((char)&PWMB_SR1) & 0x02)   //等待捕获完成
    175.     {
    176.         WritePWMB((char)&PWMB_SR1, 0x00);   //清除完成标志
    177.         
    178.         //读取捕获到的周期值
    179.         printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5H) & 0xff);
    180.         printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5L) & 0xff);
    181.         printf(" ");
    182.         
    183.         //读取捕获到的占空比值
    184.         printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6H) & 0xff);
    185.         printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6L) & 0xff);
    186.         printf("\n");
    187.     }
    188. }
    复制代码

    PWM使用HPLL时钟(高速捕获-中断方式).zip

    40.08 KB, 下载次数: 24

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-29 10:31
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    16

    主题

    717

    回帖

    2548

    积分

    超级版主

    积分
    2548
    发表于 2023-6-14 09:59:03 | 显示全部楼层
    307MHz时钟源 PWM, STC32F12K54-56MHz
    ——高速PWM应用1:  高速PWM输出
    ——高速PWM应用2:捕获外部高速脉宽(查询方式)
    ——高速PWM应用3:捕获外部高速脉宽(中断方式)

    高速PWM应用1: 高速PWM输出(CPU工作频率60MHz+ICache)
    高速PWM可使用内建500MHz高速HPLL作为时钟源【输出高速PWM】/【捕获外部高速脉宽】
    (特别的:高速HPLL时钟输入范围6M~12M。本范例高速HPLL输入频率为7.5MHz,

    产生615MHz的HPLL时钟2分频输出50%占空比的PLL输出频率307.5MHz可作为高速PWM的时钟源)
    1. /*************  功能说明    **************
    2. 时钟说明:由内部IRC产生60MHz的时钟当作CPU时钟,同时8分频产生7.5M提供给HPLL
    3.           当作HPLL输入时钟,PLL锁频到307.5MHz输出作为高速PWM的时钟源,
    4. PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P1.0/P1.1口输出频率为3.705MHz,
    5.                  占空比为50%的互补对称带死区的PWM波形
    6. CPU时钟说明:ISP下载软件根据CPU工作频率为60MHz,会自动将WTST设置为2
    7.              用户代码中不用对WTST进行设置。范例中使能了ICACHE功能,
    8.              可有效的提高代码执行效率
    9. 下载时, 选择默认IRC时钟 60MHz。
    10. ******************************************/
    11. #include "stc32g.h"
    12. #define FOSC            60000000UL
    13. #define HSCK_MCLK       0
    14. #define HSCK_PLL        1
    15. #define HSCK_SEL        HSCK_PLL
    16. #define HSIOCK          0x40
    17. #define ENHPLL          0x80
    18. #define HPLLDIV_52      0x00
    19. #define HPLLDIV_54      0x01
    20. #define HPLLDIV_56      0x02
    21. #define HPLLDIV_58      0x03
    22. #define HPLLDIV_60      0x04
    23. #define HPLLDIV_62      0x05
    24. #define HPLLDIV_64      0x06
    25. #define HPLLDIV_66      0x07
    26. #define HPLLDIV_68      0x08
    27. #define HPLLDIV_70      0x09
    28. #define HPLLDIV_72      0x0A
    29. #define HPLLDIV_74      0x0B
    30. #define HPLLDIV_76      0x0C
    31. #define HPLLDIV_78      0x0D
    32. #define HPLLDIV_80      0x0E
    33. #define HPLLDIV_82      0x0F
    34. #define ENCKM           0x80
    35. #define PCKI_MSK        0x60
    36. #define PCKI_D1         0x00
    37. #define PCKI_D2         0x20
    38. #define PCKI_D4         0x40
    39. #define PCKI_D8         0x60
    40. void delay()
    41. {
    42.     int i;
    43.     for (i=0; i<100; i++);
    44. }
    45. void ICacheOn()
    46. {
    47.     bit fEA;
    48.    
    49.     if (WTST > 0)                           //WTST为0时不需要且不能使能ICACHE
    50.     {
    51.         fEA = EA;                           //保存EA
    52.         EA = 0;                             //关闭中断
    53.         _nop_();
    54.         _nop_();
    55.         TA = 0xaa;                          //写入触发命令序列1
    56.                                             //此处不能有其他任何指令
    57.         TA = 0x55;                          //写入触发命令序列2
    58.                                             //此处不能有其他任何指令
    59.         ICHECR = 0x01;                      //写保护暂时关闭,可以修改ICHECR中的EN位
    60.                                             //EN位再次进入写保护状态
    61.         _nop_();
    62.         _nop_();
    63.         EA = fEA;                           //恢复EA
    64.     }
    65. }
    66. char ReadPWMA(char addr)
    67. {
    68.     char dat;
    69.    
    70.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    71.     HSPWMA_ADR = addr | 0x80;               //设置间接访问地址,只需要设置原XFR地址的低7位
    72.                                             //HSPWMA_ADDR寄存器的最高位写1,表示读数据
    73.     while (HSPWMA_ADR & 0x80);              //等待当前异步读取完成
    74.     dat = HSPWMA_DAT;                       //读取异步数据
    75.    
    76.     return dat;
    77. }
    78. void WritePWMA(char addr, char dat)
    79. {
    80.     while (HSPWMA_ADR & 0x80);              //等待前一个异步读写完成
    81.     HSPWMA_DAT = dat;                       //准备需要写入的数据
    82.     HSPWMA_ADR = addr & 0x7f;               //设置间接访问地址,只需要设置原XFR地址的低7位
    83.                                             //HSPWMA_ADDR寄存器的最高位写0,表示写数据
    84. }
    85. int main()
    86. {
    87.     ICacheOn();                             //使能ICACHE功能
    88.    
    89.     EAXFR = 1;
    90.    
    91.     P0M0 = 0; P0M1 = 0;
    92.     P1M0 = 0; P1M1 = 0;
    93.     P2M0 = 0; P2M1 = 0;
    94.     P3M0 = 0; P3M1 = 0;
    95.     P4M0 = 0; P4M1 = 0;
    96.     P5M0 = 0; P5M1 = 0;
    97.     //选择HPLL输入时钟分频
    98.     USBCLK &= ~PCKI_MSK;
    99.     USBCLK |= PCKI_D8;                      //PLL输入时钟8分频
    100.     //设置HPLL的除频系数
    101.     HPLLCR = HPLLDIV_82;                    //F_HPLL=60M/8*82/2=307.5M
    102.     //启动HPLL
    103.     HPLLCR |= ENHPLL;                       //使能HPLL
    104.     delay();                                //等待HPLL时钟稳定
    105.     //选择HSPWM/HSSPI时钟
    106. #if (HSCK_SEL == HSCK_MCLK)
    107.     CLKSEL &= ~HSIOCK;                      //HSPWM/HSSPI选择主时钟为时钟源
    108. #elif (HSCK_SEL == HSCK_PLL)
    109.     CLKSEL |= HSIOCK;                       //HSPWM/HSSPI选择PLL输出时钟为时钟源
    110. #else
    111.     CLKSEL &= ~HSIOCK;                      //默认HSPWM/HSSPI选择主时钟为时钟源
    112. #endif
    113.     HSCLKDIV = 0;                           //HSPWM/HSSPI时钟源不分频
    114.    
    115.     HSPWMA_CFG = 0x03;                      //使能PWMA相关寄存器异步访问功能
    116.    
    117.     PWMA_PS = 0x00;                         //PWMA_CC1/CC1N高速PWM输出到CC1/CC1N口
    118.                                             //注意:PWMA_PS属于I/O控制寄存器,不能使用异步方式进行读写
    119.     //通过异步方式设置PWMA的相关寄存器
    120.     WritePWMA((char)&PWMA_CCER1, 0x00);
    121.     WritePWMA((char)&PWMA_CCMR1, 0x00);     //CC1为输出模式
    122.     WritePWMA((char)&PWMA_CCMR1, 0x60);     //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
    123.     WritePWMA((char)&PWMA_CCER1, 0x05);     //使能CC1/CC1N上的输出功能
    124.     WritePWMA((char)&PWMA_ENO, 0x03);       //使能PWM信号输出到端口P1.0/P1.1
    125.     WritePWMA((char)&PWMA_BKR, 0x80);       //使能主输出
    126.     WritePWMA((char)&PWMA_CCR1H, 0);        //设置PWM占空比为50个PWM时钟
    127.     WritePWMA((char)&PWMA_CCR1L, 50);
    128.     WritePWMA((char)&PWMA_ARRH, 0);         //设置输出PWM的周期为100个PWM时钟
    129.     WritePWMA((char)&PWMA_ARRL, 99);
    130.     WritePWMA((char)&PWMA_DTR, 10);         //设置互补对称输出PWM的死区
    131.     WritePWMA((char)&PWMA_CR1, 0x01);       //开始PWM计数
    132. //  P2 = ReadPWMA((char)&PWMA_ARRH);        //异步方式读取寄存器
    133. //  P0 = ReadPWMA((char)&PWMA_ARRL);
    134.     while (1);
    135. }
    复制代码



    PWM使用HPLL时钟(输出高速PWM)-CPU@60M ICACHE.zip

    21 KB, 下载次数: 25

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9351

    回帖

    1万

    积分

    管理员

    积分
    13882
    发表于 2023-6-14 16:56:33 | 显示全部楼层
    HPLL的输入频率确实比我们原始定的规格【6~12M】的范围要宽,【2~16M】都可以
    HPLL输出频率超过700M/2,也就是PWM输入时钟超过350M,测试4个样品均输出正常
    HPLL输出频率超过800M/2,也就是PWM输入时钟超过400M,测试4个样品,两个样品PWM无输出

    500MHz/2 后占空比是50% 的250MHz PWM时钟
    ==搞音频PWM发声,这个250MHz 的PWM时钟源因该很舒服了
    16位PWM 当16位用,当10位用,当8位用,当2~16位用


    16位PWM当8位用的PWM最高频率



    16位PWM当10位用的PWM最高频率


    16位PWM当16位用的PWM最高频率



    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    0

    主题

    9

    回帖

    58

    积分

    注册会员

    积分
    58
    发表于 2023-6-15 06:41:04 | 显示全部楼层
    模拟DAC精度如何呢

    点评

    PWM模拟DAC的实际效果,取决于你实际测量他的ADC电路, 用这个ADC来检测反馈控制,高了就调低,低了就调高 !!! 信号发生器演示视频,STC32G12K128实验箱,老梁示波器 - STC 实验箱/核心功能实验板,原理图,MCU  详情 回复 发表于 2023-6-15 06:59
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9351

    回帖

    1万

    积分

    管理员

    积分
    13882
    发表于 2023-6-15 06:59:21 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    4

    主题

    85

    回帖

    652

    积分

    高级会员

    积分
    652
    发表于 2023-6-16 07:24:55 | 显示全部楼层
    asxddz 发表于 2023-6-15 06:41
    模拟DAC精度如何呢

    PWM DAC's are very precise, because they are timing-determined.
    Their drawback is the PWM needs to be filtered to give a varying analog value.
    One trade off possible is to use two PWM pins and two resistors for faster updates.
    Example if you use two 6 bit PWM and 10k and 640K resistors, you can output 4096 steps (12 bits) with faster PWM of SysCLK/64, which is more easily filtered externally.
    The numbers given above of 250MHz and 307.5MHz PWM clocks, would give 3.90625MHz and 4.8046875MHz PWMs, for 2 x 6 bit, which can be easily filtered to give about 100kHz+ DAC performance.
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9351

    回帖

    1万

    积分

    管理员

    积分
    13882
    发表于 2023-6-19 14:03:16 | 显示全部楼层
    STC32F12K54-56MHz-LQFP48,  7500片已到,全球发售,【免费+包邮】 送 !

    另有 3万片途中,确保 全国大学生电子设计竞赛全部大学生智能车竞赛



    HPLL的输入频率确实比我们原始定的规格【6~12M】的范围要宽,【2~16M】都可以

    HPLL输出频率超过700M/2,也就是PWM输入时钟超过350M,测试4个样品均输出正常
    HPLL输出频率超过800M/2,也就是PWM输入时钟超过400M,测试4个样品,两个样品PWM无输出

    500MHz/2 后占空比是50% 的250MHz PWM时钟
    ==搞音频PWM发声,这个250MHz 的PWM时钟源因该很舒服了
    16位PWM 当16位用,当10位用,当8位用,当2~16位用
    16位PWM当8位用的PWM最高频率



    16位PWM当10位用的PWM最高频率


    16位PWM当16位用的PWM最高频率




    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    13 小时前
  • 签到天数: 154 天

    [LV.7]常住居民III

    13

    主题

    280

    回帖

    3302

    积分

    论坛元老

    积分
    3302
    发表于 2023-6-20 15:41:09 | 显示全部楼层
    购买的追风剑到货,发现引脚没有标注,使用起来找引脚就得半天。

    追风剑

    追风剑
    众辕汽修,专业汽车维修
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    13 小时前
  • 签到天数: 143 天

    [LV.7]常住居民III

    17

    主题

    530

    回帖

    1253

    积分

    金牌会员

    积分
    1253
    发表于 2023-6-21 08:42:32 | 显示全部楼层
    STC32F12K54-56MHz-LQFP48,  8000片已到,【免费+包邮送】,是真的吗?
    不会还是只针对全国大赛才供货吧?看来我们公司产品上面也该采用这款芯片了!
    我目前尚在使用STC32G12K128——TSSOP-20的在开发中》。。。

    点评

    有官方淘宝旗舰店零售的  发表于 2023-6-22 02:09
    批量生产先用 STC32G12K128, STC32G8K64  详情 回复 发表于 2023-6-21 14:54
    不停地学习
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-9 21:51 , Processed in 0.077543 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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