学习MSP432M0手册——第三节GPIO中断

一、本节内容

外接实验开发板K1-K4按钮和交通灯模块,其中两个按键接PA口,两个按键接PB口,所有LED灯接PB口,要求通过中断获得按键按下信息,并且实现如下功能:

  1. K1:交通灯所有红灯亮
  2. K2:交通灯所有绿灯亮
  3. K3:南北通行、东西截止
  4. K4:所有灯灭

二、原理讲解

本节涉及了PINCM寄存器,GPIO寄存器输入功能,IOMUX寄存器。

在GPIO输出功能中,对每个GPIO口进行配置,设置引脚对应的IOMUX寄存器、操作GPIO寄存器、然后操作使能寄存器进行GPIO的使能控制。

在GPIO输入功能中,直接设置GPIO口使能开启,在检测数据输出对应位是否被置为1。

在串口设置中,设置GPIO口的输入功能,然后关闭中断屏蔽,再开启下降沿中断,最后配置NVIC。

三、寄存器

IOMUX等部分寄存器介绍:学习MSP432M0手册——第一节GPIO输出功能

PINCM等部分寄存器介绍:学习MSP432M0手册——第二节GPIO输入和输出 

 

 

 GPIO的寄存器,用于关闭中断屏蔽,也就是开启中断。

下面使用CUPSS的IIDX寄存器,是因为IIDX只能识别IMASK配置的中断。

 

 

 GPIO的寄存器,用于配置触发条件。

CPUSS的寄存器,GROUP[]记录第几个中断,默认1为GPIOA,2为GPIOB,以此类推,并且此寄存器先读取索引最小的 ,索引越小优先级越高。

除了使用IIDX,还有别的办法设置中断优先级。

注意:每读取一次这个寄存器就会自动全部清0。在从CPU读取后,就必须使用第二高优先级中断清0该寄存器。

此寄存器只通过使用IMASK选择的中断。

 GPIO的寄存器,用于记录对应总线的引脚号此寄存器先读取索引最小的 ,索引越小优先级越高。

除了使用IIDX,还有别的办法设置中断优先级。

注意:每读取一次这个寄存器就会自动全部清0。在从CPU读取后,就必须使用第二高优先级中断清0该寄存器。

此寄存器只通过使用IMASK选择的中断。

四、软件代码 

