MSP430学习笔记(三)丨MSP4305529定时器及其应用(定时中断、PWM、驱动舵机

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

在这里插入图片描述
​  定时器有四种工作模式:停止模式、向上模式、连续模式和向上/向下模式。使用 MC 位(两位)选择工作模式。

MC模式描述
00停止定时器停止计数。
01向上定时器从零重复计数到 TAxCCR0 的值。
10连续定时器从零不断计数到 0FFFFh。
11向上/向下定时器从零重复计数到 TAxCCR0 的值,然后回到零计数。

1.3 定时器中断优先级

在这里插入图片描述
​  以上图的Timer_A的中断向量寄存器TAxIV为例,可以看到与定时器相关的中断一共有7个,分别是通道1到通道6的输入捕获/输出比较中断和时基单元的溢出中断,且这些中断的优先级是从高到低排列的。MSP430在这里并不支持中断优先级的自由配置。

1.4 输出比较模块

​  Timer_A 中有最多七个相同的捕获/比较模块,TAxCCRn(其中n = 0 到 7)。任何一个模块都可以用来捕获定时器数据或生成时间间隔。

二、定时器相关库函数

2.1 Timer_A库函数

// 启动计数
extern void Timer\_A\_startCounter(uint16\_t baseAddress, uint16\_t timerMode);

// 初始化循环计数模式
extern void Timer\_A\_initContinuousMode(uint16\_t baseAddress, Timer_A_initContinuousModeParam \*param);

// 初始化向上计数模式
extern void Timer\_A\_initUpMode(uint16\_t baseAddress, Timer_A_initUpModeParam \*param);

// 初始化上下计数模式
extern void Timer\_A\_initUpDownMode(uint16\_t baseAddress, Timer_A_initUpDownModeParam \*param);

// 初始化捕获模式
extern void Timer\_A\_initCaptureMode(uint16\_t baseAddress, Timer_A_initCaptureModeParam \*param);

// 初始化比较模式
extern void Timer\_A\_initCompareMode(uint16\_t baseAddress, Timer_A_initCompareModeParam \*param);

// 使能中断
extern void Timer\_A\_enableInterrupt(uint16\_t baseAddress);

// 禁止中断
extern void Timer\_A\_disableInterrupt(uint16\_t baseAddress);

// 获取中断标志位状态
extern uint32\_t Timer\_A\_getInterruptStatus(uint16\_t baseAddress);

// 使能捕获/比较中断
extern void Timer\_A\_enableCaptureCompareInterrupt(uint16\_t baseAddress, uint16\_t captureCompareRegister);

// 禁止捕获/比较中断
extern void Timer\_A\_disableCaptureCompareInterrupt(uint16\_t baseAddress, uint16\_t captureCompareRegister);

// 获取捕获/比较中断标志位
extern uint32\_t Timer\_A\_getCaptureCompareInterruptStatus(uint16\_t baseAddress, uint16\_t captureCompareRegister, uint16\_t mask);

// 重置/清除定时器相关设置
extern void Timer\_A\_clear(uint16\_t baseAddress);

// 获取同步的CCR输入
extern uint8\_t Timer\_A\_getSynchronizedCaptureCompareInput(uint16\_t baseAddress, uint16\_t captureCompareRegister, uint16\_t synchronized);

// 获取输出模式的输出位
extern uint8\_t Timer\_A\_getOutputForOutputModeOutBitValue(uint16\_t baseAddress, uint16\_t captureCompareRegister);

// 获取CCR的值
extern uint16\_t Timer\_A\_getCaptureCompareCount(uint16\_t baseAddress, uint16\_t captureCompareRegister);

// 设置输出模式的输出位
extern void Timer\_A\_setOutputForOutputModeOutBitValue(uint16\_t baseAddress, uint16\_t captureCompareRegister, uint8\_t outputModeOutBitValue);

// 输出PWM
extern void Timer\_A\_outputPWM(uint16\_t baseAddress, Timer_A_outputPWMParam \*param);

// 停止定时器运行
extern void Timer\_A\_stop(uint16\_t baseAddress);

// 设置CCR的值
extern void Timer\_A\_setCompareValue(uint16\_t baseAddress, uint16\_t compareRegister, uint16\_t compareValue);

// 设置输出模式
extern void Timer\_A\_setOutputMode(uint16\_t baseAddress, uint16\_t compareRegister, uint16\_t compareOutputMode);

// 清除中断标志
extern void Timer\_A\_clearTimerInterrupt(uint16\_t baseAddress);

// 清除捕获/比较中断标志
extern void Timer\_A\_clearCaptureCompareInterrupt(uint16\_t baseAddress, uint16\_t captureCompareRegister);

// 获取定时器的计数值
extern uint16\_t Timer\_A\_getCounterValue(uint16\_t baseAddress);

三、代码实现

3.1 定时器定时产生中断

  • main.c
#include <driverlib.h>

void Delay\_ms(int x_ms)
{
    while (x_ms--)
    {
        \_\_delay\_cycles(1000);
    }
}


void Timer\_A\_Init(void)
{
    Timer_A_initUpModeParam Timer_A_InitStructure;
    Timer_A_InitStructure.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    Timer_A_InitStructure.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    Timer_A_InitStructure.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_10;
    Timer_A_InitStructure.startTimer = true;
    Timer_A_InitStructure.timerClear = TIMER_A_SKIP_CLEAR;
    Timer_A_InitStructure.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
    Timer_A_InitStructure.timerPeriod = 32767;      // 计数的目标值,即将要被写入CCR0的值
    Timer\_A\_initUpMode(TIMER_A1_BASE, &Timer_A_InitStructure);
}

/\*\*
 \* main.c
 \*/
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    Timer\_A\_Init();
    Timer\_A\_enableInterrupt(TIMER_A1_BASE);

    GPIO\_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0);


    \_EINT();    // 开启全局中断使能


    while (1)
    {

    }
}

