国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MSP430F5529庫函數(shù)定時(shí)器A——捕獲實(shí)驗(yàn)

這篇具有很好參考價(jià)值的文章主要介紹了MSP430F5529庫函數(shù)定時(shí)器A——捕獲實(shí)驗(yàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

需提前學(xué)習(xí):MSP430F5529庫函數(shù)學(xué)習(xí)——串口;MSP430F5529庫函數(shù)定時(shí)器A——硬件PWM

目錄

引腳手冊(cè)獲取

實(shí)驗(yàn)?zāi)康?/p>

代碼

代碼解析

串口數(shù)據(jù)發(fā)送部分

數(shù)據(jù)捕獲部分

定時(shí)器部分可選參數(shù)

設(shè)置定時(shí)器部分

捕獲部分可選參數(shù)

設(shè)置捕獲引腳部分

中斷處理

TA2IV_TACCR2解析

TA2IV_TAIFG解析

主函數(shù)解析

實(shí)驗(yàn)現(xiàn)象


引腳手冊(cè)獲取

詳情看MSP430F5529庫函數(shù)定時(shí)器A——硬件PWM獲取引腳手冊(cè)部分。

實(shí)驗(yàn)?zāi)康?/h2>

捕獲波形高電平持續(xù)時(shí)間

代碼

MSP430F5529可以進(jìn)行信號(hào)捕獲。先提供代碼

#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;   //無校驗(yàn)位
    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;        //把定時(shí)器的定時(shí)計(jì)數(shù)器,分頻計(jì)數(shù)器的計(jì)數(shù)值清零
    htim.startTimer = true;                 //初始化后立即啟動(dòng)定時(shí)器
    Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);  //設(shè)置為連續(xù)計(jì)數(shù)模式

    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);   //復(fù)用P2.5
    Timer_A_initCaptureModeParam capture_htim = {0};
    capture_htim.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;   //因?yàn)镻2.5使用的是TA2.2,所以這里是REGISTER_2
    capture_htim.captureMode = TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE;  //選擇雙邊沿觸發(fā)
    capture_htim.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;     //
    capture_htim.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;     //捕獲源與計(jì)時(shí)器時(shí)鐘同步
    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)
{
    //關(guān)閉看門狗
    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,"高電平持續(xù)時(shí)間:%f ms",1000.*Sign_Counts/1048576); //注意,這里1000后面必須+'.'表示是浮點(diǎn)運(yùn)算?。。》駝t結(jié)果為0?。?!
        UART_printf(USCI_A1_BASE,"高電平持續(xù)時(shí)間:%f ms",1000.*Sign_Counts/UCS_getSMCLK());//UCS_getSMCLK是獲取當(dāng)前SMCLK時(shí)鐘頻率,當(dāng)前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引腳電平,如果為高電平,將當(dāng)前寄存器值存入Sign_Begin
            {
                Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            }
            else             //獲取P2.5引腳電平,如果為低電平,將當(dāng)前寄存器值存入Sign_End
            {
                Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
                if(!Overflow_Times)    //計(jì)算高電平時(shí)間,如果高電平和低電平都在一個(gè)計(jì)數(shù)周期之內(nèi),進(jìn)入
                    Sign_Counts = Sign_End - Sign_Begin;   //如果高低電平在同一個(gè)計(jì)數(shù)周期內(nèi),那么直接相減
                else                   //計(jì)算高電平時(shí)間,如果高電平和低電平不在一個(gè)計(jì)數(shù)周期之內(nèi),進(jìn)入
                {
                    //注意,這里強(qiáng)制類型轉(zhuǎn)換,是因?yàn)閡int16_t 的最大值為65535,此處的Sign_Counts值會(huì)明顯大于65535
                    Sign_Counts = (uint32_t)(65536 * Overflow_Times + Sign_End - Sign_Begin);  //如果高低電平不在同一個(gè)計(jì)數(shù)周期,需要先加上一個(gè)周期的計(jì)數(shù)值
                    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引腳電平。如果定時(shí)器都溢出中斷了,現(xiàn)在還是高電平,那么表明高電平和低電平不在同一個(gè)定時(shí)周期內(nèi)
            {
                ++Overflow_Times;
            }
            else  //獲取P2.5引腳電平。如果定時(shí)器溢出中斷了,現(xiàn)在不是高電平,那么表明高電平和低電平在同一個(gè)定時(shí)周期內(nèi)
                Overflow_Times = 0;
            Timer_A_clearTimerInterrupt(TIMER_A2_BASE);
            break;
        default:
            break;
    }
}

