MSP430F5529库函数定时器A——捕获实验

这篇具有很好参考价值的文章主要介绍了MSP430F5529库函数定时器A——捕获实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需提前学习:MSP430F5529库函数学习——串口;MSP430F5529库函数定时器A——硬件PWM

目录

引脚手册获取

实验目的

代码

代码解析

串口数据发送部分

数据捕获部分

定时器部分可选参数

设置定时器部分

捕获部分可选参数

设置捕获引脚部分

中断处理

TA2IV_TACCR2解析

TA2IV_TAIFG解析

主函数解析

实验现象


引脚手册获取

详情看MSP430F5529库函数定时器A——硬件PWM获取引脚手册部分。

实验目的

捕获波形高电平持续时间

代码

MSP430F5529可以进行信号捕获。先提供代码

#include "driverlib.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>


#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))



void UART_printf(uint16_t baseAddress, const char *format,...)
{
    uint32_t length;
    va_list args;
    uint32_t i;
    char TxBuffer[128] = {0};

    va_start(args, format);
    length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer), (char*)format, args);
    va_end(args);

    for(i = 0; i < length; i++)
        USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}

//9600
void Usart1_Init()
{
    //P4.4=UCA1TXD      P4.5=UCA1RXD
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5+GPIO_PIN4);

    USCI_A_UART_initParam param1 = {0};
    param1.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
    param1.clockPrescalar = 6;
    param1.firstModReg = 13;
    param1.secondModReg = 0;
    param1.parity = USCI_A_UART_NO_PARITY;   //无校验位
    param1.msborLsbFirst = USCI_A_UART_LSB_FIRST;  //低位先行
    param1.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;  //1停止位
    param1.uartMode = USCI_A_UART_MODE;
    param1.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;

    if (STATUS_FAIL == USCI_A_UART_init(USCI_A1_BASE, &param1)){
       return;
    }
    //Enable UART module for operation
    USCI_A_UART_enable(USCI_A1_BASE);

    //Enable Receive Interrupt
    USCI_A_UART_clearInterrupt(USCI_A1_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
    USCI_A_UART_enableInterrupt(USCI_A1_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
}


uint32_t Sign_Counts = 0;
void Timer_A2_Capture_Init()
{
    Timer_A_initContinuousModeParam htim = {0};
    htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;  //1048576Hz
    htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;  //一分频,1048576Hz
    htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;  //使能TAIE中断
    htim.timerClear = TIMER_A_DO_CLEAR;        //把定时器的定时计数器,分频计数器的计数值清零
    htim.startTimer = true;                 //初始化后立即启动定时器
    Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);  //设置为连续计数模式

    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);   //复用P2.5
    Timer_A_initCaptureModeParam capture_htim = {0};
    capture_htim.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;   //因为P2.5使用的是TA2.2,所以这里是REGISTER_2
    capture_htim.captureMode = TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE;  //选择双边沿触发
    capture_htim.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;     //
    capture_htim.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;     //捕获源与计时器时钟同步
    capture_htim.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
    capture_htim.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
    Timer_A_initCaptureMode(TIMER_A2_BASE,&capture_htim);
}


int main(void)
{
    //关闭看门狗
    WDT_A_hold(WDT_A_BASE);
    //打开输入捕获
    Timer_A2_Capture_Init();
    Usart1_Init();
    //interrupts enabled
    __bis_SR_register(GIE);

    while(1)
    {
        delay_ms(1000);
        //UART_printf(USCI_A1_BASE,"高电平持续时间:%f ms",1000.*Sign_Counts/1048576); //注意,这里1000后面必须+'.'表示是浮点运算!!!否则结果为0!!!
        UART_printf(USCI_A1_BASE,"高电平持续时间:%f ms",1000.*Sign_Counts/UCS_getSMCLK());//UCS_getSMCLK是获取当前SMCLK时钟频率,当前SMCLK为1048576HZ
    }
}

