MSP432 Interrupt_disableSleepOnIsrExit();

 Interrupt_disableSleepOnIsrExit();

systickやタイマー、ADCなどでインターラプトをかけ、ハンドラーへ飛び処理をする。

Interrupt_disableSleepOnIsrExit();を置くのを忘れて、いつもハマるのでメモ。

これを置かないと、ハンドラーに入るとmainに戻ってこない。戻すため、 Interrupt_disableSleepOnIsrExit();ハンドラーの処理が終わったらこの命令を置いておく。

********************

動作の確認

Resource Exploerから検索でsystickを入れて、DriverLibのサンプルプログラムをインポートする。リネームするなりして、これを送り込んで動作を確認しておく。オンボードのLEDがチカチカと。

ここからが動作の確認。
Printfを使いたいので、以前の手順でprintfOverride.cをコピーしておく。詳しい手順はここ

#include <stdio.h>//printf
を他のインクルードに続けて追加する。その後mainの上の箇所で、変数を一つ定義しておく。
uint8_t count=0;
UARTを使えるように、
const eUSCI_UART_ConfigV1 uartConfig =
{
        EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        78,                                     // BRDIV = 78
        2,                                       // UCxBRF = 2
        0,                                       // UCxBRS = 0
        EUSCI_A_UART_NO_PARITY,                  // No Parity
        EUSCI_A_UART_LSB_FIRST,                  // LSB First
        EUSCI_A_UART_ONE_STOP_BIT,               // One stop bit
        EUSCI_A_UART_MODE,                       // UART mode
        EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION,  // Oversampling
        EUSCI_A_UART_8_BIT_LEN                  // 8 bit data length
};
で設定をする。main関数の中で、
    /* Setting DCO to 12MHz */
    CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
DCOのクロックを12MHzに変更し、UARTのピンアサイン等使えるようにする

    /* Selecting P1.2 and P1.3 in UART mode */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
       /* Configuring UART Module */
          MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
          /* Enable UART module */
          MAP_UART_enableModule(EUSCI_A0_BASE);

          /* Enabling interrupts */
          MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
          MAP_Interrupt_enableInterrupt(INT_EUSCIA0);

また、クロックを変更したので、
MAP_SysTick_setPeriod(12000000);// 16,777,216
を12Mにする。これで1秒間LEDが点灯して、1秒消える動作をする。
その状態で次にmainの中のwhile の部分を編集して
    while (1)
    {
        printf("count:%d\n", count);
    }
続いて、SysTick_Handlerの中を編集する。
void SysTick_Handler(void)
{
    MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
    if(count=7){count=0;}
    count=count+1;  
}
これで動作的には、countがインクリメントして、シリアルモニターに表示されるはず・・・ところが、点滅はするものの、printfでシリアルには何も表示されない。
つまり、whileのところが実行されない。点滅していることからハンドラーは呼び出されるが、ハンドラーに行ったっきりになる。

void SysTick_Handler(void)
{
    MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);

    if(count==8){count=0;}
    count=count+1;
    MAP_Interrupt_disableSleepOnIsrExit();
}
そこで、1行追加。

今度は、whileの中をぐるぐるまわって、1秒立つとハンドラーに飛んで、countがインクリメント、ハンドラーを抜けて、whileの処理を続けて1秒経過すると、またハンドラーに割り込みをかけるという動作になる。

以下は改造後のソース。
/* --COPYRIGHT--,BSD
 * Copyright (c) 2017, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
/*******************************************************************************
 * MSP432 SysTick - Blink LED Program
 *
 * Description: This program will use the SysTick module to blink an LED with
 * a one second period. Once setup, the application will go into LPM3
 * mode and only wake up to toggle the GPIO pin.
 *
 * This program runs infinitely until manually halted by the user.
 *
 *                MSP432P401
 *             ------------------
 *         /|\|                  |
 *          | |                  |
 *          --|RST         P1.0  |---> P1.0 LED
 *            |                  |
 *            |                  |
 *            |                  |
 *            |                  |
 *            |                  |
 *
  *******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>//printf

uint8_t count=0;
/* UART Configuration Parameter. These are the configuration parameters to
 * make the eUSCI A UART module to operate with a 9600 baud rate. These
 * values were calculated using the online calculator that TI provides
 * at:
 *http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
 */
const eUSCI_UART_ConfigV1 uartConfig =
{
        EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        78,                                     // BRDIV = 78
        2,                                       // UCxBRF = 2
        0,                                       // UCxBRS = 0
        EUSCI_A_UART_NO_PARITY,                  // No Parity
        EUSCI_A_UART_LSB_FIRST,                  // LSB First
        EUSCI_A_UART_ONE_STOP_BIT,               // One stop bit
        EUSCI_A_UART_MODE,                       // UART mode
        EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION,  // Oversampling
        EUSCI_A_UART_8_BIT_LEN                  // 8 bit data length
};


//![Simple SysTick Example]
int main(void)
{
    /* Halting the Watchdog */
    MAP_WDT_A_holdTimer();
    /* Setting DCO to 12MHz */
    CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
    /* Configuring GPIO as an output */
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);

    /* Selecting P1.2 and P1.3 in UART mode */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);


       /* Configuring UART Module */
          MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);

          /* Enable UART module */
          MAP_UART_enableModule(EUSCI_A0_BASE);

          /* Enabling interrupts */
          MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
          MAP_Interrupt_enableInterrupt(INT_EUSCIA0);

    /* Configuring SysTick to trigger at 1500000 (MCLK is 1.5MHz so this will 
     * make it toggle every 1s) */
    MAP_SysTick_enableModule();
    MAP_SysTick_setPeriod(12000000);// 16,777,216
    MAP_Interrupt_enableSleepOnIsrExit();
    MAP_SysTick_enableInterrupt();
    
    /* Enabling MASTER interrupts */
    MAP_Interrupt_enableMaster();

    while (1)
    {
        printf("count:%d\n", count);
    }
}

void SysTick_Handler(void)
{
    MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);

    if(count==8){count=0;}
    count=count+1;
    MAP_Interrupt_disableSleepOnIsrExit();
}
//![Simple SysTick Example]








コメント

このブログの人気の投稿

Attiny85とAQM0802A(LCD)のI2C接続

ILI9341 240X320 Arduino

Attiny85 FuseRest