历史上的今天
返回首页

历史上的今天

今天是:2025年01月21日(星期二)

正在发生

2020年01月21日 | MSP430 定时器输出PWM波形

2020-01-21 来源:eefocus

硬件介绍:

MSP430系列单片机的TimerA结构复杂,功能强大,适合应用于工业控制,如数字化电机控制,电表和手持式仪表的理想配置。它给开发人员提供了较多灵活的选择余地。当PWM 不需要修改占空比和时间时,TimerA 能自动输出PWM,而不需利用中断维持PWM输出。


MSP430F16x和MSP430F14x单片机内部均含有两个定时器,TA和TB;TA有三个模块,CCR0-CCR2;TB含有CCR0-CCR67个模块;其中CCR0模块不能完整的输出PWM波形(只有三种输出模式可用);TA可以输出完整的2路PWM波形;TB可以输出6路完整的PWM波形。


定时器的PWM输出有有8种模式:


输出模式0  输出模式:输出信号OUTx由每个捕获/比较模块的控制寄存器CCTLx中的OUTx位定义,并在写入该寄存器后立即更新。最终位OUTx直通。 

输出模式1 置位模式:输出信号在TAR等于CCRx时置位,并保持置位到定时器复位或选择另一种输出模式为止。 

输出模式2 PWM翻转/复位模式:输出在TAR的值等于CCRx时翻转,当TAR的值等于CCR0时复位。 

输出模式3 PWM置位/复位模式:输出在TAR的值等于CCRx时置位,当TAR的值等于CCR0时复位。 

输出模式4 翻转模式:输出电平在TAR的值等于CCRx时翻转,输出周期是定时器周期的2倍。 

输出模式5复位模式:输出在TAR的值等于CCRx时复位,并保持低电平直到选择另一种输出模式。 

输出模式6PWM翻转/置位模式:输出电平在TAR的值等于CCRx时翻转,当TAR值等于CCR0时置位。 

输出模式7PWM复位/置位模式:输出电平在TAR的值等于CCRx时复位,当TAR的值等于CCR0时置位。


下图是增计数模式下的输出波形(本程序使用的是增模式3和7):

image

计数模式:


增计数模式 

捕获/比较寄存器CCR0用作Timer_A增计数模式的周期寄存器,因为CCR0为16位寄存器,所以该模式适用于定时周期小于65 536的连续计数情况。计数器TAR可以增计数到CCR0的值,当计数值与CCR0的值相等(或定时器值大于CCR0的值)时,定时器复位并从0开始重新计数。

image

连续计数模式 

在需要65 536个时钟周期的定时应用场合常用连续计数模式。定时器从当前值计数到0FFFFH后,又从0开始重新计数

image

增/减计数模式 

需要对称波形的情况经常可以使用增/减计数模式,该模式下,定时器先增计数到CCR0的值,然后反向减计数到0。计数周期仍由CCR0定义,它是CCR0计数器数值的2倍。

image

TA定时器有比较、捕获两种工作方式;比较可以产生PWM波形等,捕获可以精确的测量时间;这里用的是比较输出。


硬件介绍就这么多了,其他的可以参考msp430x1xx_family_users_guide(用户指南)。


程序实现:

本程序是直接从msp430f42x移植的,只改动了端口就能正常使用了。由此,430的模块在不同的系列中是通用的,有关寄存器是一样的;只是也许外部端口不太一样。


程序初始化部分:完成TA相关寄存器的初始化。


char TAPwmInit(char Clk,char Div,char Mode1,char Mode2)

