历史上的今天
返回首页

历史上的今天

今天是:2024年10月09日(星期三)

正在发生

2019年10月09日 | MSP430程序库<十一>定时器TA的PWM输出

2019-10-09 来源:eefocus

定时器是单片机常用的其本设备,用来产生精确计时或是其他功能;msp430的定时器不仅可以完成精确定时,还能产生PWM波形输出,和捕获时刻值(上升沿或是下降沿到来的时候)。这里完成一个比较通用的PWM波形产生程序。


硬件介绍:

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的波形输出程序。有什么不足之处,欢迎评论,讨论。


推荐阅读

史海拾趣

ELECTRONIC ASSEMBLY公司的发展小趣事

在电子组装行业,品质是企业的生命线。一家名为“品质电子组装”的公司,从创立之初就坚持以品质为核心竞争力。公司引进了国际先进的生产设备和管理体系,建立了严格的质量控制体系,确保每一件产品都符合高标准、严要求。正是凭借着对品质的坚守和追求,品质电子组装赢得了客户的广泛赞誉和信赖,逐渐在行业中树立了良好的口碑。

EBK Kruger GmbH & Co KG公司的发展小趣事

面对数字化浪潮的挑战,EBK Kruger积极拥抱数字化转型。公司引入了先进的ERP系统和智能制造技术,提高了生产效率和产品质量。同时,EBK Kruger还加强了对大数据和人工智能技术的研发和应用,为客户提供了更加智能化和个性化的产品和服务。通过数字化转型的推动,EBK Kruger在激烈的市场竞争中保持了领先地位。

富瀚(Fullhan)公司的发展小趣事
确保保护器的电源供应正常,无电压波动或断电现象。
敦泰(FOCALTECH)公司的发展小趣事
这可能是显示屏的电路故障,如显示屏损坏、显示屏与主板连接线松动或主板上控制显示屏的电路出现问题。可以尝试重新插拔连接线,如果问题依旧,可能需要更换显示屏或检修主板。
Cypress Industries公司的发展小趣事

Cypress在半导体制造领域一直处于技术革新的前沿。公司不断引入新的工艺技术,从早期的0.8微米CMOS技术到后来的0.21微米工艺,不断推动产品性能的提升。这种对技术的持续投入和追求,使Cypress在行业内树立了良好的技术形象,并赢得了客户的广泛认可。

C-TON Industries公司的发展小趣事

随着国内市场的饱和,C-TON开始将目光投向国际市场。公司制定了全球化的发展战略,通过设立海外分公司、参加国际展会等方式,积极开拓海外市场。同时,C-TON还加强了与国际同行的交流与合作,学习借鉴他们的先进经验和技术。这些举措使得C-TON的产品逐渐在国际市场上占据了一席之地,公司的业务范围也得到了极大的拓展。

问答坊 | AI 解惑

过年回家吗??

过年回家吗??你们好啊。问一下,你们都在那里过年啊。回不回家。有没有不回家的啊。 我今年过年在石家庄过,不回去了,还有没有在外地过年的啊…

查看全部问答>

让你不再害怕指针

让你不再害怕指针…

查看全部问答>

如何读写SIM卡?

我认为知道这些东西就能用单片机或PC的某个接口读写SIM卡的信息、通讯录、所存短信及其它了: 1 SIM卡 引脚定义 2 数据通信所用协议(即所用总线的电气及数据传输出规范) 3 操作指令(即通过总线传输不同二进制数据控制SIM进行不同操作) 第一 ...…

查看全部问答>

突然想起一个问题,有关嵌入式系统内存管理方面的东东

WinCE系统中,动态申请内存是否可以超过32M 如果不行,当碰到处理大数据量的时候,如果要申请的buffer超过了32M,该用什么办法解决这个问题? 应该描述清楚了吧,呵。。。…

查看全部问答>

MCU的另类解释(开心一下)

    看见论坛里面那么多人回复\"女生单片机\"这个话题贴,我突然想了一下什么是MCU,为什么都是男生喜欢?   MCU就是(MM Computer unite)MM和电脑的联合体,所以有那多男生喜欢。    大家还有什么好的解释啊 ...…

查看全部问答>

请问现在做驱动开发, 是用DDk好还是用WDK好呢?

请问现在做驱动开发, 是用DDK好还是用WDK好呢? 因为我是新手,希望选一个从长远上看,较好的出发点。 没有说哪种技术不好的意思 呵呵, 望高人指点 谢谢…

查看全部问答>

windows ce怎样在xp下使用

我要用evc4.0工具开发,在xp下安装好了能直接用么?…

查看全部问答>

STM32SPI经过Keil编译优化后产生的问题

大家好,我用的是Keil UV4 MDK4.0 的编译器,用STM32 的SPI接口与CC2420通信时,发现程序未做优化时(LEVEL 0),MISO能正常接收信息,优化后(LEVE03),MISO接收的信息都是错误的,不知道是什么原因,难道KEIL的优化功能正有BUG? BYTE SPI ...…

查看全部问答>

香斑竹STM32支持浮点运算吗

                                 STM32  支持浮点运算吗  我在MDK环境中 还是有什么浮点库啊…

查看全部问答>

德州仪器:C6-Integra DSP+ARM处理器——OMAP-L138和C6748的安全特性

随着越来越多大公司的安全系统被攻破,嵌入式安全系统的保护工作变得既艰巨又迫切。本视频为你介绍嵌入式系统的系统安全,以及TI C6-Integra OMAP-L138 DSP+ARM和C6748 DSP这两款芯片所提供的安全特性。$(\'swf_uJq\').innerHTML=AC_FL_RunContent( ...…

查看全部问答>