代碼解析

串口數(shù)據(jù)發(fā)送部分

注意,這部分我就提醒一下。我們是需要進(jìn)行浮點(diǎn)數(shù)據(jù)打印的,所以我們看MSP430F5529庫函數(shù)學(xué)習(xí)——串口的時(shí)候,需要按照浮點(diǎn)數(shù)據(jù)打印這一部分配置!

數(shù)據(jù)捕獲部分

定時(shí)器部分可選參數(shù)

(1)clockSource:選擇時(shí)鐘源  
  TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
  TIMER_A_CLOCKSOURCE_ACLK
  TIMER_A_CLOCKSOURCE_SMCLK
  TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
 
(2)clockSourceDivider:選擇時(shí)鐘分頻次數(shù)
 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:使能還是失能定時(shí)器中斷
  TIMER_A_TAIE_INTERRUPT_ENABLE  //使能定時(shí)器中斷
  TIMER_A_TAIE_INTERRUPT_DISABLE  //失能定時(shí)器中斷
 
 
(4)timerClear:選擇是否把定時(shí)器的定時(shí)計(jì)數(shù)器,分頻計(jì)數(shù)器的計(jì)數(shù)值清零
  TIMER_A_DO_CLEAR      //清除
  TIMER_A_SKIP_CLEAR    //不清除
 
(5)startTimer:選擇初始化之后是否立即啟動(dòng)定時(shí)器
    true   //初始化后立即啟動(dòng)定時(shí)器
    false  //初始化后不啟動(dòng)定時(shí)器
 

設(shè)置定時(shí)器部分

(1)MSP430F5529定時(shí)器時(shí)鐘 TACLK 可以選擇?ACLK,SMCLK?或者來自外部的?TAxCLK。SMCLK系統(tǒng)默認(rèn)?1048576Hz,ACLK系統(tǒng)默認(rèn)為32768Hz。這里我們選擇SMCLK作為時(shí)鐘源

(2)不進(jìn)行分頻,因?yàn)槿绻M(jìn)行輸入捕獲,頻率越高,精確度越大。

(3)因?yàn)閿?shù)據(jù)捕獲實(shí)驗(yàn)是采用的連續(xù)計(jì)數(shù)模式,所以只能使用TAIE中斷。詳情請(qǐng)看MSP430F5529庫函數(shù)定時(shí)器A——定時(shí)中斷的Timer_A_initContinuousMode()函數(shù)介紹。

(4)把定時(shí)器的定時(shí)計(jì)數(shù)器,分頻計(jì)數(shù)器的計(jì)數(shù)值清零。也就是計(jì)數(shù)器從0開始計(jì)數(shù)

(5)初始化之后立即啟動(dòng)定時(shí)器,否則需要之后再去使用Timer_A_startCounter()函數(shù)設(shè)置為連續(xù)計(jì)數(shù)模式啟動(dòng)定時(shí)器

(6)我們開啟定時(shí)器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;        //把定時(shí)器的定時(shí)計(jì)數(shù)器,分頻計(jì)數(shù)器的計(jì)數(shù)值清零
    htim.startTimer = true;                 //初始化后立即啟動(dòng)定時(shí)器
    Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);  //設(shè)置為連續(xù)計(jì)數(shù)模式