#pragma vector=TIMER2_A1_VECTOR
__interrupt
void TIMER2_A1_ISR (void)
{
    static uint16_t  Overflow_Times = 0;
    static uint16_t Sign_Begin = 0, Sign_End = 0;

    switch(TA2IV)
    {
        case TA2IV_TACCR2:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //获取P2.5引脚电平,如果为高电平,将当前寄存器值存入Sign_Begin
            {
                Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            }
            else             //获取P2.5引脚电平,如果为低电平,将当前寄存器值存入Sign_End
            {
                Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
                if(!Overflow_Times)    //计算高电平时间,如果高电平和低电平都在一个计数周期之内,进入
                    Sign_Counts = Sign_End - Sign_Begin;   //如果高低电平在同一个计数周期内,那么直接相减
                else                   //计算高电平时间,如果高电平和低电平不在一个计数周期之内,进入
                {
                    //注意,这里强制类型转换,是因为uint16_t 的最大值为65535,此处的Sign_Counts值会明显大于65535
                    Sign_Counts = (uint32_t)(65536 * Overflow_Times + Sign_End - Sign_Begin);  //如果高低电平不在同一个计数周期,需要先加上一个周期的计数值
                    Overflow_Times = 0;
                }
            }
            Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            break;
        case TA2IV_TAIFG:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //获取P2.5引脚电平。如果定时器都溢出中断了,现在还是高电平,那么表明高电平和低电平不在同一个定时周期内
            {
                ++Overflow_Times;
            }
            else  //获取P2.5引脚电平。如果定时器溢出中断了,现在不是高电平,那么表明高电平和低电平在同一个定时周期内
                Overflow_Times = 0;
            Timer_A_clearTimerInterrupt(TIMER_A2_BASE);
            break;
        default:
            break;
    }
}

代码解析

串口数据发送部分

注意,这部分我就提醒一下。我们是需要进行浮点数据打印的,所以我们看MSP430F5529库函数学习——串口的时候,需要按照浮点数据打印这一部分配置!

数据捕获部分

定时器部分可选参数

(1)clockSource:选择时钟源  
  TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
  TIMER_A_CLOCKSOURCE_ACLK
  TIMER_A_CLOCKSOURCE_SMCLK
  TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
 
(2)clockSourceDivider:选择时钟分频次数
 TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]
 TIMER_A_CLOCKSOURCE_DIVIDER_2
 TIMER_A_CLOCKSOURCE_DIVIDER_3
 TIMER_A_CLOCKSOURCE_DIVIDER_4
 TIMER_A_CLOCKSOURCE_DIVIDER_5
 TIMER_A_CLOCKSOURCE_DIVIDER_6
 TIMER_A_CLOCKSOURCE_DIVIDER_7
 TIMER_A_CLOCKSOURCE_DIVIDER_8
 TIMER_A_CLOCKSOURCE_DIVIDER_10
 TIMER_A_CLOCKSOURCE_DIVIDER_12
 TIMER_A_CLOCKSOURCE_DIVIDER_14
 TIMER_A_CLOCKSOURCE_DIVIDER_16
 TIMER_A_CLOCKSOURCE_DIVIDER_20
 TIMER_A_CLOCKSOURCE_DIVIDER_24
 TIMER_A_CLOCKSOURCE_DIVIDER_28
 TIMER_A_CLOCKSOURCE_DIVIDER_32
 TIMER_A_CLOCKSOURCE_DIVIDER_40
 TIMER_A_CLOCKSOURCE_DIVIDER_64
 TIMER_A_CLOCKSOURCE_DIVIDER_48
 TIMER_A_CLOCKSOURCE_DIVIDER_56
 
 
 
(3)timerInterruptEnable_TAIE:使能还是失能定时器中断
  TIMER_A_TAIE_INTERRUPT_ENABLE  //使能定时器中断
  TIMER_A_TAIE_INTERRUPT_DISABLE  //失能定时器中断
 
 
(4)timerClear:选择是否把定时器的定时计数器,分频计数器的计数值清零
  TIMER_A_DO_CLEAR      //清除
  TIMER_A_SKIP_CLEAR    //不清除
 
(5)startTimer:选择初始化之后是否立即启动定时器
    true   //初始化后立即启动定时器
    false  //初始化后不启动定时器
 

设置定时器部分

(1)MSP430F5529定时器时钟 TACLK 可以选择 ACLKSMCLK 或者来自外部的 TAxCLK。SMCLK系统默认 1048576Hz,ACLK系统默认为32768Hz。这里我们选择SMCLK作为时钟源

(2)不进行分频,因为如果进行输入捕获,频率越高,精确度越大。

(3)因为数据捕获实验是采用的连续计数模式,所以只能使用TAIE中断。详情请看MSP430F5529库函数定时器A——定时中断的Timer_A_initContinuousMode()函数介绍。

