找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5581|回复: 6
收起左侧

STC15W4K60S2单片机2路SPWM源程序 可驱动电机

  [复制链接]
ID:392700 发表于 2018-9-3 07:21 | 显示全部楼层 |阅读模式
分享一个双路的SPWM源码可以驱动电机用


正弦表计算:
0.png 0.png

C语言库函数版本STC15W4K60S2单片机源程序如下:
  1. #include        "config.h"
  2. #include        "PWM.h"


  3. /*************        功能说明        **************

  4. 演示使用2路PWM产生互补或同相的SPWM.

  5. 主时钟选择24MHZ, PWM时钟选择1T, PWM周期2400, 死区12个时钟(0.5us).正弦波表用200点.

  6. 输出正弦波频率 = 24000000 / 2400 / 200 = 50 HZ.

  7. 本程序仅仅是一个SPWM的演示程序, 用户可以通过上面的计算方法修改PWM周期和正弦波的点数和幅度.

  8. 本程序输出频率固定, 如果需要变频, 请用户自己设计变频方案.

  9. 本程序从P2.1(PWM3)输出正相脉冲, 从P2.2(PWM4)输出反相脉冲(互补).

  10. 如果需要P2.2输出同相的, 请在初始化配置中"Start_IO_Level"项选择0(设置PWM输出端口的初始电平, 0或1).


  11. 工程文件:
  12. delay.c
  13. pwm.c
  14. main.c

  15. ******************************************/

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


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


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



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



  20. //========================================================================
  21. // 函数: void        PWM_config(void)
  22. // 描述: PWM配置函数。
  23. // 参数: none.
  24. // 返回: none.
  25. // 版本: VER1.0
  26. // 日期: 2014-8-15
  27. // 备注:
  28. //========================================================================
  29. void        PWM_config(void)
  30. {
  31.         PWMx_InitDefine                PWMx_InitStructure;                                        //结构定义
  32.        
  33.         PWMx_InitStructure.PWMx_IO_Select       = PWM3_P21;                //PWM输出IO选择. PWM2_P37,PWM2_P27,PWM3_P21,PWM3_P45,PWM4_P22,PWM4_P44,PWM5_P23,PWM5_P42,PWM6_P16,PWM6_P07,PWM7_P17,PWM7_P06
  34.         PWMx_InitStructure.Start_IO_Level       = 0;                        //设置PWM输出端口的初始电平, 0或1
  35.         PWMx_InitStructure.PWMx_Interrupt       = DISABLE;                //中断允许,                           ENABLE或DISABLE
  36.         PWMx_InitStructure.FirstEdge_Interrupt  = DISABLE;                //第一个翻转中断允许,   ENABLE或DISABLE
  37.         PWMx_InitStructure.SecondEdge_Interrupt = DISABLE;                //第二个翻转中断允许,   ENABLE或DISABLE
  38.         PWMx_InitStructure.FirstEdge            = 65;                        //第一个翻转计数, 1~32767
  39.         PWMx_InitStructure.SecondEdge           = 1220;                        //第二个翻转计数, 1~32767
  40.         PWMx_Configuration(PWM3_ID, &PWMx_InitStructure);                //初始化PWM,         PWM2_ID,PWM3_ID,PWM4_ID,PWM5_ID,PWM6_ID,PWM7_ID
  41.         P21 = 0;
  42.         P2n_push_pull(1<<1);                                                                        //IO初始化, 上电时为高阻

  43.         PWMx_InitStructure.PWMx_IO_Select       = PWM4_P22;                //PWM输出IO选择. PWM2_P37,PWM2_P27,PWM3_P21,PWM3_P45,PWM4_P22,PWM4_P44,PWM5_P23,PWM5_P42,PWM6_P16,PWM6_P07,PWM7_P17,PWM7_P06
  44.         PWMx_InitStructure.Start_IO_Level       = 1;                        //设置PWM输出端口的初始电平, 0或1
  45.         PWMx_InitStructure.PWMx_Interrupt       = DISABLE;                //中断允许,                           ENABLE或DISABLE
  46.         PWMx_InitStructure.FirstEdge_Interrupt  = DISABLE;                //第一个翻转中断允许,   ENABLE或DISABLE
  47.         PWMx_InitStructure.SecondEdge_Interrupt = DISABLE;                //第二个翻转中断允许,   ENABLE或DISABLE
  48.         PWMx_InitStructure.FirstEdge            = 65-PWM_DeadZone;        //第一个翻转计数, 1~32767
  49.         PWMx_InitStructure.SecondEdge           = 1220+PWM_DeadZone;//第二个翻转计数, 1~32767
  50.         PWMx_Configuration(PWM4_ID, &PWMx_InitStructure);                //初始化PWM,         PWM2_ID,PWM3_ID,PWM4_ID,PWM5_ID,PWM6_ID,PWM7_ID
  51.         P22 = 1;
  52.         P2n_push_pull(1<<2);                                                                        //IO初始化, 上电时为高阻

  53.         PWM_SourceClk_Duty(PwmClk_1T, 2400);        //时钟源: PwmClk_1T,PwmClk_2T, ... PwmClk_16T, PwmClk_Timer2,   PWM周期: 1~32767
  54.        
  55.         PWMCR |= ENPWM;                // 使能PWM波形发生器,PWM计数器开始计数
  56. //        PWMCR &= ~ECBI;                //禁止PWM计数器归零中断
  57.         PWMCR |=  ECBI;                //允许PWM计数器归零中断

  58. //        PWMFDCR = ENFD | FLTFLIO | FDIO;        //PWM失效中断控制,  ENFD | FLTFLIO | EFDI | FDCMP | FDIO
  59. }


  60. /**********************************************/
  61. void main(void)
  62. {
  63.        
  64.         PWM_config();        //初始化PWM

  65.         EA = 1;                        //允许全局中断

  66.         while (1)
  67.         {
  68.                
  69.         }
  70. }