捕獲部分可選參數(shù)

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                 //不進(jìn)行捕獲
    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,就選擇這個(gè)。好像基本都是選擇這個(gè)
    TIMER_A_CAPTURE_INPUTSELECT_CCIxB     //如果是CCI2B,就選擇這個(gè)。這個(gè)好像是跟時(shí)鐘有關(guān)的
    TIMER_A_CAPTURE_INPUTSELECT_GND
    TIMER_A_CAPTURE_INPUTSELECT_Vcc

synchronizeCaptureSource:捕獲源是否與計(jì)時(shí)器同步,一般設(shè)置為同步
    TIMER_A_CAPTURE_ASYNCHRONOUS  //不同步
    TIMER_A_CAPTURE_SYNCHRONOUS   //同步

captureInterruptEnable:是啟用或禁用定時(shí)器capturecompare中斷
    TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE    //不進(jìn)行定時(shí)器中斷
    TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE     //開啟定時(shí)器中斷

captureOutputMode:指定輸出模式
    TIMER_A_OUTPUTMODE_OUTBITVALUE    //因?yàn)槭遣东@模式,所以只能選擇這個(gè)
    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

設(shè)置捕獲引腳部分

(1)因?yàn)槲覀兩厦嬖O(shè)置的是定時(shí)器2,所以我們需要查看引腳圖。選擇具有捕獲功能的,又是定時(shí)器2的引腳。最后選擇了P2.5腳。首先我們需要將他復(fù)用為輸入,因?yàn)槭且M(jìn)行波形捕獲。

msp430f5529捕獲模式,MSP430F5529,單片機(jī),嵌入式硬件

?(2)我們看引腳手冊(cè)可知,P2.5對(duì)應(yīng)的是定時(shí)器A的定時(shí)器2的CCR2,所以選擇TIMER_A_CAPTURECOMPARE_REGISTER_2

(3)因?yàn)槲覀冃枰东@高電平持續(xù)時(shí)間,所以需要捕獲上升沿和下降沿

(4)因?yàn)槭荂CI2A所以選擇INPUTSELECT_CCIxA,我查了一下手冊(cè),發(fā)現(xiàn)CCIxB好像都是跟時(shí)鐘有關(guān)的東西。

(5)這個(gè)captureOutputMode是用于設(shè)置輸出的。這個(gè)是PWM輸出的時(shí)候才需要用到的,所以此處設(shè)置為TIMER_A_OUTPUTMODE_OUTBITVALUE,定時(shí)器輸出電平由OUT位控制。詳情看MSP430F5529庫函數(shù)定時(shí)器A——硬件PWM比較輸出模式部分。

    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);   //復(fù)用P2.5
    Timer_A_initCaptureModeParam capture_htim = {0};
    capture_htim.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;   //因?yàn)镻2.5使用的是TA2.2,所以這里是REGISTER_2
    capture_htim.captureMode = TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE;  //選擇雙邊沿觸發(fā)
    capture_htim.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;     //因?yàn)槭荂CI2A所以選擇INPUTSELECT_CCIxA
    capture_htim.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;     //捕獲源與計(jì)時(shí)器時(shí)鐘同步
    capture_htim.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;  //打開定時(shí)器捕獲中斷
    capture_htim.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;         //定時(shí)器輸出電平由OUT位控制
    Timer_A_initCaptureMode(TIMER_A2_BASE,&capture_htim);

中斷處理

因?yàn)槲覀儾捎玫氖嵌〞r(shí)器2的TALE中斷,所以中斷向量選擇TIMER2_A1_VECTOR。

(1)首先我們需要知道,TAVE中斷向量是具有多個(gè)中斷源的。我們此刻是TA2.2,使用的是CCR2的中斷源,所以需要一個(gè)TA2IV_TACCR2中斷判斷(如果上升沿或者下降沿就觸發(fā)中斷)。

(2)因?yàn)槲覀儾东@的波形不可能是同一個(gè)定時(shí)周期里面,所以還需要一個(gè)TAVE中斷,這樣就不會(huì)因?yàn)楦唠娖匠掷m(xù)時(shí)間太長,導(dǎo)致無法計(jì)算