{

    TACTL = 0;                  //清除以前设置

    TACTL |= MC_1;              //定时器TA设为增计数模式  

    switch(Clk)                 //选择时钟源

    { 

        case 'A': case 'a':  TACTL|=TASSEL_1; break;    //ACLK

        case 'S': case 's':  TACTL|=TASSEL_2; break;    //SMCLK

        case 'E':            TACTL|=TASSEL_0; break;    //外部输入(TACLK)

        case 'e':            TACTL|=TASSEL_3; break;    //外部输入(TACLK取反)

        default :  return(0);                           //参数有误

    } 

    switch(Div)                 //选择分频系数

    { 

        case 1:   TACTL|=ID_0; break;   //1

        case 2:   TACTL|=ID_1; break;   //2

        case 4:   TACTL|=ID_2; break;   //4

        case 8:   TACTL|=ID_3; break;   //8

        default :  return(0);           //参数有误

    } 

    switch(Mode1)               //设置PWM通道1的输出模式。

    { 

        case 'P':case 'p':          //如果设置为高电平模式

            TACCTL1 = OUTMOD_7;     //高电平PWM输出

            P1SEL |= BIT2;          //从P1.2输出 (不同型号单片机可能不一样)

            P1DIR |= BIT2;          //从P1.2输出 (不同型号单片机可能不一样)              

            break;

        case 'N':case 'n':          //如果设置为低电平模式          

            TACCTL1 = OUTMOD_3;     //低电平PWM输出

            P1SEL |= BIT2;          //从P1.2输出 (不同型号单片机可能不一样) 

            P1DIR |= BIT2;          //从P1.2输出 (不同型号单片机可能不一样)                

            break; 

        case '0':case 0:            //如果设置为禁用          

            P1SEL &= ~BIT2;         //P1.2恢复为普通IO口              

            break;                 

        default :  return(0);       //参数有误

    } 

    switch(Mode2)                   //设置PWM通道1的输出模式。

    { 

        case 'P':case 'p':          //如果设置为高电平模式

            TACCTL2 =OUTMOD_7;      //高电平PWM输出

            P1SEL |= BIT3;          //从P1.3输出 (不同型号单片机可能不一样)

            P1DIR |= BIT3;          //从P1.3输出 (不同型号单片机可能不一样)

            break;

        case 'N':case 'n':          //如果设置为低电平模式          

            TACCTL2 =OUTMOD_3;      //低电平PWM输出

            P1SEL |= BIT3;          //从P1.3输出 (不同型号单片机可能不一样)  

            P1DIR |= BIT3;          //从P1.3输出 (不同型号单片机可能不一样)              

            break; 

        case '0':case 0:            //如果设置为禁用          

            P1SEL &= ~BIT3;         //P1.3恢复为普通IO口              

            break;                 

        default :  return(0);       //参数有误

    }    

    return(1);  

}

主要是设置TACTL寄存器,让TA工作于增模式,设置时钟源和分频;CCTLx设置对应的输出模式;并且打开相应端口的第二功能。


设置周期函数:设置PWM波形的周期,单位是多少个TACLK周期。


void TAPwmSetPeriod(unsigned int Period)

{

    TACCR0 = Period;

}

工作于增模式时,TA计数到TACCR0,设CCR0就完成了周期的设置。


设置占空比:设置TA的PWM输出的有效电平的时间。


void TAPwmSetDuty(char Channel,unsigned int Duty)

{

    switch(Channel)

    {

        case 1: TACCR1=Duty; break; 

        case 2: TACCR2=Duty; break;    

    }

}

根据参数分别设置每一路的参数。


设置占空比,用千分比设置:


* 入口参数:Channel: 当前设置的通道号  1/2

            Percent: PWM有效时间的千分比 (0~1000) 

* 出口参数:无

* 说    明: 1000=100.0%  500=50.0% ,依次类推        

* 范    例: TAPwmSetPermill(1,300)设置PWM通道1方波的占空比为30.0%

            TAPwmSetPermill(2,825)设置PWM通道2方波的占空比为82.5%

            */

void TAPwmSetPermill(char Channel,unsigned int Percent)

{

    unsigned long int Period;

    unsigned int Duty;

    Period = TACCR0;

    Duty = Period * Percent / 1000;

    TAPwmSetDuty(Channel,Duty);

}

这个函数用千分比来设置PWM输出的有效时间。方便程序的使用。


有关定时器,TI提供的大量的例程,这些历程都很简洁、清晰。需要其他功能可以自己根据例程编写对应的程序。程序实现就这么多了,下面说下本程序的使用方法。


使用示例:

使用方式:依然是在工程中加入c文件;文件包含h头文件;然后就可以正常使用本函数了。详细参考示例工程和main.c。


main主要程序如下:


#include "msp430x16x.h"     //430寄存器头文件

#include "TAPwm.h"          //TA PWM输出程序库头文件


void main()

{

    // Stop watchdog timer to prevent time out reset

    WDTCTL = WDTPW + WDTHOLD;

    ClkInit();

    

    TAPwmInit('A',1,'P','P');   //将定时器TA初始化成为PWM发生器

                  //时钟源=ACLK ; 无分频;  通道1和通道2均设为高电平模式。

    TAPwmSetPeriod(500);        //通道1/2的PWM方波周期均设为500个时钟周期

    TAPwmSetDuty(1,200);        //1通道 有效200个时钟周期

    TAPwmSetPermill(2,200);     //2通道 20.0%


    LPM0;

}

本程序调用程序库,产生两路PWM波形。


TA的PWM输出就到这儿了,如果需要更多路的PWM波,可以使用TB,他可以产生6路完整的PWM波形;可以参考本程序编写TB的波形输出程序。有什么不足之处,欢迎评论,讨论。

推荐阅读

史海拾趣

FCI / Amphenol公司的发展小趣事

随着公司规模的扩大和市场的拓展,Amphenol公司开始实施全球扩张和多元化战略。公司不仅在美国本土设立了多个生产基地,还在欧洲、亚洲等地建立了分公司和研发中心。此外,Amphenol公司还积极涉足电子连接器等其他领域,进一步丰富了公司的产品线。这些举措不仅增强了公司的市场竞争力,也为公司的长期发展奠定了坚实的基础。

