分享一个双路的SPWM源码可以驱动电机用
正弦表计算:
C语言库函数版本STC15W4K60S2单片机源程序如下:
- #include "config.h"
- #include "PWM.h"
- /************* 功能说明 **************
- 演示使用2路PWM产生互补或同相的SPWM.
- 主时钟选择24MHZ, PWM时钟选择1T, PWM周期2400, 死区12个时钟(0.5us).正弦波表用200点.
- 输出正弦波频率 = 24000000 / 2400 / 200 = 50 HZ.
- 本程序仅仅是一个SPWM的演示程序, 用户可以通过上面的计算方法修改PWM周期和正弦波的点数和幅度.
- 本程序输出频率固定, 如果需要变频, 请用户自己设计变频方案.
- 本程序从P2.1(PWM3)输出正相脉冲, 从P2.2(PWM4)输出反相脉冲(互补).
- 如果需要P2.2输出同相的, 请在初始化配置中"Start_IO_Level"项选择0(设置PWM输出端口的初始电平, 0或1).
- 工程文件:
- delay.c
- pwm.c
- main.c
- ******************************************/
- /************* 本地常量声明 **************/
- /************* 本地变量声明 **************/
- /************* 本地函数声明 **************/
- /************* 外部函数和变量声明 *****************/
- //========================================================================
- // 函数: void PWM_config(void)
- // 描述: PWM配置函数。
- // 参数: none.
- // 返回: none.
- // 版本: VER1.0
- // 日期: 2014-8-15
- // 备注:
- //========================================================================
- void PWM_config(void)
- {
- PWMx_InitDefine PWMx_InitStructure; //结构定义
-
- 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
- PWMx_InitStructure.Start_IO_Level = 0; //设置PWM输出端口的初始电平, 0或1
- PWMx_InitStructure.PWMx_Interrupt = DISABLE; //中断允许, ENABLE或DISABLE
- PWMx_InitStructure.FirstEdge_Interrupt = DISABLE; //第一个翻转中断允许, ENABLE或DISABLE
- PWMx_InitStructure.SecondEdge_Interrupt = DISABLE; //第二个翻转中断允许, ENABLE或DISABLE
- PWMx_InitStructure.FirstEdge = 65; //第一个翻转计数, 1~32767
- PWMx_InitStructure.SecondEdge = 1220; //第二个翻转计数, 1~32767
- PWMx_Configuration(PWM3_ID, &PWMx_InitStructure); //初始化PWM, PWM2_ID,PWM3_ID,PWM4_ID,PWM5_ID,PWM6_ID,PWM7_ID
- P21 = 0;
- P2n_push_pull(1<<1); //IO初始化, 上电时为高阻
- 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
- PWMx_InitStructure.Start_IO_Level = 1; //设置PWM输出端口的初始电平, 0或1
- PWMx_InitStructure.PWMx_Interrupt = DISABLE; //中断允许, ENABLE或DISABLE
- PWMx_InitStructure.FirstEdge_Interrupt = DISABLE; //第一个翻转中断允许, ENABLE或DISABLE
- PWMx_InitStructure.SecondEdge_Interrupt = DISABLE; //第二个翻转中断允许, ENABLE或DISABLE
- PWMx_InitStructure.FirstEdge = 65-PWM_DeadZone; //第一个翻转计数, 1~32767
- PWMx_InitStructure.SecondEdge = 1220+PWM_DeadZone;//第二个翻转计数, 1~32767
- PWMx_Configuration(PWM4_ID, &PWMx_InitStructure); //初始化PWM, PWM2_ID,PWM3_ID,PWM4_ID,PWM5_ID,PWM6_ID,PWM7_ID
- P22 = 1;
- P2n_push_pull(1<<2); //IO初始化, 上电时为高阻
- PWM_SourceClk_Duty(PwmClk_1T, 2400); //时钟源: PwmClk_1T,PwmClk_2T, ... PwmClk_16T, PwmClk_Timer2, PWM周期: 1~32767
-
- PWMCR |= ENPWM; // 使能PWM波形发生器,PWM计数器开始计数
- // PWMCR &= ~ECBI; //禁止PWM计数器归零中断
- PWMCR |= ECBI; //允许PWM计数器归零中断
- // PWMFDCR = ENFD | FLTFLIO | FDIO; //PWM失效中断控制, ENFD | FLTFLIO | EFDI | FDCMP | FDIO
- }
- /**********************************************/
- void main(void)
- {
-
- PWM_config(); //初始化PWM
- EA = 1; //允许全局中断
- while (1)
- {
-
- }
- }
复制代码
另一个程序:
- #define MAIN_Fosc 24000000L //定义主时钟
- #include "STC15Fxxxx.H"
- #include "T_SineTable.h"
- #define PWM_DeadZone 12 /* 死区时钟数, 6 ~ 24之间 */
- u8 PWM_Index; //SPWM查表索引
- //========================================================================
- // 函数: void PWM_config(void)
- // 描述: PWM配置函数。
- // 参数: none.
- // 返回: none.
- // 版本: VER1.0
- // 日期: 2014-8-15
- // 备注:
- //========================================================================
- void PWM_config(void)
- {
- u8 xdata *px;
- EAXSFR(); // 访问XFR
- px = PWM3T1H; // 指针指向PWM3
- *px = 0; // 第一个翻转计数高字节
- px++;
- *px = 65; // 第一个翻转计数低字节
- px++;
- *px = 1220 / 256; // 第二个翻转计数高字节
- px++;
- *px = 1220 % 256; // 第二个翻转计数低字节
- px++;
- *px = 0; // PWM3输出选择P2.1, 无中断
- PWMCR |= 0x02; // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制
- PWMCFG &= ~0x02; // 设置PWM输出端口的初始电平为0
- // PWMCFG |= 0x02; // 设置PWM输出端口的初始电平为1
- P21 = 0;
- P2n_push_pull(1<<1); //IO初始化, 上电时为高阻
- px = PWM4T1H; // 指针指向PWM4
- *px = 0; // 第一个翻转计数高字节
- px++;
- *px = 65-PWM_DeadZone; // 第一个翻转计数低字节
- px++;
- *px = (1220+PWM_DeadZone) / 256; // 第二个翻转计数高字节
- px++;
- *px = (1220+PWM_DeadZone) % 256; // 第二个翻转计数低字节
- px++;
- *px = 0; // PWM4输出选择P2.2, 无中断
- PWMCR |= 0x04; // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制
- // PWMCFG &= ~0x04; // 设置PWM输出端口的初始电平为0
- PWMCFG |= 0x04; // 设置PWM输出端口的初始电平为1
- P22 = 1;
- P2n_push_pull(1<<2); //IO初始化, 上电时为高阻
- px = PWMCH; // PWM计数器的高字节
- *px = 2400 / 256;
- px++;
- *px = 2400 % 256; // PWM计数器的低字节
- px++; // PWMCKS, PWM时钟选择
- *px = PwmClk_1T; // 时钟源: PwmClk_1T,PwmClk_2T, ... PwmClk_16T, PwmClk_Timer2
- EAXRAM(); // 恢复访问XRAM
-
- PWMCR |= ENPWM; // 使能PWM波形发生器,PWM计数器开始计数
- // PWMCR &= ~ECBI; // 禁止PWM计数器归零中断
- PWMCR |= ECBI; // 允许PWM计数器归零中断
- // PWMFDCR = ENFD | FLTFLIO | FDIO; //PWM失效中断控制, ENFD | FLTFLIO | EFDI | FDCMP | FDIO
- }
- /**********************************************/
- void main(void)
- {
- PWM_config(); //初始化PWM
- EA = 1; //允许全局中断
- while (1)
- {
- }
- }
- /********************* PWM中断函数************************/
- void PWM_int (void) interrupt PWM_VECTOR
- {
- u8 xdata *px;
- u16 j;
- u8 SW2_tmp;
- if(PWMIF & CBIF) //PWM计数器归零中断标志
- {
- PWMIF &= ~CBIF; //清除中断标志
- SW2_tmp = P_SW2; //保存SW2设置
- EAXSFR(); //访问XFR
- px = PWM3T2H; // 指向PWM3
- j = T_SinTable[PWM_Index];
- *px = (u8)(j >> 8); //第二个翻转计数高字节
- px++;
- *px = (u8)j; //第二个翻转计数低字节
- j += PWM_DeadZone; //死区
- px = PWM4T2H; // 指向PWM4
- *px = (u8)(j >> 8); //第二个翻转计数高字节
- px++;
- *px = (u8)j; //第二个翻转计数低字节
- P_SW2 = SW2_tmp; //恢复SW2设置
- if(++PWM_Index >= 200) PWM_Index = 0;
- }
- /*
- if(PWMIF & C2IF) //PWM2中断标志
- {
- PWMIF &= ~C2IF; //清除中断标志
- }
- if(PWMIF & C3IF) //PWM3中断标志
- {
- PWMIF &= ~C3IF; //清除中断标志
- }
- if(PWMIF & C4IF) //PWM4中断标志
- {
- PWMIF &= ~C4IF; //清除中断标志
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
STC15W4K60S2-2路SPWM.zip
(104.27 KB, 下载次数: 148)
|