#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引腳電平,如果為高電平,將當(dāng)前寄存器值存入Sign_Begin
            {
                Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            }
            else             //獲取P2.5引腳電平,如果為低電平,將當(dāng)前寄存器值存入Sign_End
            {
                Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
                if(!Overflow_Times)    //計(jì)算高電平時(shí)間,如果高電平和低電平都在一個(gè)計(jì)數(shù)周期之內(nèi),進(jìn)入
                    Sign_Counts = Sign_End - Sign_Begin;   //如果高低電平在同一個(gè)計(jì)數(shù)周期內(nèi),那么直接相減
                else                   //計(jì)算高電平時(shí)間,如果高電平和低電平不在一個(gè)計(jì)數(shù)周期之內(nèi),進(jìn)入
                {
                    //注意,這里強(qiáng)制類型轉(zhuǎn)換,是因?yàn)閡int16_t 的最大值為65535,此處的Sign_Counts值會(huì)明顯大于65535
                    Sign_Counts = (uint32_t)(65536 * Overflow_Times + Sign_End - Sign_Begin);  //如果高低電平不在同一個(gè)計(jì)數(shù)周期,需要先加上一個(gè)周期的計(jì)數(shù)值
                    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引腳電平。如果定時(shí)器都溢出中斷了,現(xiàn)在還是高電平,那么表明高電平和低電平不在同一個(gè)定時(shí)周期內(nèi)
            {
                ++Overflow_Times;
            }
            else  //獲取P2.5引腳電平。如果定時(shí)器溢出中斷了,現(xiàn)在不是高電平,那么表明高電平和低電平在同一個(gè)定時(shí)周期內(nèi)
                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腳捕獲到上升沿或者下降沿將會(huì)進(jìn)入這里。我們先判斷是上升沿還是下降沿,如果是上升沿,那么此時(shí)P2.5將會(huì)是高電平。我們將定時(shí)器的值存入Sign_Begin 中,程序中認(rèn)為,高電平為信號(hào)起始。

(2)如果現(xiàn)在P2.5為低電平,進(jìn)入else語句,表示捕獲已經(jīng)結(jié)束了。將當(dāng)前捕獲的數(shù)據(jù)儲(chǔ)存到,開始進(jìn)行判斷高電平和低電平是否在同一個(gè)定時(shí)周期內(nèi)。

(3)如果Overflow_Times為0,那么表示高電平和低電平在同一定時(shí)周期,只需要把記錄到的低電平時(shí)間減去高電平時(shí)間即可

(4)如果Overflow_Times不為0,那么高低電平不在同一定時(shí)周期。需要先讓記錄的低電平時(shí)間加上Overflow_Times(定時(shí)了幾個(gè)周期)*65536 (定時(shí)器A為16位的定時(shí)器,16bit最大為65535,計(jì)數(shù)65536次,因?yàn)槭菑?開始計(jì)數(shù)),然后再減去記錄的高電平時(shí)間即可。

        case TA2IV_TACCR2:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //獲取P2.5引腳電平,如果為高電平,將當(dāng)前寄存器值存入Sign_Begin
            {
                Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            }
            else             //獲取P2.5引腳電平,如果為低電平,將當(dāng)前寄存器值存入Sign_End
            {
                Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
                if(!Overflow_Times)    //計(jì)算高電平時(shí)間,如果高電平和低電平都在一個(gè)計(jì)數(shù)周期之內(nèi),進(jìn)入
                    Sign_Counts = Sign_End - Sign_Begin;   //如果高低電平在同一個(gè)計(jì)數(shù)周期內(nèi),那么直接相減
                else                   //計(jì)算高電平時(shí)間,如果高電平和低電平不在一個(gè)計(jì)數(shù)周期之內(nèi),進(jìn)入
                {
                    //注意,這里強(qiáng)制類型轉(zhuǎn)換,是因?yàn)閡int16_t 的最大值為65535,此處的Sign_Counts值會(huì)明顯大于65535
                    Sign_Counts = (uint32_t)(65536 * Overflow_Times + Sign_End - Sign_Begin);  //如果高低電平不在同一個(gè)計(jì)數(shù)周期,需要先加上一個(gè)周期的計(jì)數(shù)值
                    Overflow_Times = 0;
                }
            }
            Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
            break;

TA2IV_TAIFG解析

(1)因?yàn)椴东@的波形高電平持續(xù)時(shí)間不一定會(huì)完整的被一共定時(shí)周期捕獲,所以需要建立一個(gè)?Overflow_Times 來統(tǒng)計(jì)高電平到底跨越了幾個(gè)定時(shí)周期。