Econais公司的发展小趣事

随着技术的不断成熟和市场的日益扩大,Econais开始将目光投向全球市场。公司积极参加各类国际展会和研讨会,与全球各地的客户和合作伙伴建立联系。同时,Econais还针对不同地区的市场需求,推出定制化的产品和解决方案。这些努力使得Econais在全球范围内的市场份额逐渐扩大。

Eurohm Resistors公司的发展小趣事

随着市场的不断扩张和竞争的加剧,Eurohm Resistors始终坚持品质至上的原则。公司建立了严格的质量控制体系,从原材料采购到生产流程,再到成品检验,每一个环节都严格把关。这种对品质的坚守不仅赢得了客户的信任,也为公司赢得了良好的口碑。

Ho Chien Electronics Group Inc公司的发展小趣事

随着环保意识的不断提高,Eurohm Resistors公司积极响应绿色发展的号召。公司投入大量资源研发环保型电阻器产品,采用可再生材料和绿色生产工艺,降低产品对环境的影响。同时,公司还积极参与各种环保活动,推动行业的绿色发展。

Analog Microelectronics GmbH公司的发展小趣事

在全球化的浪潮下,Eurohm Resistors公司积极拓展海外市场。公司深入分析了全球电子行业的发展趋势和市场需求,制定了详细的市场拓展计划。通过与当地合作伙伴的紧密合作,Eurohm Resistors成功打入了多个国家和地区的市场,实现了全球化布局。

EMBEST公司的发展小趣事

EMBEST公司成立于XXXX年,早期便专注于ARM嵌入式软件的开发。在XXXX年,EMBEST发布了国内首个具有自主知识产权的ARM嵌入式软件开发工具Embest IDE For ARM,这一里程碑式的产品不仅填补了国内市场的空白,也为EMBEST在嵌入式领域的地位奠定了基础。通过持续的创新和研发,EMBEST逐步建立了自己的技术壁垒,为公司的长远发展奠定了坚实基础。

问答坊 | AI 解惑

Xilinx通过ISO/TS 16949汽车行业标准认证

赛灵思公司(Xilinx)今天宣布获得汽车行业质量标准ISO/TS 16949认证。ISO/TS 16949标准使赛灵思公司能够为整个汽车供应链提供质量和可靠性最高的电子元器件。赛灵思公司在此之前已经满足了其它世界级质量标准的严格要求,包括ISO 9 ...…

查看全部问答>

单片机C51典型应用设计代码

所有代码均在Keil C51 7.0以上版本编译通过。只需要能够运行Windows 98 以上版本的操作系统、并能够安装Keil C51 7.0以上版本的软件即可。…

查看全部问答>

搞通信的:硬件和软件哪个发展前景更大?

请大家谈谈自己相关领域的状况。…

查看全部问答>

请教!请教!

请问一下,三星笔记本管理员密码忘记了,开不了机怎么办?…

查看全部问答>

那里能找到高通qsd8x50片子的资料

我们用到高通这样一个片子,可是没有芯片资料,据高通说还没有发布,不知各位大爷有没有找得到的。 给个网址、 …

查看全部问答>

关于 飞思卡尔(freescale)i.MX51

1、阅读了一下i.MX51  ARM Cortex A8的datasheet,对于IOMUX还是不清楚, 2、还有一些缩写如:PAD、ALTn(n=0, 1, 2...)等等很多,配置一个引脚做很多工作。 3、感觉freescale的比较难理解,以前做三星的一看寄存器就知道是干什么的。 ...…

查看全部问答>

定制系统时加入了微软拼音中文输入法

定制系统时加入了微软拼音中文输入法,结果运行时,只出声母,不出韵母,打不出中文来,请问有人遇到过没,怎么解决? 1、设置了环境变量SET LOCALE=0804; 2.在platform settings中选择了中文(中国),英文(美国),默认语言设为中文; 3.在P ...…

查看全部问答>

关于驱动的调试release和debug

不知道大家对于调试的看法怎么样。一般你在调试的时候是release还是debug的。我每次都基本上时release的。因为是经理教的。只有在调试一些流层性,我们不知道架构的东西我才用debug。反正基本上不用。。用过几次也很懊恼。。点个屏漫天的打印信息。 ...…

查看全部问答>

求助:如何测量白石灰料位?

求助:料仓里的白石灰粉,当放料后,形成如图(四周高,中间低的料位情况)。 这时候测量仪表无法准确测了料位高度。 求助解决方法:如何能让料仓里的料位处于相对水平状态;或者采用什么样的仪表才能够做到精确测量?…

查看全部问答>