(4)把定时器的定时计数器,分频计数器的计数值清零。也就是计数器从0开始计数

(5)初始化之后立即启动定时器,否则需要之后再去使用Timer_A_startCounter()函数设置为连续计数模式启动定时器

(6)我们开启定时器2

    Timer_A_initContinuousModeParam htim = {0};
    htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;  //1048576Hz
    htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;  //一分频,1048576Hz
    htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;  //使能TAIE中断
    htim.timerClear = TIMER_A_DO_CLEAR;        //把定时器的定时计数器,分频计数器的计数值清零
    htim.startTimer = true;                 //初始化后立即启动定时器
    Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);  //设置为连续计数模式

捕获部分可选参数

captureRegister:选择所捕获引脚的CCRx,如果是CCR2就选择REGISTER_2
    TIMER_A_CAPTURECOMPARE_REGISTER_0
    TIMER_A_CAPTURECOMPARE_REGISTER_1
    TIMER_A_CAPTURECOMPARE_REGISTER_2
    TIMER_A_CAPTURECOMPARE_REGISTER_3
    TIMER_A_CAPTURECOMPARE_REGISTER_4
    TIMER_A_CAPTURECOMPARE_REGISTER_5
    TIMER_A_CAPTURECOMPARE_REGISTER_6

captureMode:选择捕获模式
    TIMER_A_CAPTUREMODE_NO_CAPTURE                 //不进行捕获
    TIMER_A_CAPTUREMODE_RISING_EDGE                //上升沿捕获
    TIMER_A_CAPTUREMODE_FALLING_EDGE               //下降沿捕获
    TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE    //双边沿捕获

captureInputSelect:选择捕获的CCIxA还是CCIxB
    TIMER_A_CAPTURE_INPUTSELECT_CCIxA     //如果是CCI2A,就选择这个。好像基本都是选择这个
    TIMER_A_CAPTURE_INPUTSELECT_CCIxB     //如果是CCI2B,就选择这个。这个好像是跟时钟有关的
    TIMER_A_CAPTURE_INPUTSELECT_GND
    TIMER_A_CAPTURE_INPUTSELECT_Vcc

synchronizeCaptureSource:捕获源是否与计时器同步,一般设置为同步
    TIMER_A_CAPTURE_ASYNCHRONOUS  //不同步
    TIMER_A_CAPTURE_SYNCHRONOUS   //同步

captureInterruptEnable:是启用或禁用定时器capturecompare中断
    TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE    //不进行定时器中断
    TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE     //开启定时器中断

captureOutputMode:指定输出模式
    TIMER_A_OUTPUTMODE_OUTBITVALUE    //因为是捕获模式,所以只能选择这个
    TIMER_A_OUTPUTMODE_SET
    TIMER_A_OUTPUTMODE_TOGGLE_RESET
    TIMER_A_OUTPUTMODE_SET_RESET
    TIMER_A_OUTPUTMODE_TOGGLE
    TIMER_A_OUTPUTMODE_RESET
    TIMER_A_OUTPUTMODE_TOGGLE_SET
    TIMER_A_OUTPUTMODE_RESET_SET

设置捕获引脚部分

(1)因为我们上面设置的是定时器2,所以我们需要查看引脚图。选择具有捕获功能的,又是定时器2的引脚。最后选择了P2.5脚。首先我们需要将他复用为输入,因为是要进行波形捕获。

msp430f5529捕获模式,MSP430F5529,单片机,嵌入式硬件

 (2)我们看引脚手册可知,P2.5对应的是定时器A的定时器2的CCR2,所以选择TIMER_A_CAPTURECOMPARE_REGISTER_2

(3)因为我们需要捕获高电平持续时间,所以需要捕获上升沿和下降沿

(4)因为是CCI2A所以选择INPUTSELECT_CCIxA,我查了一下手册,发现CCIxB好像都是跟时钟有关的东西。

(5)这个captureOutputMode是用于设置输出的。这个是PWM输出的时候才需要用到的,所以此处设置为TIMER_A_OUTPUTMODE_OUTBITVALUE,定时器输出电平由OUT位控制。详情看MSP430F5529库函数定时器A——硬件PWM比较输出模式部分。

    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);   //复用P2.5
    Timer_A_initCaptureModeParam capture_htim = {0};
    capture_htim.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;   //因为P2.5使用的是TA2.2,所以这里是REGISTER_2
    capture_htim.captureMode = TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE;  //选择双边沿触发
    capture_htim.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;     //因为是CCI2A所以选择INPUTSELECT_CCIxA
    capture_htim.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;     //捕获源与计时器时钟同步
    capture_htim.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;  //打开定时器捕获中断
    capture_htim.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;         //定时器输出电平由OUT位控制
    Timer_A_initCaptureMode(TIMER_A2_BASE,&capture_htim);