(2)我們先判斷P2.5引腳電平,如果P2.5為高電平,表示高電平還在持續(xù),這個(gè)跨度超過了一共定時(shí)周期。

(3)如果現(xiàn)在P2.5為低電平,就說明高電平和低電平在同一個(gè)定時(shí)周期內(nèi)。將Overflow_Times置0。

        case TA2IV_TAIFG:
            if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5))  //獲取P2.5引腳電平。如果定時(shí)器都溢出中斷了,現(xiàn)在還是高電平,那么表明高電平和低電平不在同一個(gè)定時(shí)周期內(nèi)
            {
                ++Overflow_Times;
            }
            else  //獲取P2.5引腳電平。如果定時(shí)器溢出中斷了,現(xiàn)在不是高電平,那么表明高電平和低電平在同一個(gè)定時(shí)周期內(nèi)
                Overflow_Times = 0;
            Timer_A_clearTimerInterrupt(TIMER_A2_BASE);
            break;

主函數(shù)解析

(1)我們需要關(guān)閉看門狗,否則你不即使喂狗,會(huì)導(dǎo)致程序一致復(fù)位——>執(zhí)行一點(diǎn)點(diǎn)程序——>執(zhí)行一點(diǎn)點(diǎn)程序。最后你調(diào)試的時(shí)候,會(huì)有一種程序卡死的感覺。

(2)打開捕獲和串口,使能總中斷。

(3)我們每過1S給電腦發(fā)送一次高電平持續(xù)時(shí)間。我們需要知道HZ,1S所變化的次數(shù),如果時(shí)鐘為1048576HZ,那么定時(shí)器+1,就是1/1048576秒。所以這里需要/1048576。因?yàn)檫@里是以ms為單位,所以需要乘以1000。如果我們不知道當(dāng)前時(shí)鐘的頻率,可以使用UCS_getSMCLK()函數(shù),獲取當(dāng)前SMCLK的頻率。為什么是獲取SMCLK的頻率,是因?yàn)槲覀冊(cè)O(shè)置的定時(shí)器時(shí)鐘源是SMCLK。

注意:1000后面一定一定要加一個(gè)小數(shù)點(diǎn)'.',因?yàn)?1048576之后,如果一個(gè)波形周期內(nèi),高電平持續(xù)時(shí)間<1S,那么算出來的值一定會(huì)小于1。如果是整型運(yùn)算,那么結(jié)果一定會(huì)只是0?。。〖由闲?shù)點(diǎn)'.'后,變成浮點(diǎn)運(yùn)算。

    //關(guān)閉看門狗
    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,"高電平持續(xù)時(shí)間:%f ms",1000.*Sign_Counts/1048576); //注意,這里1000后面必須+'.'表示是浮點(diǎn)運(yùn)算!?。》駝t結(jié)果為0?。?!
    }

實(shí)驗(yàn)現(xiàn)象

我用自己的手持式示波器產(chǎn)生一共100HZ的,占空比為50%的方波。給單片機(jī)測量,結(jié)果如下msp430f5529捕獲模式,MSP430F5529,單片機(jī),嵌入式硬件

?msp430f5529捕獲模式,MSP430F5529,單片機(jī),嵌入式硬件

