历史上的今天
返回首页

历史上的今天

今天是:2024年12月05日(星期四)

正在发生

2020年12月05日 | STC15W4K60S2单片机2路SPWM源程序 可驱动电机

2020-12-05 来源:51hei

分享一个双路的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, 无中断

推荐阅读

史海拾趣

Brilliance公司的发展小趣事

在国内市场取得一定成功后,Brilliance公司开始将目光投向国际市场。公司制定了详细的国际化战略,积极寻求与国际知名企业的合作机会。通过与国外合作伙伴的共同努力,Brilliance的产品逐渐打入国际市场,并获得了良好的口碑。同时,公司还积极参加国际电子展会和交流活动,提升了品牌知名度和影响力。

EAO公司的发展小趣事

面对全球市场的竞争压力,EAO公司坚定实施全球化战略。公司在全球范围内建立了完善的销售网络和售后服务体系,为客户提供及时、高效的服务。同时,EAO公司还积极寻求与国际知名企业的合作机会,共同开拓市场、分享资源。通过全球化战略的实施,EAO公司不断提升品牌影响力和市场竞争力。

GD Rectifiers Ltd公司的发展小趣事

面对数字化时代的到来,GD Rectifiers Ltd主动拥抱变革,积极推进数字化转型。公司投入巨资建设了先进的数字化生产管理系统和客户关系管理系统,实现了生产过程的智能化和透明化。通过数据分析和挖掘技术,公司能够更准确地把握市场需求和客户需求的变化趋势,为产品研发和市场营销提供有力支持。同时,公司还加强了与供应商和客户的数字化连接和协作,提高了供应链的协同效率和响应速度。数字化转型的成功实施为GD Rectifiers Ltd注入了新的活力,进一步提升了公司的市场竞争力和行业地位。

CHINFA公司的发展小趣事

在环保日益受到重视的今天,CHINFA公司积极响应国家号召,践行绿色环保理念。公司致力于研发和生产节能、环保的电子产品,通过技术创新和材料替代,减少了对环境的污染和破坏。同时,公司还加强了对生产废弃物的处理和回收利用,实现了资源的循环利用和可持续发展。

Furukawa Electric Co Ltd公司的发展小趣事

在环保日益受到重视的今天,CHINFA公司积极响应国家号召,践行绿色环保理念。公司致力于研发和生产节能、环保的电子产品,通过技术创新和材料替代,减少了对环境的污染和破坏。同时,公司还加强了对生产废弃物的处理和回收利用,实现了资源的循环利用和可持续发展。

Hirel Systems Ltd公司的发展小趣事

CHINFA公司的创立并非一帆风顺。在创业初期,公司面临着资金短缺、技术落后和市场竞争激烈等多重困难。然而,公司的创始人凭借对电子行业的深厚热爱和坚定信念,带领团队克服了一个又一个难关。他们通过自主研发、技术创新和市场拓展,逐渐在行业中崭露头角。

问答坊 | AI 解惑

如何编写Em78系列单片机的中断程序

编写EM78p153芯片的汇编程序时,如何编写一个中断程序,请各位指导一下,最好能提供几个中断程序予以参考 我是初学者 …

查看全部问答>

周立功的中断KEY程序

请教各位一下 周立功的KEY外部中断程序有几个地方不明白 #define BEEP            (1ul << 7)               ...…

查看全部问答>

【9B96触摸屏】关于SSD2119的初始化流程

TI 9B96开发板的触摸屏程序中的SSD2119驱动程序是根据哪个文档写的? 我没有在SSD2119 DataSheet上看到有初始化流程,哪个大虾玩过,请明示啊 …

查看全部问答>

关于单色50*200的LED动态显示器

一个单色50*200的LED动态显示器的满负荷功耗有多大啊?急!急!急!…

查看全部问答>

430也能玩嵌入式:Contiki内核在IAR+MSP430下移植(三)

2.3 ISR定义修改 Contiki默认开发环境是Linux,其中断服务处理程序定义格式与IAR不同,编译的时候报如下错误:图4 ISR相关错误 这里只要略加修改即可,改成符合IAR的格式,以button-sensor.c为例,如下: interrupt(PORT2_VECTOR) irq_p2(void ...…

查看全部问答>

TM4C123G使用ADC和GPIO引起FaultISR

初学M4遇到的问题,我在ti官方的例程timers上加入了ADC模块的使用,同时使用了一个普通IO口驱动的显示屏,发现一旦运行就会进入FaultISR函数。查阅Program Status Register (xPSR) 寄存器,为0x01000003,应该是出现了hard fault。但是我不知道是什 ...…

查看全部问答>

【TI C2000的使用经验】V1.31库文件使用的改进方法(ECAN为例)

TI C2000官方的V1.31程序库也有年头了,也没太关注,不知道更新了没有。 C2000 V1.31程序库的寄存器定义和别的MCU不太一样,寄存器地址定义不是太直观,使用不是很方便。 以ECAN模块为例,它的寄存器组是这样定义的: struct MOTO_REGS {   ...…

查看全部问答>