S32K144 EVB之外部中断

开发环境

IAR7.8 + S32K144-EVB

这次采用了裸机编程,时钟初始化的代码是从SDK中摘取出来的
由于硬件电路上已经采用在下拉时采用并联电容的方式进行消抖处理
本次的DEMO便可使用SW2和SW3按键通过中断来控制LED灯颜色变化:

#include "S32K144.h"
#include "S32K144_features.h"

#define RED     15
#define GREEN   16
#define BLUE    0

#define BTN0    12
#define BTN1    13
#define BIT(n)  (1 << (n))

typedef unsigned char   u8;
typedef unsigned short  u16;
typedef unsigned long   u32;

typedef enum
{
        false = 0,
        true,
} bool;

typedef enum
{
        CLK_SRC_OFF   = 0x00U,             /* Clock is off */
        CLK_SRC_SOSC  = 0x01U,             /* OSCCLK - System Oscillator Bus Clock */
        CLK_SRC_SIRC  = 0x02U,             /* SCGIRCLK - Slow IRC Clock */
        CLK_SRC_FIRC  = 0x03U,             /* SCGFIRCLK - Fast IRC Clock */
        CLK_SRC_SPLL  = 0x06U              /* SCGPCLK System PLL clock */

} peripheral_clock_source_t;

const u16 clockNameMappings[] = PCC_CLOCK_NAME_MAPPINGS;

static inline void PCC_HAL_SetClockMode(PCC_Type* const base, const clock_names_t clockName, const bool isClockEnabled)
{
    u32 regValue = (u32)base->PCCn[clockNameMappings[clockName]];
    regValue &= (u32)(~(PCC_PCCn_CGC_MASK));
    regValue |= PCC_PCCn_CGC((isClockEnabled == true) ? 1UL : 0UL);
    base->PCCn[clockNameMappings[clockName]] = (u32)regValue;
}

static inline void PCC_HAL_SetClockSourceSel(PCC_Type* const base, const clock_names_t clockName, const peripheral_clock_source_t clockSource)
{
    u32 clkSource, regValue;

    switch(clockSource)
    {
        case CLK_SRC_SPLL:
            clkSource = 6U;
            break;
        case CLK_SRC_FIRC:
            clkSource = 3U;
            break;
        case CLK_SRC_SIRC:
            clkSource = 2U;
            break;
        case CLK_SRC_SOSC:
            clkSource = 1U;
            break;
        case CLK_SRC_OFF:
        /* Pass-thourgh */
        default:
            clkSource = 0U;
            break;
    }

    regValue = base->PCCn[clockNameMappings[clockName]];
    regValue &= ~(PCC_PCCn_PCS_MASK);
    regValue |= PCC_PCCn_PCS(clkSource);
    base->PCCn[clockNameMappings[clockName]] = regValue;    
}

/**
 * PTD15-> RGB_RED
 * PTD16-> RGB_GREEN
 * PTD0 -> RGB_BLUE
 * BTN0 -> PTC12
 * BTN1 -> PTC13
 */
#define LED_PORT_PCC    PCC_PORTD_CLOCK
#define BTN_PORT_PCC    PCC_PORTC_CLOCK

static void Gpio_Config(void)
{
        //config clock source
        PCC_HAL_SetClockMode(PCC, LED_PORT_PCC, false);
        PCC_HAL_SetClockSourceSel(PCC, LED_PORT_PCC, CLK_SRC_FIRC);
        PCC_HAL_SetClockMode(PCC, LED_PORT_PCC, true);

        PCC_HAL_SetClockMode(PCC, BTN_PORT_PCC, false);
        PCC_HAL_SetClockSourceSel(PCC, BTN_PORT_PCC, CLK_SRC_FIRC);
        PCC_HAL_SetClockMode(PCC, BTN_PORT_PCC, true);

        /*
         * ISF  Interrupt Status Flag
         * IRQC Interrupt Configuration
         * LK   Lock Register
         * MUX  Pin Mux Control
         * DSE  Drive Strength Enable
         * PFE  Passive Filter Enable
         * PE   Pull Enable
         * PS   Pull Select
         */
         /*
         * ISF  0
         * IRQC 0000
         * LK   0
         * MUX  001
         * DSE  0
         * PFE  0
         * PE   0
         * PS   0
         */
        PORTD->PCR[RED] = 0x00000100;
        PORTD->PCR[GREEN] = 0x00000100;
        PORTD->PCR[BLUE] = 0x00000100;

        PTD->PDDR |= BIT(RED) | BIT(GREEN) | BIT(BLUE);

        PTD->PDOR |= BIT(RED) | BIT(GREEN) | BIT(BLUE);
        /*
         * ISF  0
         * IRQC 1001
         * LK   0
         * MUX  001
         * DSE  0
         * PFE  0
         * PE   0
         * PS   0
         */
        PORTC->PCR[BTN0] = 0x00090100;
        PORTC->PCR[BTN1] = 0x00090100;

        PTC->PDDR &=~(BIT(BTN0) | BIT(BTN1));
}

static void LED_light(u8 color)
{
        PTD->PDOR |= BIT(RED) | BIT(GREEN) | BIT(BLUE);

        if (color & 0x01)
                PTD->PDOR &=~BIT(RED);
        if (color & 0x02)
                PTD->PDOR &=~BIT(GREEN);
        if (color & 0x04)
                PTD->PDOR &=~BIT(BLUE);
}

static void IRQ_Config(void)
{
        FSL_NVIC->ICPR[1] = 1 << (PORTC_IRQn % 32);  /* clr any pending IRQ*/
        FSL_NVIC->ISER[1] = 1 << (PORTC_IRQn % 32);  /* enable IRQ */
        FSL_NVIC->IP[PORTC_IRQn] = 0xA;              /* priority 10 of 0-15*/
}

static u8 color = 0;

int main(void)
{
    u32 cnt;

    cnt = 0;
        color = 0;

        Gpio_Config();
        IRQ_Config();

        while (1) {
                cnt ++;
        }
}

void PORTC_IRQHandler(void)
{
        if (PORTC->ISFR & BIT(BTN0)) {
                LED_light(color ++ % 8);
                PORTC->ISFR |= BIT(BTN0);
        } else if (PORTC->ISFR & BIT(BTN1)) {
                LED_light(color -- % 8);
                PORTC->ISFR |= BIT(BTN1);
        } else {
                /* do_nothing(); */
        }
}

编译运行之后,可以通过按键控制LED灯的颜色依次朝前或向后进行变化

你可能感兴趣的:(S32K144)