?如果沒有信號(hào)發(fā)生器,可以自己利用定時(shí)器產(chǎn)生一共PWM。不會(huì)的,可以看這位大佬的MSP430F5529 DriverLib 庫函數(shù)學(xué)習(xí)筆記(五)定時(shí)器A,只需要看輸入捕獲模式測量脈寬長度部分即可??次覍懙腗SP430F5529庫函數(shù)定時(shí)器A——硬件PWM,也可以。???????文章來源地址http://www.zghlxwxcb.cn/news/detail-545418.html

到了這里,關(guān)于MSP430F5529庫函數(shù)定時(shí)器A——捕獲實(shí)驗(yàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • MSP430F5529庫函數(shù)——模數(shù)轉(zhuǎn)換模塊(ADC12)軟件觸發(fā)

    MSP430F5529庫函數(shù)——模數(shù)轉(zhuǎn)換模塊(ADC12)軟件觸發(fā)

    需提前觀看:MSP430F5529庫函數(shù)學(xué)習(xí)——串口 ? 目錄 代碼 ADC初始化部分 引腳復(fù)位 ADC12_A_init() 函數(shù)聲明 baseAddress sampleHoldSignalSourceSelect clockSourceSelec clockSourceDivider ADC12_A_enable() ADC12_A_setupSamplingTimer() ADC12_A_configureMemory() memoryBufferControlIndex ?inputSourceSelect positiveRefVolta

    2024年02月16日
    瀏覽(27)
  • 【MSP430F5529基于庫函數(shù)的學(xué)習(xí)】電賽速學(xué)及小車實(shí)戰(zhàn)

    【MSP430F5529基于庫函數(shù)的學(xué)習(xí)】電賽速學(xué)及小車實(shí)戰(zhàn)

    為電賽準(zhǔn)備學(xué)習(xí)的MSP430筆記 提示:主要跟著這個(gè)大佬學(xué)的 一張經(jīng)常要看的圖 時(shí)鐘配置和閃爍的LED 時(shí)鐘系統(tǒng)結(jié)構(gòu) (1)5個(gè)時(shí)鐘來源 時(shí)鐘系統(tǒng)模塊具有5個(gè)時(shí)鐘來源。 ① XT1CLK:低頻/高頻振蕩器,可以使用32768Hz的手表晶振、標(biāo)準(zhǔn)晶體、諧振器或4~32MHz的外部時(shí)鐘源; ② VLOCLK:

    2024年02月12日
    瀏覽(22)
  • MSP430F5529 DriverLib 庫函數(shù)學(xué)習(xí)筆記(一)時(shí)鐘配置和閃爍LED

    MSP430F5529 DriverLib 庫函數(shù)學(xué)習(xí)筆記(一)時(shí)鐘配置和閃爍LED

    平臺(tái):Code Composer Studio 10.3.1 MSP430F5529 LaunchPad? Development Kit (MSP?EXP430F5529LP) (1)5個(gè)時(shí)鐘來源 ????????時(shí)鐘系統(tǒng)模塊具有5個(gè)時(shí)鐘來源。 ① XT1CLK :低頻/高頻振蕩器,可以使用32768Hz的手表晶振、標(biāo)準(zhǔn)晶體、諧振器或4~32MHz的外部時(shí)鐘源; ② VLOCLK :內(nèi)部超低功耗低頻振蕩

    2024年02月16日
    瀏覽(21)
  • MSP430F5529 DriverLib 庫函數(shù)I2C驅(qū)動(dòng)OLED屏幕

    MSP430F5529 DriverLib 庫函數(shù)I2C驅(qū)動(dòng)OLED屏幕

    平臺(tái):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日
    瀏覽(25)
  • MSP430F5529——中斷理解

    MSP430F5529——中斷理解

    認(rèn)識(shí)低功耗模式; MSP430的中斷,需要兩個(gè)部分,一部分是打開中斷,另外一部分是編寫中斷服務(wù)函數(shù) 首先我們得知道__bis_SR_register和_BIS_SR是一個(gè)玩意。查看宏定義可知 ?_BIS_SR()可傳入的參數(shù) 然后我們查看x的值,發(fā)現(xiàn)里面有八個(gè)可以傳入的值 我們這里只需要關(guān)系GIE就可以

    2024年02月16日
    瀏覽(32)
  • MSP430F5529學(xué)習(xí)筆記

    該MCU是由德州儀器TI生產(chǎn)的16位低功耗單片機(jī) 主要分以下型號(hào): 專注低功耗的 1xx 通用型,配備1KB-60KB FLASH、512B-10KB RAM,工作時(shí)耗電僅達(dá)200uA/MIPS,RAM保持模式耗電0.1uA,RTC模式耗電0.7uA;可在6us之內(nèi)快速喚醒。搭載10/12位斜率SAR ADC,集成模擬比較器、DMA、硬件乘法器、BOR、SV

    2024年02月15日
    瀏覽(28)
  • 05:OLED模塊【MSP430F5529】

    05:OLED模塊【MSP430F5529】

    目錄 實(shí)物圖 字模取字 ????????字模軟件 ? ? ? ? 取模步驟 ????????1.設(shè)置軟件 ????????2.取模 ????????3.輸出數(shù)據(jù) ?代碼 type.h oledfont.h oled.h oled.c main.c 下面圖片中,可以看到OLED模塊的四個(gè)接口:GND,VCC,SCL,SDA GND VCC SCL SDA 接地 接電源3.3V/5V 接P3.5 接P3.6 ??????

    2024年02月16日
    瀏覽(29)
  • msp430f5529學(xué)習(xí)筆記(2)時(shí)鐘系統(tǒng)

    msp430f5529學(xué)習(xí)筆記(2)時(shí)鐘系統(tǒng)

    寫在前~本章將會(huì)詳細(xì)的講解msp430f5529單片機(jī)的時(shí)鐘系統(tǒng)及其使用方法。如有不妥的地方歡迎各位大佬斧正?。?! 目錄 什么是時(shí)鐘系統(tǒng)和時(shí)鐘源 MSP430f5529時(shí)鐘源和時(shí)鐘系統(tǒng)介紹 產(chǎn)生時(shí)鐘信號(hào)的時(shí)鐘源: 時(shí)鐘配置 ? ? ? ?在單片機(jī)中,單片機(jī)每開始一個(gè)周期的工作就需要一個(gè)節(jié)

    2024年02月17日
    瀏覽(21)
  • MSP430F5529學(xué)習(xí)筆記(6)——導(dǎo)入MSP430Ware,查看例程

    MSP430F5529學(xué)習(xí)筆記(6)——導(dǎo)入MSP430Ware,查看例程

    MSP430WARE下載; 目錄 在線版本 下載MSP430Ware 查看例程 導(dǎo)入例程? 離線版本 下載MSP430Ware ?查看例程 導(dǎo)入例程 MSP430Ware里面有很多例程和庫函數(shù)使用手冊(cè),我們可以查看學(xué)習(xí)。非常重要 (1) 打開CCS——view——Resource Explorer ?之后我們會(huì)進(jìn)入如下界面 (2) ?點(diǎn)擊MSP430——Embe

    2024年02月13日
    瀏覽(26)
  • 06:PWM與電機(jī)驅(qū)動(dòng)【MSP430F5529】

    電機(jī)型號(hào): 工作方式: 原理圖以及接線: 根據(jù)官方例程,主要代碼為drive.c drive.h main.c (后面好像使用的時(shí)候會(huì)有什么沖突導(dǎo)致1或者2通道無法正常運(yùn)行,不太記得了,可以到實(shí)物上實(shí)驗(yàn)一下子) 下面是智能送藥小車使用PWM驅(qū)動(dòng)電機(jī)相關(guān)代碼與注釋(在實(shí)物中,均能正常運(yùn)行)

    2024年02月15日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包