找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8519|回复: 25
收起左侧

STC8H系列单片机PWM如何学习?看文档摸不到方向

  [复制链接]
ID:734017 发表于 2021-8-14 10:28 | 显示全部楼层 |阅读模式
STC 16 位高级PWM定时器,支持正交编码器
文档看得我都有点乱,摸不到方向。 导出页面自 C915673_STC8H1K08-36I-TSSOP20_2020-11-05.pdf (1.21 MB, 下载次数: 129)
回复

使用道具 举报

ID:401564 发表于 2021-8-14 18:46 | 显示全部楼层
STC的PWM的数据手册着实让人头痛,洋洋洒洒写一大堆,看半天都不知道它在说什么,好几次看了一半,心想着算了,还是去用定时器去吧
后来定时器没空,用不了,只能用PWM了
你就对着给出的例程,把里头相关的说明全部抄一遍,再加上自己的理解,其实也就明白一半了
再抄第二次就基本会用了
没什么捷径,不断的烧录验证就可以了,如果有示波器就用示波器看波形,没有就串联一个电阻加上一个LED看亮度,尝试调节一下
整个过程也就一两个小时就差不多了.没什么难的
回复

使用道具 举报

ID:57657 发表于 2021-8-14 19:28 | 显示全部楼层
配置硬件PWM寄存器打开后,然后用示波器或逻辑分析仪测量IO口输出即可。
回复

使用道具 举报

ID:155507 发表于 2021-8-14 21:03 | 显示全部楼层
我给你来个程序试试

