碰撞开关的两种解决方法

碰撞开关的两种解决方法_第1张图片
这是接口板以及相应的电路连接。

可以发现MSP432主控板外接了一个接口板,接口板与另外的模块之间有连接。包括红外循迹,电机驱动以及电源模块,碰撞开关的接入。

碰撞开关指的是在小车前端的六个可触碰开关。这里的需求是【当6个碰撞开关其中任意一个遭受撞击后,接口板上的灯开始闪烁起提示作用,但需要是不同颜色】

由于接口板和主控板已经封装好,碰撞模块又算的上外设,所以这里的输入为P4.0-P4.7中的6个接口。输出当然是LED灯

至于以不同的颜色闪烁,考虑到此主控板上LED2.0-LED2.2是不同的颜色,且可以单色三灯+任意两个三原色进行排列组合,这样就可以达到预期效果。

具体实现流程大致为:

定义输出LED → \rightarrow 定义输入包含上拉电阻的接口 → \rightarrow 当按下(低电平有效时)将灯点亮(即加一段延时),注意点亮灯地址的分配

需要用到的函数:

GPIO_setAsOutputPin()——将端口设置为输出

GPIO_setAsInputPinWithPullUpResistor()——将端口定义为上拉电阻输入

GPIO_INPUT_PIN_LOW()——表示GPIO接口低电平时

GPIO_getInputPinValue()——检测高低电平的函数

注意要用一个大循环给框着

具体代码如下:

/* DriverLib Includes */
#include 

/* Standard Includes */
#include 
#include 
volatile uint32_t ui32Loop;
/**
 * main.c
 */
void main(void)
{
     
    //关闭看门狗
    WDT_A_holdTimer();
    //配置输出,P2.0三个接口判断亮灭
    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0);
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2);
    //配置上拉
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN0);
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN2);
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN3);
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN5);
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN6);
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN7);

    while(1)
       {
     
        //P4.0
        if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN0))
            {
     
                GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
                    for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
                          {
     
                          }
                while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN0));
            }
        //P4.2
        if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN2))
                    {
     
                        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
                            for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
                                  {
     
                                  }
                        while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN2));
                    }
        //p4.3对应
        if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN3))
                    {
     
                        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
                            for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
                                  {
     
                                  }
                        while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN3));
                    }
        //P4.5对应
        if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN5))
                           {
     
                               GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
                               GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
                                   for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
                                         {
     
                                         }
                               while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN5));
                           }
        //P4.6对应
        if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN6))
                                   {
     
                                       GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
                                       GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
                                           for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
                                                 {
     
                                                 }
                                       while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN6));
                                   }
       //P4.7对应
        if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN7))
                                          {
     
                                              GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
                                              GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
                                                  for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
                                                        {
     
                                                        }
                                              while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN7));
                                          }
       }


}


有些凌乱。定义引脚依旧了最前面。

现在考虑用中断相关知识来实现这个效果。因为对中断过程不了解,现找出相应的例程函数看看

/* DriverLib Includes */
#include 

/* Standard Includes */
#include 
#include 

int main(void)
{
     
    /* Halting the Watchdog */
    MAP_WDT_A_holdTimer();

    /* P1.0口输入 */
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);

    /*MAP函数可以自动决策这部分的存储空间,是用FLASH还是RAM*/
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);//1.1设置为输出
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);//清理中断标志
    MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);//使能中断端口
    MAP_Interrupt_enableInterrupt(INT_PORT1);//端口总使能

    /* Enabling SRAM Bank Retention */
    MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
    
    /* Enabling MASTER interrupts */
    MAP_Interrupt_enableMaster();   

    /* Going to LPM3 */
    while (1)
    {
     
        MAP_PCM_gotoLPM3();
    }
}

//这是端口中断的中断服务程序
void PORT1_IRQHandler(void)
{
     
    uint32_t status;//设置状态

    status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);//一次性获取状态
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

   
    if(status & GPIO_PIN1)
    {
     
        MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);//对端口的电平反向
    }

}

同样的包括引脚设置,中断请求,中断服务程序三项。

中断请求这里包括设置上拉电阻,清理中断标志位和打开中断允许端口三项

这里解释一下什么是中断标志位。一般中断程序执行有两个必要条件,一个是标志位置1,另外一个是中断允许端口打开。而中断允许端口日常打开,中断程序中也有相应的ENABLE指令,为:

MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);

具体怎么搞,根据给出的模板套应该就行了。大致分为这几个部分,且很多地方是不变的。

现在给出相应的通过中断实现的代码:

/*
 * 文件说明: rslk碰撞开关的相关函数
 *
 * */

/* DriverLib Includes */
#include 

/* Standard Includes */
#include 
#include 

int main(void)
{
     
    //停用看门狗
    MAP_WDT_A_holdTimer();

   
    //p1.0  p2.0  p2.1  p2.2
    //LED引脚设置为输出
    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);

    //输出低电平,led灯熄灭
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
    GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);

    //设置碰撞开关引脚为输入,使能内部上拉,启用中断
    //P4.0  p4.2  p4.3 p4.5 p4.6 p4.7

    //P4.0
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4,GPIO_PIN0);//给输入端上拉电阻
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN0);//清理中断标志位
    MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN0);//中断使能
    //P4.2
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN2);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN2);
    MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN2);
    //P4.3
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN3);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN3);
    MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN3);
    //P4.5
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN5);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN5);
    MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN5);
    //P4.6
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN6);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN6);
    MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN6);
    //P4.7
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN7);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN7);
    MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN7);

    //启用中断
    MAP_Interrupt_enableInterrupt(INT_PORT4);

    //使能中断
    MAP_Interrupt_enableMaster();

    while (1)
    {
     

    }
}

//GPIO中断处理函数
//出现了中断,程序会自动执行中断服务程序
void PORT4_IRQHandler(void)
{
     
    uint32_t status;

    //读取GPIO口的中断标志位,如果发生了中断,那么相关的引脚会被 置1.
    //这个函数,一次都会P4端口所有引脚的中断
    status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P4);

    //将相应的中断标志清除
    //好好理解下输入参数status。 假设有多个置1的位,那么这些位都会清零
    GPIO_clearInterruptFlag(GPIO_PORT_P4, status);


    if(status & GPIO_PIN0)
    {
     
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
    }

    if(status & GPIO_PIN2)
    {
     
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
    }

    if(status & GPIO_PIN3)
    {
     
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
    }

    if(status & GPIO_PIN5)
    {
     
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
    }

    if(status & GPIO_PIN6)
    {
        
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
    }

    if(status & GPIO_PIN7)
    {
     
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
        GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
    }

}

`

你可能感兴趣的:(单片机)