中断处理

因为我们采用的是定时器2的TALE中断,所以中断向量选择TIMER2_A1_VECTOR。

(1)首先我们需要知道,TAVE中断向量是具有多个中断源的。我们此刻是TA2.2,使用的是CCR2的中断源,所以需要一个TA2IV_TACCR2中断判断(如果上升沿或者下降沿就触发中断)。

(2)因为我们捕获的波形不可能是同一个定时周期里面,所以还需要一个TAVE中断,这样就不会因为高电平持续时间太长,导致无法计算

#pragma vector=TIMER2_A1_VECTOR
__interrupt
void TIMER2_A1_ISR (void)
{
    static uint16_t  Overflow_Times = 0;
    static uint16_t Sign_Begin = 0, Sign_End = 0;

    switch(TA2IV)
    {
        case TA2IV_TACCR2:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //获取P2.5引脚电平,如果为高电平,将当前寄存器值存入Sign_Begin
            {
                Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            }
            else             //获取P2.5引脚电平,如果为低电平,将当前寄存器值存入Sign_End
            {
                Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
                if(!Overflow_Times)    //计算高电平时间,如果高电平和低电平都在一个计数周期之内,进入
                    Sign_Counts = Sign_End - Sign_Begin;   //如果高低电平在同一个计数周期内,那么直接相减
                else                   //计算高电平时间,如果高电平和低电平不在一个计数周期之内,进入
                {
                    //注意,这里强制类型转换,是因为uint16_t 的最大值为65535,此处的Sign_Counts值会明显大于65535
                    Sign_Counts = (uint32_t)(65536 * Overflow_Times + Sign_End - Sign_Begin);  //如果高低电平不在同一个计数周期,需要先加上一个周期的计数值
                    Overflow_Times = 0;
                }
            }
            Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            break;
        case TA2IV_TAIFG:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //获取P2.5引脚电平。如果定时器都溢出中断了,现在还是高电平,那么表明高电平和低电平不在同一个定时周期内
            {
                ++Overflow_Times;
            }
            else  //获取P2.5引脚电平。如果定时器溢出中断了,现在不是高电平,那么表明高电平和低电平在同一个定时周期内
                Overflow_Times = 0;
            Timer_A_clearTimerInterrupt(TIMER_A2_BASE);
            break;
        default:
            break;
    }
}

如下为TAVE中断向量里面所含有的中断方式。 

#pragma vector=TIMER0_A1_VECTOR
__interrupt
void TIMER0_A1_ISR (void)
{
    switch(TA0IV)
    {
        case TA0IV_NONE:
            break;
        case TA0IV_TACCR1:
            break;
        case TA0IV_TACCR2:
            break;
        case TA0IV_TACCR3:
            break;
        case TA0IV_TACCR4:
            break;
        case TA0IV_5:
            break;
        case TA0IV_6:
            break;
        case TA0IV_TAIFG:
            GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN1);
            break;
        default:
            break;
    }
}

TA2IV_TACCR2解析

(1)首先是TA2IV_TACCR2中断,如果P2.5脚捕获到上升沿或者下降沿将会进入这里。我们先判断是上升沿还是下降沿,如果是上升沿,那么此时P2.5将会是高电平。我们将定时器的值存入Sign_Begin 中,程序中认为,高电平为信号起始

(2)如果现在P2.5为低电平,进入else语句,表示捕获已经结束了。将当前捕获的数据储存到,开始进行判断高电平和低电平是否在同一个定时周期内。

(3)如果Overflow_Times为0,那么表示高电平和低电平在同一定时周期,只需要把记录到的低电平时间减去高电平时间即可