高级PWM1-PWM2-PWM3-PWM4驱动P6口呼吸灯实验程序-STC8H
  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序            */
  5. /*---------------------------------------------------------------------*/
  6. //11-高级PWM1-PWM2-PWM3-PWM4驱动P6口呼吸灯实验程序-STC8H
  7. /*********************************************************/

  8. //#define MAIN_Fosc                22118400L        //定义主时钟
  9. //#define MAIN_Fosc                12000000L        //定义主时钟
  10. //#define MAIN_Fosc                11059200L        //定义主时钟
  11. //#define MAIN_Fosc                 5529600L        //定义主时钟
  12. #define MAIN_Fosc                24000000L        //定义主时钟


  13. /*********************************************************/

  14. #include        "STC8xxxx.H"
  15. #define        GPIO_PullUp                0        //上拉准双向口
  16. #define        GPIO_HighZ                1        //浮空输入
  17. #define        GPIO_OUT_OD                2        //开漏输出
  18. #define        GPIO_OUT_PP                3        //推挽输出

  19. #define        GPIO_Pin_0                0x01        //IO引脚 Px.0
  20. #define        GPIO_Pin_1                0x02        //IO引脚 Px.1
  21. #define        GPIO_Pin_2                0x04        //IO引脚 Px.2
  22. #define        GPIO_Pin_3                0x08        //IO引脚 Px.3
  23. #define        GPIO_Pin_4                0x10        //IO引脚 Px.4
  24. #define        GPIO_Pin_5                0x20        //IO引脚 Px.5
  25. #define        GPIO_Pin_6                0x40        //IO引脚 Px.6
  26. #define        GPIO_Pin_7                0x80        //IO引脚 Px.7
  27. #define        GPIO_Pin_All        0xFF        //IO所有引脚
  28.         
  29. #define        GPIO_P0                        0                //
  30. #define        GPIO_P1                        1
  31. #define        GPIO_P2                        2
  32. #define        GPIO_P3                        3
  33. #define        GPIO_P4                        4
  34. #define        GPIO_P5                        5
  35. #define        GPIO_P6                        6
  36. #define        GPIO_P7                        7


  37. typedef struct
  38. {
  39.         u8        Mode;                //IO模式,                  GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  40.         u8        Pin;                //要设置的端口        
  41. } GPIO_InitTypeDef;

  42. u8        GPIO_Inilize(u8 GPIO, GPIO_InitTypeDef *GPIOx);
  43. #define        Timer0                                                0
  44. #define        Timer1                                                1
  45. #define        Timer2                                                2
  46. #define        Timer3                                                3
  47. #define        Timer4                                                4

  48. #define        TIM_16BitAutoReload                        0
  49. #define        TIM_16Bit                                        1
  50. #define        TIM_8BitAutoReload                        2
  51. #define        TIM_16BitAutoReloadNoMask        3

  52. #define        TIM_CLOCK_1T                                0
  53. #define        TIM_CLOCK_12T                                1
  54. #define        TIM_CLOCK_Ext                                2

  55. typedef struct
  56. {
  57.         u8        TIM_Mode;                //工作模式,          TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
  58.         u8        TIM_Priority;                //优先级设置        Priority_0,Priority_1,Priority_2,Priority_3
  59.         u8        TIM_Interrupt;        //中断允许                ENABLE,DISABLE
  60.         u8        TIM_ClkSource;        //时钟源                TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
  61.         u8        TIM_ClkOut;                //可编程时钟输出,        ENABLE,DISABLE
  62.         u16        TIM_Value;                //装载初值
  63.         u8        TIM_Run;                //是否运行                ENABLE,DISABLE
  64. } TIM_InitTypeDef;

  65. u8        Timer_Inilize(u8 TIM, TIM_InitTypeDef *TIMx);
  66. #define ENO1P       0x01
  67. #define ENO1N       0x02
  68. #define ENO2P       0x04
  69. #define ENO2N       0x08
  70. #define ENO3P       0x10
  71. #define ENO3N       0x20
  72. #define ENO4P       0x40
  73. #define ENO4N       0x80

  74. #define ENO5P       0x01
  75. #define ENO6P       0x04
  76. #define ENO7P       0x10
  77. #define ENO8P       0x40

  78. #define        PWMA        1
  79. #define        PWMB        2

  80. #define        PWM1_SW_P10_P11                0
  81. #define        PWM1_SW_P20_P21                1
  82. #define        PWM1_SW_P60_P61                2

  83. #define        PWM2_SW_P12_P13                0
  84. #define        PWM2_SW_P22_P23                (1<<2)
  85. #define        PWM2_SW_P62_P63                (2<<2)

  86. #define        PWM3_SW_P14_P15                0
  87. #define        PWM3_SW_P24_P25                (1<<4)
  88. #define        PWM3_SW_P64_P65                (2<<4)

  89. #define        PWM4_SW_P16_P17                0
  90. #define        PWM4_SW_P26_P27                (1<<6)
  91. #define        PWM4_SW_P66_P67                (2<<6)
  92. #define        PWM4_SW_P34_P33                (3<<6)

  93. #define        PWM5_SW_P20                                0
  94. #define        PWM5_SW_P17                                1
  95. #define        PWM5_SW_P00                                2
  96. #define        PWM5_SW_P74                                3

  97. #define        PWM6_SW_P21                                0
  98. #define        PWM6_SW_P54                                (1<<2)
  99. #define        PWM6_SW_P01                                (2<<2)
  100. #define        PWM6_SW_P75                                (3<<2)

  101. #define        PWM7_SW_P22                                0
  102. #define        PWM7_SW_P33                                (1<<4)
  103. #define        PWM7_SW_P02                                (2<<4)
  104. #define        PWM7_SW_P76                                (3<<4)

  105. #define        PWM8_SW_P23                                0
  106. #define        PWM8_SW_P34                                (1<<6)
  107. #define        PWM8_SW_P03                                (2<<6)
  108. #define        PWM8_SW_P77                                (3<<6)

  109. typedef struct
  110. {
  111.         u8        PWM1_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  112.         u8        PWM2_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  113.         u8        PWM3_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  114.         u8        PWM4_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  115.         u8        PWM5_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  116.         u8        PWM6_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  117.         u8        PWM7_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  118.         u8        PWM8_Mode;                        //模式,   CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2

  119.         u16        PWM_Period;                        //周期时间,   0~65535
  120.         u16        PWM1_Duty;                        //PWM1占空比时间, 0~Period
  121.         u16        PWM2_Duty;                        //PWM2占空比时间, 0~Period
  122.         u16        PWM3_Duty;                        //PWM3占空比时间, 0~Period
  123.         u16        PWM4_Duty;                        //PWM4占空比时间, 0~Period
  124.         u16        PWM5_Duty;                        //PWM5占空比时间, 0~Period
  125.         u16        PWM6_Duty;                        //PWM6占空比时间, 0~Period
  126.         u16        PWM7_Duty;                        //PWM7占空比时间, 0~Period
  127.         u16        PWM8_Duty;                        //PWM8占空比时间, 0~Period
  128.         u8        PWM_DeadTime;                //死区发生器设置, 0~255

  129.         u8        PWM_CC1Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  130.         u8        PWM_CC1NEnable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  131.         u8        PWM_CC2Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  132.         u8        PWM_CC2NEnable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  133.         u8        PWM_CC3Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  134.         u8        PWM_CC3NEnable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  135.         u8        PWM_CC4Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  136.         u8        PWM_CC4NEnable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  137.         u8        PWM_CC5Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  138.         u8        PWM_CC6Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  139.         u8        PWM_CC7Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE
  140.         u8        PWM_CC8Enable;        //开启输入捕获/比较输出,  ENABLE,DISABLE

  141.         u8        PWM_Reload;                        //输出比较的预装载使能,   ENABLE,DISABLE
  142.         u8        PWM_Fast;                                //输出比较快速功能使能,   ENABLE,DISABLE

  143.         u8        PWM1_SetPriority;        //设置PWM1优先级,   Priority_0,Priority_1,Priority_2,Priority_3
  144.         u8        PWM2_SetPriority;        //设置PWM2优先级,   Priority_0,Priority_1,Priority_2,Priority_3
  145.         u8        PWM3_SetPriority;        //设置PWM3优先级,   Priority_0,Priority_1,Priority_2,Priority_3
  146.         u8        PWM4_SetPriority;        //设置PWM4优先级,   Priority_0,Priority_1,Priority_2,Priority_3
  147.         u8        PWM5_SetPriority;        //设置PWM4优先级,   Priority_0,Priority_1,Priority_2,Priority_3

  148.         u8        PWM_EnoSelect;        //输出通道选择,        ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
  149.         u8        PWM_PreLoad;                //预装载,     ENABLE,DISABLE
  150.         u8        PWM_PS_SW;                        //切换端口,   PWM1_SW_P10_P11,PWM1_SW_P20_P21,PWM1_SW_P60_P61
  151.         u8        PWM_CEN_Enable;        //使能计数器, ENABLE,DISABLE

  152.         u8        PWM_BrakeEnable;        //刹车输入使能,  ENABLE,DISABLE
  153.         u8        PWM_MainOutEnable;//主输出使能,  ENABLE,DISABLE
  154. } PWMx_InitDefine;

  155. typedef struct
  156. {
  157.         u16        PWM1_Duty;                        //PWM1占空比时间, 0~Period
  158.         u16        PWM2_Duty;                        //PWM2占空比时间, 0~Period
  159.         u16        PWM3_Duty;                        //PWM3占空比时间, 0~Period
  160.         u16        PWM4_Duty;                        //PWM4占空比时间, 0~Period
  161.         u16        PWM5_Duty;                        //PWM5占空比时间, 0~Period
  162.         u16        PWM6_Duty;                        //PWM6占空比时间, 0~Period
  163.         u16        PWM7_Duty;                        //PWM7占空比时间, 0~Period
  164.         u16        PWM8_Duty;                        //PWM8占空比时间, 0~Period
  165. } PWMx_Duty;

  166. u8        PWM_Configuration(u8 PWM, PWMx_InitDefine *PWMx);
  167. void UpdatePwm(u8 PWM, PWMx_Duty *PWMx);


  168. /***************        功能说明        ****************

  169. 本文件为STC8系列的端口初始化程序,用户几乎可以不修改这个程序.

  170. ******************************************/

  171. //========================================================================
  172. // 函数: u8        GPIO_Inilize(u8 GPIO, GPIO_InitTypeDef *GPIOx)
  173. // 描述: 初始化IO口.
  174. // 参数: GPIOx: 结构参数,请参考timer.h里的定义.
  175. // 返回: 成功返回0, 空操作返回1,错误返回2.
  176. // 版本: V1.0, 2012-10-22
  177. //========================================================================
  178. u8        GPIO_Inilize(u8 GPIO, GPIO_InitTypeDef *GPIOx)
  179. {
  180.         if(GPIO > GPIO_P7)                                return 1;        //空操作
  181.         if(GPIOx->Mode > GPIO_OUT_PP)        return 2;        //错误
  182.         if(GPIO == GPIO_P0)
  183.         {
  184.                 if(GPIOx->Mode == GPIO_PullUp)                P0M1 &= ~GPIOx->Pin,        P0M0 &= ~GPIOx->Pin;         //上拉准双向口
  185.                 if(GPIOx->Mode == GPIO_HighZ)                P0M1 |=  GPIOx->Pin,        P0M0 &= ~GPIOx->Pin;         //浮空输入
  186.                 if(GPIOx->Mode == GPIO_OUT_OD)                P0M1 |=  GPIOx->Pin,        P0M0 |=  GPIOx->Pin;         //开漏输出
  187.                 if(GPIOx->Mode == GPIO_OUT_PP)                P0M1 &= ~GPIOx->Pin,        P0M0 |=  GPIOx->Pin;         //推挽输出
  188.         }
  189.         if(GPIO == GPIO_P1)
  190.         {
  191.                 if(GPIOx->Mode == GPIO_PullUp)                P1M1 &= ~GPIOx->Pin,        P1M0 &= ~GPIOx->Pin;         //上拉准双向口
  192.                 if(GPIOx->Mode == GPIO_HighZ)                P1M1 |=  GPIOx->Pin,        P1M0 &= ~GPIOx->Pin;         //浮空输入
  193.                 if(GPIOx->Mode == GPIO_OUT_OD)                P1M1 |=  GPIOx->Pin,        P1M0 |=  GPIOx->Pin;         //开漏输出
  194.                 if(GPIOx->Mode == GPIO_OUT_PP)                P1M1 &= ~GPIOx->Pin,        P1M0 |=  GPIOx->Pin;         //推挽输出
  195.         }
  196.         if(GPIO == GPIO_P2)
  197.         {
  198.                 if(GPIOx->Mode == GPIO_PullUp)                P2M1 &= ~GPIOx->Pin,        P2M0 &= ~GPIOx->Pin;         //上拉准双向口
  199.                 if(GPIOx->Mode == GPIO_HighZ)                P2M1 |=  GPIOx->Pin,        P2M0 &= ~GPIOx->Pin;         //浮空输入
  200.                 if(GPIOx->Mode == GPIO_OUT_OD)                P2M1 |=  GPIOx->Pin,        P2M0 |=  GPIOx->Pin;         //开漏输出
  201.                 if(GPIOx->Mode == GPIO_OUT_PP)                P2M1 &= ~GPIOx->Pin,        P2M0 |=  GPIOx->Pin;         //推挽输出
  202.         }
  203.         if(GPIO == GPIO_P3)
  204.         {
  205.                 if(GPIOx->Mode == GPIO_PullUp)                P3M1 &= ~GPIOx->Pin,        P3M0 &= ~GPIOx->Pin;         //上拉准双向口
  206.                 if(GPIOx->Mode == GPIO_HighZ)                P3M1 |=  GPIOx->Pin,        P3M0 &= ~GPIOx->Pin;         //浮空输入
  207.                 if(GPIOx->Mode == GPIO_OUT_OD)                P3M1 |=  GPIOx->Pin,        P3M0 |=  GPIOx->Pin;         //开漏输出
  208.                 if(GPIOx->Mode == GPIO_OUT_PP)                P3M1 &= ~GPIOx->Pin,        P3M0 |=  GPIOx->Pin;         //推挽输出
  209.         }
  210.         if(GPIO == GPIO_P4)
  211.         {
  212.                 if(GPIOx->Mode == GPIO_PullUp)                P4M1 &= ~GPIOx->Pin,        P4M0 &= ~GPIOx->Pin;         //上拉准双向口
  213.                 if(GPIOx->Mode == GPIO_HighZ)                P4M1 |=  GPIOx->Pin,        P4M0 &= ~GPIOx->Pin;         //浮空输入
  214.                 if(GPIOx->Mode == GPIO_OUT_OD)                P4M1 |=  GPIOx->Pin,        P4M0 |=  GPIOx->Pin;         //开漏输出
  215.                 if(GPIOx->Mode == GPIO_OUT_PP)                P4M1 &= ~GPIOx->Pin,        P4M0 |=  GPIOx->Pin;         //推挽输出
  216.         }
  217.         if(GPIO == GPIO_P5)
  218.         {
  219.                 if(GPIOx->Mode == GPIO_PullUp)                P5M1 &= ~GPIOx->Pin,        P5M0 &= ~GPIOx->Pin;         //上拉准双向口
  220.                 if(GPIOx->Mode == GPIO_HighZ)                P5M1 |=  GPIOx->Pin,        P5M0 &= ~GPIOx->Pin;         //浮空输入
  221.                 if(GPIOx->Mode == GPIO_OUT_OD)                P5M1 |=  GPIOx->Pin,        P5M0 |=  GPIOx->Pin;         //开漏输出
  222.                 if(GPIOx->Mode == GPIO_OUT_PP)                P5M1 &= ~GPIOx->Pin,        P5M0 |=  GPIOx->Pin;         //推挽输出
  223.         }
  224.         if(GPIO == GPIO_P6)
  225.         {
  226.                 if(GPIOx->Mode == GPIO_PullUp)                P6M1 &= ~GPIOx->Pin,        P6M0 &= ~GPIOx->Pin;         //上拉准双向口
  227.                 if(GPIOx->Mode == GPIO_HighZ)                P6M1 |=  GPIOx->Pin,        P6M0 &= ~GPIOx->Pin;         //浮空输入
  228.                 if(GPIOx->Mode == GPIO_OUT_OD)                P6M1 |=  GPIOx->Pin,        P6M0 |=  GPIOx->Pin;         //开漏输出
  229.                 if(GPIOx->Mode == GPIO_OUT_PP)                P6M1 &= ~GPIOx->Pin,        P6M0 |=  GPIOx->Pin;         //推挽输出
  230.         }
  231.         if(GPIO == GPIO_P7)
  232.         {
  233.                 if(GPIOx->Mode == GPIO_PullUp)                P7M1 &= ~GPIOx->Pin,        P7M0 &= ~GPIOx->Pin;         //上拉准双向口
  234.                 if(GPIOx->Mode == GPIO_HighZ)                P7M1 |=  GPIOx->Pin,        P7M0 &= ~GPIOx->Pin;         //浮空输入
  235.                 if(GPIOx->Mode == GPIO_OUT_OD)                P7M1 |=  GPIOx->Pin,        P7M0 |=  GPIOx->Pin;         //开漏输出
  236.                 if(GPIOx->Mode == GPIO_OUT_PP)                P7M1 &= ~GPIOx->Pin,        P7M0 |=  GPIOx->Pin;         //推挽输出
  237.         }
  238.         return 0;        //成功
  239. }

  240. /*************        功能说明        **************

  241. 本文件为STC8系列的定时器初始化和中断程序,用户可以在这个文件中修改自己需要的中断程序.

  242. ******************************************/


  243. /*************        本地变量声明        **************/
  244. bit PWM1_Flag;
  245. bit PWM2_Flag;
  246. bit PWM3_Flag;
  247. bit PWM4_Flag;

  248. /*************  外部函数和变量声明 *****************/
  249. extern PWMx_Duty PWMA_Duty;

  250. /********************* Timer0中断函数************************/
  251. void timer0_int (void) interrupt TIMER0_VECTOR
  252. {
  253.         if(!PWM1_Flag)
  254.         {
  255.                 PWMA_Duty.PWM1_Duty++;
  256.                 if(PWMA_Duty.PWM1_Duty >= 2047) PWM1_Flag = 1;
  257.         }
  258.         else
  259.         {
  260.                 PWMA_Duty.PWM1_Duty--;
  261.                 if(PWMA_Duty.PWM1_Duty <= 0) PWM1_Flag = 0;
  262.         }

  263.         if(!PWM2_Flag)
  264.         {
  265.                 PWMA_Duty.PWM2_Duty++;
  266.                 if(PWMA_Duty.PWM2_Duty >= 2047) PWM2_Flag = 1;
  267.         }
  268.         else
  269.         {
  270.                 PWMA_Duty.PWM2_Duty--;
  271.                 if(PWMA_Duty.PWM2_Duty <= 0) PWM2_Flag = 0;
  272.         }

  273.         if(!PWM3_Flag)
  274.         {
  275.                 PWMA_Duty.PWM3_Duty++;
  276.                 if(PWMA_Duty.PWM3_Duty >= 2047) PWM3_Flag = 1;
  277.         }
  278.         else
  279.         {
  280.                 PWMA_Duty.PWM3_Duty--;
  281.                 if(PWMA_Duty.PWM3_Duty <= 0) PWM3_Flag = 0;
  282.         }

  283.         if(!PWM4_Flag)
  284.         {
  285.                 PWMA_Duty.PWM4_Duty++;
  286.                 if(PWMA_Duty.PWM4_Duty >= 2047) PWM4_Flag = 1;
  287.         }
  288.         else
  289.         {
  290.                 PWMA_Duty.PWM4_Duty--;
  291.                 if(PWMA_Duty.PWM4_Duty <= 0) PWM4_Flag = 0;
  292.         }
  293.         
  294.         UpdatePwm(PWMA, &PWMA_Duty);
  295. }

  296. /********************* Timer1中断函数************************/
  297. void timer1_int (void) interrupt TIMER1_VECTOR
  298. {
  299. //   P66 = ~P66;
  300. }

  301. /********************* Timer2中断函数************************/
  302. void timer2_int (void) interrupt TIMER2_VECTOR
  303. {
  304. //        P65 = ~P65;
  305. }

  306. /********************* Timer3中断函数************************/
  307. void timer3_int (void) interrupt TIMER3_VECTOR
  308. {
  309. //        P64 = ~P64;
  310. }

  311. /********************* Timer4中断函数************************/
  312. void timer4_int (void) interrupt TIMER4_VECTOR
  313. {
  314. //        P63 = ~P63;
  315. }


  316. //========================================================================
  317. // 函数: u8        Timer_Inilize(u8 TIM, TIM_InitTypeDef *TIMx)
  318. // 描述: 定时器初始化程序.
  319. // 参数: TIMx: 结构参数,请参考timer.h里的定义.
  320. // 返回: 成功返回0, 空操作返回1,错误返回2.
  321. // 版本: V1.0, 2012-10-22
  322. //========================================================================
  323. u8        Timer_Inilize(u8 TIM, TIM_InitTypeDef *TIMx)
  324. {
  325.         if(TIM > Timer4)        return 1;        //空操作

  326.         if(TIM == Timer0)
  327.         {
  328.                 Timer0_Stop();                //停止计数
  329.                 if(TIMx->TIM_Interrupt == ENABLE)                Timer0_InterruptEnable();        //允许中断
  330.                 else                Timer0_InterruptDisable();        //禁止中断
  331.                 if(TIMx->TIM_Priority > Priority_3)        return 2;        //错误
  332.                 Timer0_Priority(TIMx->TIM_Priority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

  333.                 if(TIMx->TIM_Mode >= TIM_16BitAutoReloadNoMask)        return 2;        //错误
  334.                 TMOD = (TMOD & ~0x30) | TIMx->TIM_Mode;        //工作模式,0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
  335.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_12T)        Timer0_12T();        //12T
  336.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_1T)                Timer0_1T();        //1T
  337.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_Ext)        Timer0_AsCounter();        //对外计数或分频
  338.                 else                Timer0_AsTimer();        //定时
  339.                 if(TIMx->TIM_ClkOut == ENABLE)        Timer0_CLKO_Enable();        //输出时钟
  340.                 else                Timer0_CLKO_Disable();        //不输出时钟
  341.                
  342.                 T0_Load(TIMx->TIM_Value);
  343.                 if(TIMx->TIM_Run == ENABLE)        Timer0_Run();        //开始运行
  344.                 return        0;                //成功
  345.         }

  346.         if(TIM == Timer1)
  347.         {
  348.                 Timer1_Stop();                //停止计数
  349.                 if(TIMx->TIM_Interrupt == ENABLE)                Timer1_InterruptEnable();        //允许中断
  350.                 else                Timer1_InterruptDisable();        //禁止中断
  351.                 if(TIMx->TIM_Priority > Priority_3)        return 2;        //错误
  352.                 Timer1_Priority(TIMx->TIM_Priority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  353.                 if(TIMx->TIM_Mode >= TIM_16BitAutoReloadNoMask)        return 2;        //错误
  354.                 TMOD = (TMOD & ~0x30) | TIMx->TIM_Mode;        //工作模式,0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
  355.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_12T)        Timer1_12T();        //12T
  356.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_1T)                Timer1_1T();        //1T
  357.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_Ext)        Timer1_AsCounter();        //对外计数或分频
  358.                 else                Timer1_AsTimer();        //定时
  359.                 if(TIMx->TIM_ClkOut == ENABLE)        Timer1_CLKO_Enable();        //输出时钟
  360.                 else                Timer1_CLKO_Disable();        //不输出时钟
  361.                
  362.                 T1_Load(TIMx->TIM_Value);
  363.                 if(TIMx->TIM_Run == ENABLE)        Timer1_Run();        //开始运行
  364.                 return        0;                //成功
  365.         }

  366.         if(TIM == Timer2)                //Timer2,固定为16位自动重装, 中断无优先级
  367.         {
  368.                 Timer2_Stop();        //停止计数
  369.                 if(TIMx->TIM_Interrupt == ENABLE)                Timer2_InterruptEnable();        //允许中断
  370.                 else                Timer2_InterruptDisable();        //禁止中断
  371.                 if(TIMx->TIM_ClkSource >  TIM_CLOCK_Ext)        return 2;
  372.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_12T)        Timer2_12T();        //12T
  373.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_1T)                Timer2_1T();        //1T
  374.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_Ext)        Timer2_AsCounter();        //对外计数或分频
  375.                 else                Timer2_AsTimer();                //定时
  376.                 if(TIMx->TIM_ClkOut == ENABLE)        Timer2_CLKO_Enable();                //输出时钟
  377.                 else                Timer2_CLKO_Disable();        //不输出时钟

  378.                 T2_Load(TIMx->TIM_Value);
  379.                 if(TIMx->TIM_Run == ENABLE)        Timer2_Run();        //开始运行
  380.                 return        0;                //成功
  381.         }

  382.         if(TIM == Timer3)                //Timer3,固定为16位自动重装, 中断无优先级
  383.         {
  384.                 Timer3_Stop();        //停止计数
  385.                 if(TIMx->TIM_Interrupt == ENABLE)                Timer3_InterruptEnable();        //允许中断
  386.                 else                Timer3_InterruptDisable();        //禁止中断
  387.                 if(TIMx->TIM_ClkSource >  TIM_CLOCK_Ext)        return 2;
  388.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_12T)        Timer3_12T();        //12T
  389.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_1T)                Timer3_1T();        //1T
  390.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_Ext)        Timer3_AsCounter();        //对外计数或分频
  391.                 else                Timer3_AsTimer();                //定时
  392.                 if(TIMx->TIM_ClkOut == ENABLE)        Timer3_CLKO_Enable();                //输出时钟
  393.                 else                Timer3_CLKO_Disable();        //不输出时钟

  394.                 T3_Load(TIMx->TIM_Value);
  395.                 if(TIMx->TIM_Run == ENABLE)        Timer3_Run();        //开始运行
  396.                 return        0;                //成功
  397.         }

  398.         if(TIM == Timer4)                //Timer3,固定为16位自动重装, 中断无优先级
  399.         {
  400.                 Timer4_Stop();        //停止计数
  401.                 if(TIMx->TIM_Interrupt == ENABLE)                Timer4_InterruptEnable();        //允许中断
  402.                 else                Timer4_InterruptDisable();        //禁止中断
  403.                 if(TIMx->TIM_ClkSource >  TIM_CLOCK_Ext)        return 2;
  404.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_12T)        Timer4_12T();        //12T
  405.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_1T)                Timer4_1T();        //1T
  406.                 if(TIMx->TIM_ClkSource == TIM_CLOCK_Ext)        Timer4_AsCounter();        //对外计数或分频
  407.                 else                Timer4_AsTimer();                //定时
  408.                 if(TIMx->TIM_ClkOut == ENABLE)        Timer4_CLKO_Enable();                //输出时钟
  409.                 else                Timer4_CLKO_Disable();        //不输出时钟

  410.                 T4_Load(TIMx->TIM_Value);
  411.                 if(TIMx->TIM_Run == ENABLE)        Timer4_Run();        //开始运行
  412.                 return        0;                //成功
  413.         }
  414.         return 2;        //错误
  415. }

  416. u8 PWM_Configuration(u8 PWM, PWMx_InitDefine *PWMx)
  417. {
  418.         if(PWM == PWMA)
  419.         {
  420.                 EAXSFR();                /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */
  421.                
  422.                 if(PWMx->PWM1_SetPriority <= Priority_3)        PWM1_Priority(PWMx->PWM1_SetPriority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  423.                 if(PWMx->PWM2_SetPriority <= Priority_3)        PWM2_Priority(PWMx->PWM2_SetPriority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  424.                 if(PWMx->PWM3_SetPriority <= Priority_3)        PWM3_Priority(PWMx->PWM3_SetPriority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  425.                 if(PWMx->PWM4_SetPriority <= Priority_3)        PWM4_Priority(PWMx->PWM4_SetPriority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  426.                
  427.                 PWMA_CCER1_Disable();                //关闭所有输入捕获/比较输出
  428.                 PWMA_CCER2_Disable();                //关闭所有输入捕获/比较输出
  429.                 PWMA_OC1ModeSet(PWMx->PWM1_Mode);                //设置输出比较模式
  430.                 PWMA_OC2ModeSet(PWMx->PWM2_Mode);                //设置输出比较模式
  431.                 PWMA_OC3ModeSet(PWMx->PWM3_Mode);                //设置输出比较模式
  432.                 PWMA_OC4ModeSet(PWMx->PWM4_Mode);                //设置输出比较模式
  433.                 if(PWMx->PWM_Reload == ENABLE)        PWMA_OC1_ReloadEnable();        //输出比较的预装载使能
  434.                 else                PWMA_OC1_RelosdDisable();        //禁止输出比较的预装载
  435.                 if(PWMx->PWM_Fast == ENABLE)        PWMA_OC1_FastEnable();                //输出比较快速功能使能
  436.                 else                PWMA_OC1_FastDisable();        //禁止输出比较快速功能
  437.                
  438.                 if(PWMx->PWM_CC1Enable == ENABLE)        PWMA_CC1E_Enable();                        //开启输入捕获/比较输出
  439.                 else                PWMA_CC1E_Disable();        //关闭输入捕获/比较输出
  440.                 if(PWMx->PWM_CC1NEnable == ENABLE)        PWMA_CC1NE_Enable();        //开启输入捕获/比较输出
  441.                 else                PWMA_CC1NE_Disable();        //关闭输入捕获/比较输出
  442.                 if(PWMx->PWM_CC2Enable == ENABLE)        PWMA_CC2E_Enable();                        //开启输入捕获/比较输出
  443.                 else                PWMA_CC2E_Disable();        //关闭输入捕获/比较输出
  444.                 if(PWMx->PWM_CC2NEnable == ENABLE)        PWMA_CC2NE_Enable();        //开启输入捕获/比较输出
  445.                 else                PWMA_CC2NE_Disable();        //关闭输入捕获/比较输出
  446.                 if(PWMx->PWM_CC3Enable == ENABLE)        PWMA_CC3E_Enable();                        //开启输入捕获/比较输出
  447.                 else                PWMA_CC3E_Disable();        //关闭输入捕获/比较输出
  448.                 if(PWMx->PWM_CC3NEnable == ENABLE)        PWMA_CC3NE_Enable();        //开启输入捕获/比较输出
  449.                 else                PWMA_CC3NE_Disable();        //关闭输入捕获/比较输出
  450.                 if(PWMx->PWM_CC4Enable == ENABLE)        PWMA_CC4E_Enable();                        //开启输入捕获/比较输出
  451.                 else                PWMA_CC4E_Disable();        //关闭输入捕获/比较输出
  452.                 if(PWMx->PWM_CC4NEnable == ENABLE)        PWMA_CC4NE_Enable();        //开启输入捕获/比较输出
  453.                 else                PWMA_CC4NE_Disable();        //关闭输入捕获/比较输出
  454.                
  455.                 PWMA_AutoReload(PWMx->PWM_Period);
  456.                 PWMA_Duty1(PWMx->PWM1_Duty);
  457.                 PWMA_Duty2(PWMx->PWM2_Duty);
  458.                 PWMA_Duty3(PWMx->PWM3_Duty);
  459.                 PWMA_Duty4(PWMx->PWM4_Duty);
  460.                
  461.                 PWMA_CCPCAPreloaded(PWMx->PWM_PreLoad);        //捕获/比较预装载控制位(该位只对具有互补输出的通道起作用)
  462.                 PWMA_PS = PWMx->PWM_PS_SW;                        //切换IO
  463.                 PWMA_ENO = PWMx->PWM_EnoSelect;        //输出通道选择
  464.                 PWMA_DeadTime(PWMx->PWM_DeadTime);        //死区发生器设置
  465.                
  466.                 if(PWMx->PWM_BrakeEnable == ENABLE)        PWMA_BrakeEnable();        //开启刹车输入
  467.                 else                PWMA_BrakeDisable();                //禁止刹车输入
  468.                 if(PWMx->PWM_MainOutEnable == ENABLE)        PWMA_BrakeOutputEnable();        //主输出使能
  469.                 else                PWMA_BrakeOutputDisable();                //主输出禁止
  470.                 if(PWMx->PWM_CEN_Enable == ENABLE)        PWMA_CEN_Enable();        //使能计数器
  471.                 else                PWMA_CEN_Disable();                //禁止计数器
  472.                
  473.                 EAXRAM();                /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展RAM(XRAM) */
  474.                 return        0;
  475.         }

  476.         if(PWM == PWMB)
  477.         {
  478.                 EAXSFR();                /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */
  479.                
  480.                 if(PWMx->PWM5_SetPriority <= Priority_3)        PWM5_Priority(PWMx->PWM5_SetPriority);        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  481.                
  482.                 PWMB_CCER1_Disable();                //关闭所有输入捕获/比较输出
  483.                 PWMB_CCER2_Disable();                //关闭所有输入捕获/比较输出
  484.                 PWMB_OC5ModeSet(PWMx->PWM5_Mode);                //设置输出比较模式
  485.                 PWMB_OC6ModeSet(PWMx->PWM6_Mode);                //设置输出比较模式
  486.                 PWMB_OC7ModeSet(PWMx->PWM7_Mode);                //设置输出比较模式
  487.                 PWMB_OC8ModeSet(PWMx->PWM8_Mode);                //设置输出比较模式
  488.                 if(PWMx->PWM_Reload == ENABLE)        PWMB_OC5_ReloadEnable();        //输出比较的预装载使能
  489.                 else                PWMB_OC5_RelosdDisable();        //禁止输出比较的预装载
  490.                 if(PWMx->PWM_Fast == ENABLE)        PWMB_OC5_FastEnable();                //输出比较快速功能使能
  491.                 else                PWMB_OC5_FastDisable();        //禁止输出比较快速功能
  492.                
  493.                 if(PWMx->PWM_CC5Enable == ENABLE)        PWMB_CC5E_Enable();                        //开启输入捕获/比较输出
  494.                 else                PWMB_CC5E_Disable();        //关闭输入捕获/比较输出
  495.                 if(PWMx->PWM_CC6Enable == ENABLE)        PWMB_CC6E_Enable();                        //开启输入捕获/比较输出
  496.                 else                PWMB_CC6E_Disable();        //关闭输入捕获/比较输出
  497.                 if(PWMx->PWM_CC7Enable == ENABLE)        PWMB_CC7E_Enable();                        //开启输入捕获/比较输出
  498.                 else                PWMB_CC7E_Disable();        //关闭输入捕获/比较输出
  499.                 if(PWMx->PWM_CC8Enable == ENABLE)        PWMB_CC8E_Enable();                        //开启输入捕获/比较输出
  500.                 else                PWMB_CC8E_Disable();        //关闭输入捕获/比较输出
  501.                
  502.                 PWMB_AutoReload(PWMx->PWM_Period);
  503.                 PWMB_Duty5(PWMx->PWM5_Duty);
  504.                 PWMB_Duty6(PWMx->PWM6_Duty);
  505.                 PWMB_Duty7(PWMx->PWM7_Duty);
  506.                 PWMB_Duty8(PWMx->PWM8_Duty);
  507.                
  508.                 PWMB_CCPCBPreloaded(PWMx->PWM_PreLoad);        //捕获/比较预装载控制位(该位只对具有互补输出的通道起作用)
  509.                 PWMB_PS = PWMx->PWM_PS_SW;                        //切换IO
  510.                 PWMB_ENO = PWMx->PWM_EnoSelect;        //输出通道选择
  511.                 PWMB_DeadTime(PWMx->PWM_DeadTime);        //死区发生器设置
  512.                
  513.                 if(PWMx->PWM_BrakeEnable == ENABLE)        PWMB_BrakeEnable();        //开启刹车输入
  514.                 else                PWMB_BrakeDisable();                //禁止刹车输入
  515.                 if(PWMx->PWM_MainOutEnable == ENABLE)        PWMB_BrakeOutputEnable();        //主输出使能
  516.                 else                PWMB_BrakeOutputDisable();                //主输出禁止
  517.                 if(PWMx->PWM_CEN_Enable == ENABLE)        PWMB_CEN_Enable();        //使能计数器
  518.                 else                PWMB_CEN_Disable();                //禁止计数器
  519.                
  520.                 EAXRAM();                /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展RAM(XRAM) */
  521.                 return        0;
  522.         }

  523.         return        2;        //错误
  524. }

  525. /*********************************************************/


  526. /*************        功能说明        **************

  527. 本例程基于STC8H8K64U为主控芯片的实验箱8进行编写测试,STC8H系列芯片可通用参考.

  528. 高级PWM定时器 PWM1P/PWM1N,PWM2P/PWM2N,PWM3P/PWM3N,PWM4P/PWM4N 每个通道都可独立实现PWM输出,或者两两互补对称输出.

  529. 8个通道PWM设置对应P6的8个端口.

  530. 通过P6口上连接的8个LED灯,利用PWM实现呼吸灯效果.

  531. PWM周期和占空比可以根据需要自行设置,最高可达65535.

  532. 下载时, 选择时钟 24MHZ (用户可在"config.h"修改频率).

  533. ******************************************/

  534. /*************        本地常量声明        **************/


  535. /*************        本地变量声明        **************/

  536. PWMx_Duty PWMA_Duty;

  537. /*************        本地函数声明        **************/



  538. /*************  外部函数和变量声明 *****************/



  539. /************************ IO口配置 ****************************/
  540. void        GPIO_config(void)
  541. {
  542.         GPIO_InitTypeDef        GPIO_InitStructure;                                //结构定义
  543.         GPIO_InitStructure.Pin  = GPIO_Pin_0;                                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
  544.         GPIO_InitStructure.Mode = GPIO_PullUp;                        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  545.         GPIO_Inilize(GPIO_P4,&GPIO_InitStructure);        //初始化

  546.         GPIO_InitStructure.Pin  = GPIO_Pin_All;                        //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
  547.         GPIO_InitStructure.Mode = GPIO_PullUp;                        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  548.         GPIO_Inilize(GPIO_P6,&GPIO_InitStructure);        //初始化
  549. }

  550. /************************ 定时器配置 ****************************/
  551. void        Timer_config(void)
  552. {
  553.         TIM_InitTypeDef                TIM_InitStructure;                                                //结构定义
  554.         TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;        //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
  555.         TIM_InitStructure.TIM_Priority    = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  556.         TIM_InitStructure.TIM_Interrupt = ENABLE;                                        //中断是否允许,   ENABLE或DISABLE
  557.         TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T;                //指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
  558.         TIM_InitStructure.TIM_ClkOut    = DISABLE;                                //是否输出高速脉冲, ENABLE或DISABLE
  559.         TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / 1000);                //中断频率, 1000次/秒
  560.         TIM_InitStructure.TIM_Run       = ENABLE;                                        //是否初始化后启动定时器, ENABLE或DISABLE
  561.         Timer_Inilize(Timer0,&TIM_InitStructure);                                        //初始化Timer0          Timer0,Timer1,Timer2,Timer3,Timer4
  562. }

  563. /***************  串口初始化函数 *****************/
  564. void        PWM_config(void)
  565. {
  566.         PWMx_InitDefine                PWMx_InitStructure;
  567.         
  568.         PWMx_InitStructure.PWM1_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  569.         PWMx_InitStructure.PWM2_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  570.         PWMx_InitStructure.PWM3_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  571.         PWMx_InitStructure.PWM4_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2

  572.         PWMx_InitStructure.PWM1_SetPriority  = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  573.         PWMx_InitStructure.PWM2_SetPriority  = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  574.         PWMx_InitStructure.PWM3_SetPriority  = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  575.         PWMx_InitStructure.PWM4_SetPriority  = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  576.         
  577.         PWMx_InitStructure.PWM_Period   = 2047;                                                        //周期时间,   0~65535
  578.         PWMx_InitStructure.PWM1_Duty    = PWMA_Duty.PWM1_Duty;        //PWM1占空比时间, 0~Period
  579.         PWMx_InitStructure.PWM2_Duty    = PWMA_Duty.PWM2_Duty;        //PWM2占空比时间, 0~Period
  580.         PWMx_InitStructure.PWM3_Duty    = PWMA_Duty.PWM3_Duty;        //PWM3占空比时间, 0~Period
  581.         PWMx_InitStructure.PWM4_Duty    = PWMA_Duty.PWM4_Duty;        //PWM4占空比时间, 0~Period
  582.         PWMx_InitStructure.PWM_DeadTime = 0;                                                                //死区发生器设置, 0~255
  583.         
  584.         PWMx_InitStructure.PWM_EnoSelect   = ENO1P | ENO1N | ENO2P | ENO2N | ENO3P | ENO3N | ENO4P | ENO4N;        //输出通道选择,        ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
  585.         PWMx_InitStructure.PWM_PS_SW       = PWM1_SW_P60_P61| PWM2_SW_P62_P63 | PWM3_SW_P64_P65 | PWM4_SW_P66_P67;        //切换端口,                PWM1_SW_P10_P11,PWM1_SW_P20_P21,PWM1_SW_P60_P61
  586.                                                                                                                                                                                                                         //                                                PWM2_SW_P12_P13,PWM2_SW_P22_P23,PWM2_SW_P62_P63
  587.                                                                                                                                                                                                                         //                                                PWM3_SW_P14_P15,PWM3_SW_P24_P25,PWM3_SW_P64_P65
  588.                                                                                                                                                                                                                         //                                                PWM4_SW_P16_P17,PWM4_SW_P26_P27,PWM4_SW_P66_P67,PWM4_SW_P34_P33

  589.         PWMx_InitStructure.PWM_CC1Enable   = ENABLE;                                //开启PWM1P输入捕获/比较输出,  ENABLE,DISABLE
  590.         PWMx_InitStructure.PWM_CC1NEnable  = ENABLE;                                //开启PWM1N输入捕获/比较输出,  ENABLE,DISABLE
  591.         PWMx_InitStructure.PWM_CC2Enable   = ENABLE;                                //开启PWM2P输入捕获/比较输出,  ENABLE,DISABLE
  592.         PWMx_InitStructure.PWM_CC2NEnable  = ENABLE;                                //开启PWM2N输入捕获/比较输出,  ENABLE,DISABLE
  593.         PWMx_InitStructure.PWM_CC3Enable   = ENABLE;                                //开启PWM3P输入捕获/比较输出,  ENABLE,DISABLE
  594.         PWMx_InitStructure.PWM_CC3NEnable  = ENABLE;                                //开启PWM3N输入捕获/比较输出,  ENABLE,DISABLE
  595.         PWMx_InitStructure.PWM_CC4Enable   = ENABLE;                                //开启PWM4P输入捕获/比较输出,  ENABLE,DISABLE
  596.         PWMx_InitStructure.PWM_CC4NEnable  = ENABLE;                                //开启PWM4N输入捕获/比较输出,  ENABLE,DISABLE
  597.         
  598.         PWMx_InitStructure.PWM_MainOutEnable= ENABLE;                                //主输出使能, ENABLE,DISABLE
  599.         PWMx_InitStructure.PWM_CEN_Enable   = ENABLE;                                //使能计数器, ENABLE,DISABLE
  600.         PWM_Configuration(PWMA, &PWMx_InitStructure);                                //初始化PWM,  PWMA,PWMB
  601. }


  602. /******************* PWM 占空比设置函数 *******************/
  603. void UpdatePwm(u8 PWM, PWMx_Duty *PWMx)
  604. {
  605.         EAXSFR();                /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */

  606.         if(PWM == PWMA)
  607.         {
  608.                 PWMA_Duty1(PWMx->PWM1_Duty);
  609.                 PWMA_Duty2(PWMx->PWM2_Duty);
  610.                 PWMA_Duty3(PWMx->PWM3_Duty);
  611.                 PWMA_Duty4(PWMx->PWM4_Duty);
  612.         }
  613.         else
  614.         {
  615.                 PWMB_Duty5(PWMx->PWM5_Duty);
  616.                 PWMB_Duty6(PWMx->PWM6_Duty);
  617.                 PWMB_Duty7(PWMx->PWM7_Duty);
  618.                 PWMB_Duty8(PWMx->PWM8_Duty);
  619.         }
  620.         
  621.         EAXRAM();                /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展RAM(XRAM) */
  622. }

  623. /*********************************************************/


  624. /******************** 主函数**************************/
  625. void main(void)
  626. {
  627.         PWMA_Duty.PWM1_Duty = 128;
  628.         PWMA_Duty.PWM2_Duty = 256;
  629.         PWMA_Duty.PWM3_Duty = 512;
  630.         PWMA_Duty.PWM4_Duty = 1024;
  631.         
  632.         GPIO_config();
  633.         Timer_config();
  634.         PWM_config();
  635.         EA = 1;
  636.         P40 = 0;                //打开LED电源

  637.         while (1);
  638. }



复制代码
回复

使用道具 举报

ID:734017 发表于 2021-8-15 01:37 | 显示全部楼层
angmall 发表于 2021-8-14 21:03
我给你来个程序试试

高级PWM1-PWM2-PWM3-PWM4驱动P6口呼吸灯实验程序-STC8H

太复杂了,老哥,还是感谢谢,我只需要简单的PWM
回复

使用道具 举报

ID:734017 发表于 2021-8-15 01:39 | 显示全部楼层
Y_G_G 发表于 2021-8-14 18:46
STC的PWM的数据手册着实让人头痛,洋洋洒洒写一大堆,看半天都不知道它在说什么,好几次看了一半,心想着算了, ...

是的,写得一大堆,看不下去。
回复

使用道具 举报

ID:349729 发表于 2022-1-12 12:50 | 显示全部楼层
我也是
回复

使用道具 举报

ID:72649 发表于 2022-1-12 16:39 来自手机 | 显示全部楼层
angmall 发表于 2021-8-14 21:03
我给你来个程序试试

高级PWM1-PWM2-PWM3-PWM4驱动P6口呼吸灯实验程序-STC8H

这么多是不是完整的
回复

使用道具 举报

ID:391100 发表于 2022-2-16 11:44 | 显示全部楼层
同感----定时器没空,用不了,只能用PWM了,PCA-PWM的芯片 IO不够,用增强型PWM,结果芯片又不产了。只好重新弄高级PWM,烦得静不下心情。
回复

使用道具 举报

ID:391100 发表于 2022-2-16 11:46 | 显示全部楼层
那么多寄存器,很怕某一个没设置到,造成不稳定。
回复

使用道具 举报

ID:748788 发表于 2022-2-17 08:42 | 显示全部楼层
可繁可简,根据需要吧。手册中下面这个例程就很简洁:
20.8.13  输出任意周期和任意占空比的波形
回复

使用道具 举报

ID:1003077 发表于 2022-3-5 10:33 | 显示全部楼层
高级PWM确实看不懂技术手册,用寄存器太多了
回复

使用道具 举报

ID:382454 发表于 2022-3-5 16:35 | 显示全部楼层
先要有一个开发板,一个一个动作烧录进去验证,之后就慢慢的会了。要么你会画PCB的话,自己画也行。
回复

使用道具 举报

ID:922504 发表于 2022-3-16 09:02 | 显示全部楼层
angmall 发表于 2021-8-14 21:03
我给你来个程序试试

高级PWM1-PWM2-PWM3-PWM4驱动P6口呼吸灯实验程序-STC8H

很有学习价值   收藏   慢慢研究
回复

使用道具 举报

ID:514901 发表于 2022-3-16 09:12 | 显示全部楼层
打开STC-ISP,选择里面的“范例程序”选项栏,里面有PWM的范例程序,看懂了,就学会了。不必去深究那些寄存器,因为过后你也会忘掉,你只需要知道PWM的两大因素周期、占空比怎么去计算和设置即可。
回复

使用道具 举报

ID:87631 发表于 2022-6-15 11:02 | 显示全部楼层
但这种方式不能保持一直输出一个高电平,也就是100%占空比啊
回复

使用道具 举报

ID:1041851 发表于 2023-5-5 09:04 | 显示全部楼层
同感,感觉把简单的事情整复杂了
回复

使用道具 举报

ID:1034262 发表于 2023-5-5 11:22 | 显示全部楼层
如果比较了解PWM,那就不是事。
STC8H的PWM跟STM32F103的PWM几乎一样的,没见到有人说STM32F103的PWM寄存器多、复杂。
STC手册还是中文的,不难。
PWM原理都是一样的,用各个寄存器来控制而已。下面是STC官方论坛发布的PWM程序,我觉得比STM32的简单的多,楼主可以参考。
STC8H系列-高级PWM相关程序.rar (1.36 MB, 下载次数: 101)
回复

使用道具 举报

ID:1092259 发表于 2023-9-5 14:52 | 显示全部楼层
楼上的很全面。
回复

使用道具 举报

ID:391100 发表于 2024-1-10 10:27 | 显示全部楼层
那你们还好,整个STC系列,他们的PWM每次变动,都成功绕晕我好几天,而且没有记忆性,下次又得晕。
回复

使用道具 举报

ID:391100 发表于 2024-1-10 10:29 | 显示全部楼层
Y_G_G 发表于 2021-8-14 18:46
STC的PWM的数据手册着实让人头痛,洋洋洒洒写一大堆,看半天都不知道它在说什么,好几次看了一半,心想着算了, ...

洋洋洒洒不怕,我怕的是那些寄存器,基本上就那几个大写字母,调换下顺序翻来覆去,关键又太多。。。
回复

使用道具 举报

ID:71233 发表于 2024-1-13 20:13 | 显示全部楼层
STC芯片手册中关于PWM部分的叙述,我也觉得不好理解,好像有点思路不清的样子。
回复

使用道具 举报

ID:1109109 发表于 2024-1-14 13:31 | 显示全部楼层
文档看不明白建议多看看视频,网上有很多教学视频,多搜索一下,编程也有很多教程,需要找到自己适合的并认真学习,不用着急慢慢来就可以
回复

使用道具 举报

ID:1109109 发表于 2024-1-14 13:32 | 显示全部楼层
网上有很多视频教程,可以上网多搜索一下,类似编程也是一样的,多看看视频,学习一下人家的思路,找到适合自己风格的加以学习可以成功的
回复

使用道具 举报

ID:72088 发表于 2024-4-11 19:57 | 显示全部楼层
同感,我也看不懂PWM,我也想学高级的16位,一度怀疑这文档是翻译过来的,你们看呢
回复

使用道具 举报

ID:1034262 发表于 2024-4-12 17:21 | 显示全部楼层
新乡家电维修 发表于 2024-4-11 19:57
同感,我也看不懂PWM,我也想学高级的16位,一度怀疑这文档是翻译过来的,你们看呢

2007年我第一次用STM32F103的PWM也是这样想的,觉得都不是设计给人用的。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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