#pragma vector = TIMER1\_A1\_VECTOR;
__interrupt void Port1\_interrupt\_process(void)
{
    \_DINT();    // 关闭全局中断

    GPIO\_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN0);

    Timer\_A\_clearTimerInterrupt(TIMER_A1_BASE);

    \_EINT();    // 开启全局中断
}



3.2 PWM波形驱动位置伺服舵机

  • PWM.h
/\*
 \* PWM.h
 \*
 \* Created on: 2023年7月18日
 \* Author: Include everything
 \*/

#ifndef HARDWARE\_PWM\_H\_
#define HARDWARE\_PWM\_H\_

void PWM\_Init(void);
void PWM\_SetPeriod(uint16\_t periodValue);
void PWM\_SetCompare1(uint16\_t value);
void PWM\_SetCompare2(uint16\_t value);

#endif /\* HARDWARE\_PWM\_H\_ \*/


  • PWM.c
/\*
 \* PWM.c
 \*
 \* Created on: 2023年7月18日
 \* Author: Include everything
 \*/

#include <driverlib.h>

void PWM\_Init(void)
{
    GPIO\_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2);   // TA0.1
    GPIO\_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN3);   // TA0.2

    Timer_A_initUpModeParam Timer_A_UpModeInitStructure = {0};
    Timer_A_UpModeInitStructure.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
    Timer_A_UpModeInitStructure.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;    // 32MHz
    Timer_A_UpModeInitStructure.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_32;    // 计时频率为1MHz
    Timer_A_UpModeInitStructure.startTimer = true;
    Timer_A_UpModeInitStructure.timerClear = TIMER_A_SKIP_CLEAR;
    Timer_A_UpModeInitStructure.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
    Timer_A_UpModeInitStructure.timerPeriod = 20000 - 1;    // 周期为20ms
    Timer\_A\_initUpMode(TIMER_A0_BASE, &Timer_A_UpModeInitStructure);

    Timer_A_outputPWMParam Timer_A_outputPWMInitStructure;
    Timer_A_outputPWMInitStructure.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;    // 32MHz
    Timer_A_outputPWMInitStructure.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_32;    // 计时频率为1MHz
    Timer_A_outputPWMInitStructure.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
    Timer_A_outputPWMInitStructure.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
    Timer_A_outputPWMInitStructure.timerPeriod = 20000 - 1;     // 写入CCR0的值
    Timer_A_outputPWMInitStructure.dutyCycle = 500;             // 写入CCR1的值
    Timer\_A\_outputPWM(TIMER_A0_BASE, &Timer_A_outputPWMInitStructure);      // 在TA0.1引脚输出PWM波形

    Timer_A_outputPWMInitStructure.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
    Timer_A_outputPWMInitStructure.compareOutputMode = TIMER_A_OUTPUTMODE_SET_RESET;
    Timer_A_outputPWMInitStructure.dutyCycle = 1000;          // 写入CCR2的值
    Timer\_A\_outputPWM(TIMER_A0_BASE, &Timer_A_outputPWMInitStructure);      // 在TA0.2引脚输出PWM波形
}

// 设置周期
void PWM\_SetPeriod(uint16\_t periodValue)
{
    Timer\_A\_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0, periodValue);
}

void PWM\_SetCompare1(uint16\_t value)
{
    Timer\_A\_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, value);
}

void PWM\_SetCompare2(uint16\_t value)
{
    Timer\_A\_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, value);
}




**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/95d6f19f2826bd8172860bb3cfd12ac9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9fcc7fd60a7159d10717e7642a6db0c2.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

.(img-IXqB2Gk0-1715890063885)]
[外链图片转存中...(img-GIHzzhFO-1715890063885)]

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值