int main(void)
{
    SYSCFG_DL_init();//初始化

     //PA18,按键输入、下降沿中断
    IOMUX->SECCFG.PINCM[39] |= 0x01<<0 | 0x01<<7 | 0x01<<18;//输入功能
    GPIOA->CPU_INT.IMASK |= 0X01<<18;//关闭中断屏蔽
    GPIOA->POLARITY31_16 |= 0X02<<4; //下降沿中断
     //PA17,按键输入、下降沿中断
    IOMUX->SECCFG.PINCM[38] |= 0x01<<0 | 0x01<<7 | 0x01<<18; //输入功能
    GPIOA->CPU_INT.IMASK |= 0X01<<17;//关闭中断屏蔽
    GPIOA->POLARITY31_16 |= 0X02<<2; //下降沿中断
     //PB6,按键输入、下降沿中断
    IOMUX->SECCFG.PINCM[22] |= 0x01<<0 | 0x01<<7 | 0x01<<18;
    GPIOB->CPU_INT.IMASK |= 0X01<<6;
    GPIOB-> POLARITY15_0 |= 0X03<<12; 
     //PB7,按键输入、下降沿中断
    IOMUX->SECCFG.PINCM[23] |= 0x01<<0 | 0x01<<7 | 0x01<<18;
    GPIOB->CPU_INT.IMASK |= 0X01<<7;
    GPIOB-> POLARITY15_0 |= 0X03<<14; 

    NVIC->ISER[0] |= 0X01<<1;//配置NVIC

    //PB1,led1
    IOMUX->SECCFG.PINCM[12] |= 0X01<<0 | 0X01<<7;//设置GPIO口为输出功能
    GPIOB->DOESET31_0 = 0X01<<1;//输出启用设置
    GPIOB->DOUTSET31_0 = 0X01<<1;//数据输出设置
    //PB12,led3
    IOMUX->SECCFG.PINCM[28] |= 0X01<<0 | 0X01<<7; //设置GPIO口为输出功能
    GPIOB->DOESET31_0 = 0X01<<12; //输出启用设置
    GPIOB->DOUTSET31_0 = 0X01<<12; //数据输出设置
    //PB17,led4
    IOMUX->SECCFG.PINCM[42] |= 0X01<<0 | 0X01<<7;
    GPIOB->DOESET31_0 = 0X01<<17;
    GPIOB->DOUTSET31_0 = 0X01<<17;
    //PB15,led6
    IOMUX->SECCFG.PINCM[31] |= 0X01<<0 | 0X01<<7;
    GPIOB->DOESET31_0 = 0X01<<15;
    GPIOB->DOUTSET31_0 = 0X01<<15;
    //PB0,led7
    IOMUX->SECCFG.PINCM[11] |= 0X01<<0 | 0X01<<7;
    GPIOB->DOESET31_0 = 0X01<<0;
    GPIOB->DOUTSET31_0 = 0X01<<0;
    //PB16,led9
    IOMUX->SECCFG.PINCM[32] |= 0X01<<0 | 0X01<<7;
    GPIOB->DOESET31_0 = 0X01<<16;
    GPIOB->DOUTSET31_0 = 0X01<<16;
    //PB20,led10
    IOMUX->SECCFG.PINCM[47] |= 0X01<<0 | 0X01<<7;
    GPIOB->DOESET31_0 = 0X01<<20;
    GPIOB->DOUTSET31_0 = 0X01<<20;
    //PB13,led12
    IOMUX->SECCFG.PINCM[29] |= 0X01<<0 | 0X01<<7;
    GPIOB->DOESET31_0 = 0X01<<13;
    GPIOB->DOUTSET31_0 = 0X01<<13;
}
void GROUP1_IRQHandler(void)
{
    int nowiidx;//记录中断引脚参数
    switch (CPUSS->INT_GROUP[1].IIDX)//记录中断总线
    {
        case 1: //GPIOA 中断IIDX     
            nowiidx =  GPIOA->CPU_INT.IIDX; //记录中断引脚   
            if (nowiidx == 19)  //引脚编号加1,具体中断A,B
            {
                GPIOB->DOUTCLR31_0 = 0X01<<1;//输出启用清除
                GPIOB->DOUTCLR31_0 = 0X01<<12; //输出启用清除
                GPIOB->DOUTCLR31_0 = 0X01<<17; //输出启用清除
                GPIOB->DOUTCLR31_0 = 0X01<<15; //输出启用清除
                GPIOB->DOUTCLR31_0 = 0X01<<0;
                GPIOB->DOUTCLR31_0 = 0X01<<16;
                GPIOB->DOUTCLR31_0 = 0X01<<20;
                GPIOB->DOUTCLR31_0 = 0X01<<13;
                GPIOB->DOUTSET31_0 = 0X01<<12; //数据输出启用设置
                GPIOB->DOUTSET31_0 = 0X01<<15; //数据输出启用设置
                GPIOB->DOUTSET31_0 = 0X01<<16;
                GPIOB->DOUTSET31_0 = 0X01<<13;
            }   
            if (nowiidx == 18)  //引脚编号加1,具体中断A,B
            {
                GPIOB->DOUTCLR31_0 = 0X01<<1;
                GPIOB->DOUTCLR31_0 = 0X01<<12;
                GPIOB->DOUTCLR31_0 = 0X01<<17;
                GPIOB->DOUTCLR31_0 = 0X01<<15;
                GPIOB->DOUTCLR31_0 = 0X01<<0;
                GPIOB->DOUTCLR31_0 = 0X01<<16;
                GPIOB->DOUTCLR31_0 = 0X01<<20;
                GPIOB->DOUTCLR31_0 = 0X01<<13;
                GPIOB->DOUTSET31_0 = 0X01<<1;
                GPIOB->DOUTSET31_0 = 0X01<<17;
                GPIOB->DOUTSET31_0 = 0X01<<0;
                GPIOB->DOUTSET31_0 = 0X01<<20;
            }         
            break;     
        case 2: //GPIOB 中断IIDX
            nowiidx = GPIOB->CPU_INT.IIDX; //记录中断引脚
            if (nowiidx ==7)
            {
                GPIOB->DOUTCLR31_0 = 0X01<<1;
                GPIOB->DOUTCLR31_0 = 0X01<<12;
                GPIOB->DOUTCLR31_0 = 0X01<<17;
                GPIOB->DOUTCLR31_0 = 0X01<<15;
                GPIOB->DOUTCLR31_0 = 0X01<<0;
                GPIOB->DOUTCLR31_0 = 0X01<<16;
                GPIOB->DOUTCLR31_0 = 0X01<<20;
                GPIOB->DOUTCLR31_0 = 0X01<<13;
                GPIOB->DOUTSET31_0 = 0X01<<1;
                GPIOB->DOUTSET31_0 = 0X01<<15;
                GPIOB->DOUTSET31_0 = 0X01<<0;
                GPIOB->DOUTSET31_0 = 0X01<<13;
            }
            if (nowiidx ==8)
            {
                GPIOB->DOUTCLR31_0 = 0X01<<1;
                GPIOB->DOUTCLR31_0 = 0X01<<12;
                GPIOB->DOUTCLR31_0 = 0X01<<17;
                GPIOB->DOUTCLR31_0 = 0X01<<15;
                GPIOB->DOUTCLR31_0 = 0X01<<0;
                GPIOB->DOUTCLR31_0 = 0X01<<16;
                GPIOB->DOUTCLR31_0 = 0X01<<20;
                GPIOB->DOUTCLR31_0 = 0X01<<13;
                GPIOB-> DOUTSET31_0  = 0X01<<1;
                GPIOB-> DOUTSET31_0  = 0X01<<12;
                GPIOB-> DOUTSET31_0  = 0X01<<17;
                GPIOB-> DOUTSET31_0  = 0X01<<15;
                GPIOB-> DOUTSET31_0  = 0X01<<0;
                GPIOB-> DOUTSET31_0  = 0X01<<16;
                GPIOB-> DOUTSET31_0  = 0X01<<20;
                GPIOB-> DOUTSET31_0  = 0X01<<13;
            }
			break;
    }

本节介绍了对GPIO口进行中断配置,设置引脚对应的IOMUX寄存器、操作GPIO中断寄存器、然后关闭中断屏蔽,再开启下降沿触发。

注意

DOE与DOUT寄存器存在区别,中断控制需要记录具体GPIO口。

IIDX中断每读取一次这个寄存器就会自动全部清0。在从CPU读取后,就必须使用第二高优先级中断清0该寄存器。

IIDX中断寄存器只通过使用IMASK选择的中断。

关于其他中断配置,笔者会放在其他章节介绍。

MSP432 低功耗高性能并存10.1 Digital I/O Introduction The digital I/O features include: • Independently programmable individual I/Os • Any combination of input or output • Individually configurable interrupts for ports (available for certain ports only) • Independent input and output data registers • Individually configurable pullup or pulldown resistors • Wake-up capability from ultra-low power modes (available for certain ports only) • Individually configurable high drive I/Os (available for certain I/Os only) Devices within the family may have up to eleven digital I/O ports implemented (P1 to P10 and PJ). Most ports contain eight I/O lines; however, some ports may contain less (see the device-specific data sheet for ports available). Each I/O line is individually configurable for input or output direction, and each can be individually read or written. Each I/O line is individually configurable for pullup or pulldown resistors. Certain ports have interrupt and wake-up capability from ultra-low power modes (see device specific data sheet for ports with interrupt and wake-up capability). Each interrupt can be individually enabled and configured to provide an interrupt on a rising or falling edge of an input signal. All interrupts are fed into an encoded Interrupt Vector register, allowing the application to determine which sub-pin of a port has generated the event. Individual ports can be accessed as byte-wide ports or can be combined into half-word-wide ports. Port pairs P1 and P2, P3 and P4, P5 and P6, P7 and P8, and so on, are associated with the names PA, PB, PC, PD, and so on, respectively. All port registers are handled in this manner with this naming convention. The main exception are the interrupt vector registers, for example, interrupts for ports P1 and P2 must be handled through P1IV and P2IV, PAIV does not exist. When writing to port PA with half-word operations, all 16 bits are written to the port. When writing to the lower byte of port PA using byte operations, the upper byte remains unchanged. Similarly, writing to the upper byte of port PA using byte instructions leaves the lower byte unchanged. When writing to a port that contains less than the maximum number of bits possible, the unused bits are don't care. Ports PB, PC, PD, PE, and PF behave similarly.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值