(4)如果Overflow_Times不为0,那么高低电平不在同一定时周期。需要先让记录的低电平时间加上Overflow_Times(定时了几个周期)*65536 (定时器A为16位的定时器,16bit最大为65535,计数65536次,因为是从0开始计数),然后再减去记录的高电平时间即可。

        case TA2IV_TACCR2:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //获取P2.5引脚电平,如果为高电平,将当前寄存器值存入Sign_Begin
            {
                Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            }
            else             //获取P2.5引脚电平,如果为低电平,将当前寄存器值存入Sign_End
            {
                Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
                if(!Overflow_Times)    //计算高电平时间,如果高电平和低电平都在一个计数周期之内,进入
                    Sign_Counts = Sign_End - Sign_Begin;   //如果高低电平在同一个计数周期内,那么直接相减
                else                   //计算高电平时间,如果高电平和低电平不在一个计数周期之内,进入
                {
                    //注意,这里强制类型转换,是因为uint16_t 的最大值为65535,此处的Sign_Counts值会明显大于65535
                    Sign_Counts = (uint32_t)(65536 * Overflow_Times + Sign_End - Sign_Begin);  //如果高低电平不在同一个计数周期,需要先加上一个周期的计数值
                    Overflow_Times = 0;
                }
            }
            Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            break;

TA2IV_TAIFG解析

(1)因为捕获的波形高电平持续时间不一定会完整的被一共定时周期捕获,所以需要建立一个 Overflow_Times 来统计高电平到底跨越了几个定时周期。

(2)我们先判断P2.5引脚电平,如果P2.5为高电平,表示高电平还在持续,这个跨度超过了一共定时周期。

(3)如果现在P2.5为低电平,就说明高电平和低电平在同一个定时周期内。将Overflow_Times置0。

        case TA2IV_TAIFG:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //获取P2.5引脚电平。如果定时器都溢出中断了,现在还是高电平,那么表明高电平和低电平不在同一个定时周期内
            {
                ++Overflow_Times;
            }
            else  //获取P2.5引脚电平。如果定时器溢出中断了,现在不是高电平,那么表明高电平和低电平在同一个定时周期内
                Overflow_Times = 0;
            Timer_A_clearTimerInterrupt(TIMER_A2_BASE);
            break;

主函数解析

(1)我们需要关闭看门狗,否则你不即使喂狗,会导致程序一致复位——>执行一点点程序——>执行一点点程序。最后你调试的时候,会有一种程序卡死的感觉。

(2)打开捕获和串口,使能总中断。

(3)我们每过1S给电脑发送一次高电平持续时间。我们需要知道HZ,1S所变化的次数,如果时钟为1048576HZ,那么定时器+1,就是1/1048576秒。所以这里需要/1048576。因为这里是以ms为单位,所以需要乘以1000。如果我们不知道当前时钟的频率,可以使用UCS_getSMCLK()函数,获取当前SMCLK的频率。为什么是获取SMCLK的频率,是因为我们设置的定时器时钟源是SMCLK。

注意:1000后面一定一定要加一个小数点'.',因为/1048576之后,如果一个波形周期内,高电平持续时间<1S,那么算出来的值一定会小于1。如果是整型运算,那么结果一定会只是0!!!加上小数点'.'后,变成浮点运算。

    //关闭看门狗
    WDT_A_hold(WDT_A_BASE);
    //打开输入捕获
    Timer_A2_Capture_Init();
    Usart1_Init();
    //interrupts enabled
    __bis_SR_register(GIE);

    while(1)
    {
        delay_ms(1000);
        UART_printf(USCI_A1_BASE,"高电平持续时间:%f ms",1000.*Sign_Counts/1048576); //注意,这里1000后面必须+'.'表示是浮点运算!!!否则结果为0!!!
    }

实验现象

我用自己的手持式示波器产生一共100HZ的,占空比为50%的方波。给单片机测量,结果如下msp430f5529捕获模式,MSP430F5529,单片机,嵌入式硬件

 msp430f5529捕获模式,MSP430F5529,单片机,嵌入式硬件

 如果没有信号发生器,可以自己利用定时器产生一共PWM。不会的,可以看这位大佬的MSP430F5529 DriverLib 库函数学习笔记(五)定时器A,只需要看输入捕获模式测量脉宽长度部分即可。看我写的MSP430F5529库函数定时器A——硬件PWM,也可以。​​​​​​​文章来源地址https://www.toymoban.com/news/detail-545418.html