复制代码

另一个程序:
  1. #define         MAIN_Fosc                24000000L        //定义主时钟

  2. #include        "STC15Fxxxx.H"

  3. #include        "T_SineTable.h"

  4. #define                PWM_DeadZone        12        /* 死区时钟数, 6 ~ 24之间  */


  5. u8        PWM_Index;        //SPWM查表索引


  6. //========================================================================
  7. // 函数: void        PWM_config(void)
  8. // 描述: PWM配置函数。
  9. // 参数: none.
  10. // 返回: none.
  11. // 版本: VER1.0
  12. // 日期: 2014-8-15
  13. // 备注:
  14. //========================================================================
  15. void        PWM_config(void)
  16. {
  17.         u8        xdata        *px;

  18.         EAXSFR();                        // 访问XFR

  19.         px = PWM3T1H;                // 指针指向PWM3
  20.         *px = 0;                        // 第一个翻转计数高字节
  21.         px++;
  22.         *px = 65;                        // 第一个翻转计数低字节
  23.         px++;
  24.         *px = 1220 / 256;        // 第二个翻转计数高字节
  25.         px++;
  26.         *px = 1220 % 256;        // 第二个翻转计数低字节
  27.         px++;
  28.         *px = 0;                                // PWM3输出选择P2.1, 无中断
  29.         PWMCR  |=  0x02;        // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制
  30.         PWMCFG &= ~0x02;        // 设置PWM输出端口的初始电平为0
  31. //        PWMCFG |=  0x02;        // 设置PWM输出端口的初始电平为1
  32.         P21 = 0;
  33.         P2n_push_pull(1<<1);        //IO初始化, 上电时为高阻

  34.         px = PWM4T1H;                // 指针指向PWM4
  35.         *px = 0;                        // 第一个翻转计数高字节
  36.         px++;
  37.         *px = 65-PWM_DeadZone;                        // 第一个翻转计数低字节
  38.         px++;
  39.         *px = (1220+PWM_DeadZone) / 256;        // 第二个翻转计数高字节
  40.         px++;
  41.         *px = (1220+PWM_DeadZone) % 256;        // 第二个翻转计数低字节
  42.         px++;
  43.         *px = 0;                        // PWM4输出选择P2.2, 无中断
  44.         PWMCR  |=  0x04;        // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制
  45. //        PWMCFG &= ~0x04;        // 设置PWM输出端口的初始电平为0
  46.         PWMCFG |=  0x04;        // 设置PWM输出端口的初始电平为1
  47.         P22 = 1;
  48.         P2n_push_pull(1<<2);        //IO初始化, 上电时为高阻

  49.         px  = PWMCH;                // PWM计数器的高字节
  50.         *px = 2400 / 256;
  51.         px++;
  52.         *px = 2400 % 256;        // PWM计数器的低字节
  53.         px++;                                // PWMCKS, PWM时钟选择
  54.         *px = PwmClk_1T;        // 时钟源: PwmClk_1T,PwmClk_2T, ... PwmClk_16T, PwmClk_Timer2

  55.         EAXRAM();                        // 恢复访问XRAM
  56.        
  57.         PWMCR |= ENPWM;                // 使能PWM波形发生器,PWM计数器开始计数
  58. //        PWMCR &= ~ECBI;                // 禁止PWM计数器归零中断
  59.         PWMCR |=  ECBI;                // 允许PWM计数器归零中断

  60. //        PWMFDCR = ENFD | FLTFLIO | FDIO;        //PWM失效中断控制,  ENFD | FLTFLIO | EFDI | FDCMP | FDIO
  61. }


  62. /**********************************************/
  63. void main(void)
  64. {

  65.         PWM_config();        //初始化PWM

  66.         EA = 1;                        //允许全局中断

  67.         while (1)
  68.         {

  69.         }
  70. }


  71. /********************* PWM中断函数************************/

  72. void PWM_int (void) interrupt PWM_VECTOR
  73. {
  74.         u8        xdata        *px;
  75.         u16        j;
  76.         u8        SW2_tmp;

  77.         if(PWMIF & CBIF)        //PWM计数器归零中断标志
  78.         {
  79.                 PWMIF &= ~CBIF;        //清除中断标志

  80.                 SW2_tmp = P_SW2;        //保存SW2设置
  81.                 EAXSFR();                //访问XFR
  82.                 px = PWM3T2H;        // 指向PWM3
  83.                 j = T_SinTable[PWM_Index];
  84.                 *px = (u8)(j >> 8);        //第二个翻转计数高字节
  85.                 px++;
  86.                 *px = (u8)j;                        //第二个翻转计数低字节

  87.                 j += PWM_DeadZone;                //死区
  88.                 px = PWM4T2H;                        // 指向PWM4
  89.                 *px = (u8)(j >> 8);        //第二个翻转计数高字节
  90.                 px++;
  91.                 *px = (u8)j;                        //第二个翻转计数低字节
  92.                 P_SW2 = SW2_tmp;        //恢复SW2设置

  93.                 if(++PWM_Index >= 200)        PWM_Index = 0;

  94.         }
  95. /*
  96.         if(PWMIF & C2IF)        //PWM2中断标志
  97.         {
  98.                 PWMIF &= ~C2IF;        //清除中断标志
  99.         }

  100.         if(PWMIF & C3IF)        //PWM3中断标志
  101.         {
  102.                 PWMIF &= ~C3IF;        //清除中断标志
  103.         }

  104.         if(PWMIF & C4IF)        //PWM4中断标志
  105.         {
  106.                 PWMIF &= ~C4IF;        //清除中断标志
  107. ……………………

  108. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
STC15W4K60S2-2路SPWM.zip (104.27 KB, 下载次数: 145)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:170318 发表于 2018-9-4 16:17 | 显示全部楼层
下来学习,谢谢分享
回复

使用道具 举报

ID:119977 发表于 2019-5-26 14:30 | 显示全部楼层
我试了  不行  正玄波有很大缺口
回复

使用道具 举报

ID:151314 发表于 2019-5-27 23:58 | 显示全部楼层
如何来驱动电机?
回复

使用道具 举报

ID:235188 发表于 2019-9-12 15:02 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:719608 发表于 2020-4-24 11:38 | 显示全部楼层
感谢分享,谢谢大神1
回复

使用道具 举报

ID:486443 发表于 2020-12-5 16:39 | 显示全部楼层
请问:在另一个程序里,第37、38行 :   
       *px = 0;                       // PWM3输出选择P2.1, 无中断
        PWMCR  |=  0x02;        // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制

和第53、54行:
        *px = 0;                        // PWM4输出选择P2.2, 无中断
        PWMCR  |=  0x04;        // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制

如果要换成第二组口 P4.5和 P4.4 该怎么弄啊?   用PWM3CR=0x08;根本加不进,编译过不了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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