数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 2351|回复: 4

[C51] 哪位有玩过STC8的高速高级PWM的,请教一下|已解决

[复制链接]
发表于 2024-2-6 08:32:32 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
本帖最后由 lmn2005 于 2024-2-6 15:29 编辑

近日玩手推车STC8的高速高级PWM,明明是按照他们的范例改的,只是添加了分频和中断,还是调不通。

问题已经在他们论坛在发帖求助,也许是因为那里的工程师太忙,或者他们对于代码贴不太喜欢,所以他们只是回复了范例。
代码如下,有玩过的坛友,请赐教,谢谢!



  1. //芯片用STC8H2K17U,外部晶振为24MHz

  2. sfr PLLCR = 0xdc;
  3. //测试工作频率为24MHz
  4. #include "stc8h.h"
  5. #include "intrins.h"
  6. typedef unsigned char u8;
  7. #define       FOSC                           24000000UL
  8. #define       HSCK_MCLK             0
  9. #define       HSCK_PLL                 1
  10. #define       HSCK_SEL                 HSCK_PLL
  11. #define       PLL_96M                     0
  12. #define       PLL_144M                  1
  13. #define       PLL_SEL                     PLL_96M
  14. #define       CKMS                          0x80
  15. #define       HSIOCK                      0x40
  16. #define       MCK2SEL_MSK        0x0c
  17. #define       MCK2SEL_SEL1        0x00
  18. #define       MCK2SEL_PLLD2     0x04
  19. #define       MCK2SEL_PLLD4     0x08
  20. #define       MCKSEL_MSK          0x03
  21. #define       MCKSEL_HIRC         0x00
  22. #define       MCKSEL_XOSC        0x01
  23. #define       MCKSEL_X32K          0x02
  24. #define       MCKSEL_IRC32K     0x03
  25. #define       ENCKM                      0x80
  26. #define       PCKI_MSK                 0x60
  27. #define       PCKI_D1                     0x00
  28. #define       PCKI_D2                     0x20
  29. #define       PCKI_D3                     0x40
  30. #define       PCKI_D4                     0x60

  31. void delay()
  32. {
  33.          int     i;
  34.          
  35.          for    (i=0; i<100; i++);
  36. }
  37. char ReadPWMA(char addr)
  38. {
  39.          char dat;
  40.          
  41.          while(HSPWMA_ADR & 0x80);                                                //等待前一个异步读写完成
  42.          HSPWMA_ADR= addr | 0x80;                                                   //设置间接访问地址,只需要设置原XFR地址的低7位
  43.                                                                                                                 //HSPWMA_ADR寄存器的最高位写1,表示读数据
  44.          while(HSPWMA_ADR & 0x80);                                                //等待当前异步读取完成
  45.          dat    = HSPWMA_DAT;                                                              //读取异步数据
  46.          
  47.          return dat;
  48. }
  49. void WritePWMA(char addr, char dat)
  50. {
  51.          while(HSPWMA_ADR & 0x80);                                                //等待前一个异步读写完成
  52.          HSPWMA_DAT= dat;                                                                 //准备需要写入的数据
  53.          HSPWMA_ADR= addr & 0x7f;                                                 //设置间接访问地址,只需要设置原XFR地址的低7位
  54.                                                                                                                 //HSPWMA_ADR寄存器的最高位写0,表示写数据
  55. }
  56. void main()
  57. {
  58.          P_SW2|= 0x80;                                                                            //使能访问XFR
  59.          XOSCCR = 0xc0; // 启动外部晶振
  60.         while (!(XOSCCR & 1));                   // 等待时钟稳定               
  61.         CLKDIV = 0x00; // 时钟不分频
  62.         CKSEL = 0x01;  // 选择外部晶振
  63.         
  64.          //选择PLL输出时钟
  65. #if     (PLL_SEL == PLL_96M)
  66.          CLKSEL&= ~CKMS;                                                                  //选择PLL的96M作为PLL的输出时钟
  67. #elif (PLL_SEL == PLL_144M)
  68.          CLKSEL|= CKMS;                                                                      //选择PLL的144M作为PLL的输出时钟
  69. #else
  70.          CLKSEL&= ~CKMS;                                                                  //默认选择PLL的96M作为PLL的输出时钟
  71. #endif
  72.          
  73.          //选择PLL输入时钟分频,保证输入时钟为12M
  74.          PLLCR&= ~PCKI_MSK;
  75. #if     (FOSC == 12000000UL)
  76.          PLLCR|= PCKI_D1;                                                                   //PLL输入时钟1分频
  77. #elif (FOSC == 24000000UL)
  78.          PLLCR|= PCKI_D2;                                                                   //PLL输入时钟2分频
  79. #elif (FOSC == 36000000UL)
  80.          PLLCR|= PCKI_D3;                                                                   //PLL输入时钟3分频
  81. #elif (FOSC == 48000000UL)
  82.          PLLCR|= PCKI_D4;                                                                   //PLL输入时钟4分频
  83. #else
  84.          PLLCR|= PCKI_D1;                                                                   //默认PLL输入时钟1分频
  85. #endif
  86.          //启动PLL
  87.          PLLCR|= ENCKM;                                                                    //使能PLL倍频
  88.          
  89.          delay();                                                                                          //等待PLL锁频
  90.          //选择HSPWM/HSSPI时钟
  91. #if     (HSCK_SEL == HSCK_MCLK)
  92.          CLKSEL&= ~HSIOCK;                                                             //HSPWM/HSSPI选择主时钟为时钟源
  93. #elif (HSCK_SEL == HSCK_PLL)
  94.          CLKSEL|= HSIOCK;                                                                  //HSPWM/HSSPI选择PLL输出时钟为时钟源
  95. #else
  96.          CLKSEL&= ~HSIOCK;                                                             //默认HSPWM/HSSPI选择主时钟为时钟源
  97. #endif
  98.          HSCLKDIV= 0;                                                                            //HSPWM/HSSPI时钟源不分频
  99.          
  100.          HSPWMA_CFG= 0x03;                                                             //使能PWMA相关寄存器异步访问功能
  101.          
  102.          //通过异步方式设置PWMA的相关寄存器
  103.          WritePWMA((char)&PWMA_PSCR,48000 - 1);                  //分频(注:自己加的)
  104.          WritePWMA((char)&PWMA_CCER1,0x00);
  105.          WritePWMA((char)&PWMA_CCMR1,0x00);                           //CC1为输出模式
  106.          WritePWMA((char)&PWMA_CCMR1,0x60);                           //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
  107.          WritePWMA((char)&PWMA_CCER1,0x05);                           //使能CC1/CC1N上的输出功能
  108.          WritePWMA((char)&PWMA_ENO,0x03);                                //使能PWM信号输出到端口
  109.          WritePWMA((char)&PWMA_BKR,0x80);                                //使能主输出
  110.          WritePWMA((char)&PWMA_CCR1H,200 >> 8);                    //设置输出PWM的占空比
  111.          WritePWMA((char)&PWMA_CCR1L,200);
  112.          WritePWMA((char)&PWMA_ARRH,2000 >> 8);                    //设置输出PWM的周期(注:原来1000,现改为2000)
  113.          WritePWMA((char)&PWMA_ARRL,2000);
  114.          WritePWMA((char)&PWMA_DTR,10);                                    //设置互补对称输出PWM的死区
  115.          WritePWMA((char)&PWMA_CR1,0x01);                                 //开始PWM计数
  116.          WritePWMA((char)&PWMA_IER,0x01);             // 使能PWMA中断
  117.           EA=1;                       
  118.                                  
  119.          P2M0= 0;
  120.          P2M1= 0;
  121.          P3M0= 0;
  122.          P3M1= 0;
  123.          
  124. //         P2= ReadPWMA((char)&PWMA_ARRH);                               //异步方式读取寄存器
  125. //         P3= ReadPWMA((char)&PWMA_ARRL);
  126.          
  127.          while(1);


  128. }

  129. void PWMA_Isr() interrupt 26 // PWMA中断处理程序,1秒中断(注:自己加的)
  130. {
  131.         
  132.     u8 i=ReadPWMA((char)&PWMA_SR1);   
  133.     if (i & 0x01))  
  134.     {
  135.         WritePWMA((char)&PWMA_SR1,i&~0x01);         // 清除PWM中断
  136.         P37=!P37;
  137.     }
  138. }
复制代码


发表于 2024-2-6 08:54:26 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 1 反对 0

使用道具 举报

发表于 2024-2-6 09:22:49 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-2-6 09:35:31 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2024-2-7 08:19:17 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-4-1 17:43 , Processed in 0.265200 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

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