到了这里,关于MSP430F5529库函数定时器A——捕获实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MSP430F5529库函数——模数转换模块(ADC12)软件触发

    需提前观看:MSP430F5529库函数学习——串口   目录 代码 ADC初始化部分 引脚复位 ADC12_A_init() 函数声明 baseAddress sampleHoldSignalSourceSelect clockSourceSelec clockSourceDivider ADC12_A_enable() ADC12_A_setupSamplingTimer() ADC12_A_configureMemory() memoryBufferControlIndex  inputSourceSelect positiveRefVolta

    2024年02月16日
    浏览(49)
  • 【MSP430F5529基于库函数的学习】电赛速学及小车实战

    为电赛准备学习的MSP430笔记 提示:主要跟着这个大佬学的 一张经常要看的图 时钟配置和闪烁的LED 时钟系统结构 (1)5个时钟来源 时钟系统模块具有5个时钟来源。 ① XT1CLK:低频/高频振荡器,可以使用32768Hz的手表晶振、标准晶体、谐振器或4~32MHz的外部时钟源; ② VLOCLK:

    2024年02月12日
    浏览(46)
  • MSP430F5529 DriverLib 库函数学习笔记(一)时钟配置和闪烁LED

    平台:Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) (1)5个时钟来源         时钟系统模块具有5个时钟来源。 ① XT1CLK :低频/高频振荡器,可以使用32768Hz的手表晶振、标准晶体、谐振器或4~32MHz的外部时钟源; ② VLOCLK :内部超低功耗低频振荡

    2024年02月16日
    浏览(52)
  • MSP430F5529 DriverLib 库函数I2C驱动OLED屏幕

    平台:Code Composer Studio 10.4.0 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) P3.0为SDA,P3.1为SCL OLED.c OLED.h OLED_Font.h

    2024年02月15日
    浏览(36)
  • MSP430F5529学习笔记

    该MCU是由德州仪器TI生产的16位低功耗单片机 主要分以下型号: 专注低功耗的 1xx 通用型,配备1KB-60KB FLASH、512B-10KB RAM,工作时耗电仅达200uA/MIPS,RAM保持模式耗电0.1uA,RTC模式耗电0.7uA;可在6us之内快速唤醒。搭载10/12位斜率SAR ADC,集成模拟比较器、DMA、硬件乘法器、BOR、SV

    2024年02月15日
    浏览(117)
  • MSP430F5529——中断理解

    认识低功耗模式; MSP430的中断,需要两个部分,一部分是打开中断,另外一部分是编写中断服务函数 首先我们得知道__bis_SR_register和_BIS_SR是一个玩意。查看宏定义可知  _BIS_SR()可传入的参数 然后我们查看x的值,发现里面有八个可以传入的值 我们这里只需要关系GIE就可以

    2024年02月16日
    浏览(54)
  • 05:OLED模块【MSP430F5529】

    目录 实物图 字模取字         字模软件         取模步骤         1.设置软件         2.取模         3.输出数据  代码 type.h oledfont.h oled.h oled.c main.c 下面图片中,可以看到OLED模块的四个接口:GND,VCC,SCL,SDA GND VCC SCL SDA 接地 接电源3.3V/5V 接P3.5 接P3.6       

    2024年02月16日
    浏览(46)
  • msp430f5529学习笔记(2)时钟系统

    写在前~本章将会详细的讲解msp430f5529单片机的时钟系统及其使用方法。如有不妥的地方欢迎各位大佬斧正!!! 目录 什么是时钟系统和时钟源 MSP430f5529时钟源和时钟系统介绍 产生时钟信号的时钟源: 时钟配置        在单片机中,单片机每开始一个周期的工作就需要一个节

    2024年02月17日
    浏览(46)
  • MSP430F5529学习笔记(6)——导入MSP430Ware,查看例程

    MSP430WARE下载; 目录 在线版本 下载MSP430Ware 查看例程 导入例程  离线版本 下载MSP430Ware  查看例程 导入例程 MSP430Ware里面有很多例程和库函数使用手册,我们可以查看学习。非常重要 (1) 打开CCS——view——Resource Explorer  之后我们会进入如下界面 (2)  点击MSP430——Embe

    2024年02月13日
    浏览(54)
  • 06:PWM与电机驱动【MSP430F5529】

    电机型号: 工作方式: 原理图以及接线: 根据官方例程,主要代码为drive.c drive.h main.c (后面好像使用的时候会有什么冲突导致1或者2通道无法正常运行,不太记得了,可以到实物上实验一下子) 下面是智能送药小车使用PWM驱动电机相关代码与注释(在实物中,均能正常运行)

    2024年02月15日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包