TiveC微控制器基础练习1.3源码(中断实现按键)

本实验源码为参考代码,可以在EK-TM4C123GXL上进行验证。

演示代码并非最优代码,是从易于理解的角度出发,争取做到最好理解的代码。

//*****************************************************************************
// 基础练习1.3: 按键控制LED灯亮灭
//
//  本例程在前一个例程的基础上,按键识别采用中断的方式进行实现。
//
// 过程描述:
//  1. 从硬件电路中可知,按键未按下时,引脚是高电平;按键按下时,接地,引脚是低电平;
//     用户按键时,从高电平到低电平的变化,产生一个下降沿。
//     把按键的引脚设置为输入,使能下降沿中断。
//  2. 把引脚配置成GPIO,输出。 通过输出高电平和低电平来控制LED的亮和灭。
//  3. 要简单点,可以直接在GPIO中断中对LED灯进行操作。为了后续的方便,采用存储按键值的方式。
//  4. K1->D2, K2->D3, K3->D4
//
// 硬件描述:
//    LED2(蓝色) --PF0
//    LED3(绿色) --PA4
//    LED4(红色) --PD6
//    K1 -- PD7
//    K2 -- PF4 
//    K3 -- PA3 
//    K4 -- PA2 
//
// 注意事项:
// 引脚PF0和PD7比较特殊,默认是保护的。要重新编程操作的话,需要先解锁
// 小技巧:
//  通过SysConfig工具进行引脚的初始配置,就不用考虑这些因素了.
//  SysConfig的使用可参考链接: https://www.bilibili.com/read/cv6258251
//
//
//*****************************************************************************

#include 
#include 
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"

//宏定义,用一个变量来存储键值; 0000 x x x x
//低4位,有按键按下时,该比特位置位1; 按键响应后该比特位清零
#define KEY_VALUE_KEY1   0x01
#define KEY_VALUE_KEY2   0x02
#define KEY_VALUE_KEY3   0x04
#define KEY_VALUE_KEY4   0x08
#define KEY_VALUE_NOKEY  0x00

//变量定义
uint8_t key_value; //储存键值

//*****************************************************************************
//
// 中断服务函数--GPIO中断
//
// Key1 -- PD7
// Key2 -- PF4 
// Key3 -- PA3
// Key4 -- PA2 
// 因为按键分布在不同的端口,所以中断要分别处理。
// 该例程只是简单处理LED,可以直接在中断里边处理。
// 考虑到后续的延续性,在中断里只做键值的处理。
//*****************************************************************************
void Key1IntHandler()
{
    static uint32_t ui32Status;

    //读取中断标志,变量
    ui32Status = GPIOIntStatus(GPIO_PORTD_BASE,true);
    //手动清除中断标志
    GPIOIntClear(GPIO_PORTD_BASE,ui32Status);
    //对变量进行判断处理
    if(ui32Status & GPIO_INT_PIN_7)
    {
        key_value |= KEY_VALUE_KEY1;
    }
}

void Key2IntHandler()
{
    static uint32_t ui32Status;

    //读取中断标志,变量
    ui32Status = GPIOIntStatus(GPIO_PORTF_BASE,true);
    //手动清除中断标志
    GPIOIntClear(GPIO_PORTF_BASE,ui32Status);
    //对变量进行判断处理
    if(ui32Status & GPIO_INT_PIN_4)
    {
        key_value |= KEY_VALUE_KEY2;
    }
}


void Key3and4IntHandler()
{
    static uint32_t ui32Status;

    //读取中断标志,变量
    ui32Status = GPIOIntStatus(GPIO_PORTA_BASE,true);
    //手动清除中断标志
    GPIOIntClear(GPIO_PORTA_BASE,ui32Status);
    //对变量进行判断处理
    if(ui32Status & GPIO_INT_PIN_3)
    {
        key_value |= KEY_VALUE_KEY3;
    }

    if(ui32Status & GPIO_INT_PIN_2)
    {
        key_value |= KEY_VALUE_KEY4;
    }
}


void main(void)
{
    //用来存储当前的LED状态.
    //0表示关 ,1表示开.可以用宏定义.
    uint8_t led2,led3,led4;

    //-----------外设使能-------------
    //使能PA外设的时钟,并等待Ready
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA))
    {
    }

    //使能PD外设的时钟,并等待Ready
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD))
    {
    }

    //使能PF外设的时钟,并等待Ready
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
    {
    }

    //-----------引脚配置-------------

    //PA4->绿色LED,将PA4配置成GPIO,输出
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_4);

    //PD6->红色LED,将PD6配置成GPIO,输出
    GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_6);

    //PF0->蓝色LED,将PF0配置成GPIO,输出
    HWREG(GPIO_PORTF_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE+GPIO_O_CR)   |= GPIO_PIN_0;
    HWREG(GPIO_PORTF_BASE+GPIO_O_LOCK) = 0x0;
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0);

    //PD7->K1,将PD7配置成GPIO,输入
    HWREG(GPIO_PORTD_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTD_BASE+GPIO_O_CR)   |= GPIO_PIN_7;
    HWREG(GPIO_PORTD_BASE+GPIO_O_LOCK) = 0x0;
    GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_7);

    //PF4->K2,将PF4配置成GPIO,输入
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);

    //PA3->K3,将PA3配置成GPIO,输入
    GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_3);

    //PA2->K4,将PA2配置成GPIO,输入
    GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_2);

    //---------按键引脚的中断设置---------
    //先设置为下降沿触发,然后使能中断,注册中断函数

    // Key1 -- PD7
    GPIOIntTypeSet(GPIO_PORTD_BASE,GPIO_PIN_7,GPIO_FALLING_EDGE);
    GPIOIntEnable(GPIO_PORTD_BASE,GPIO_PIN_7);
    GPIOIntRegister(GPIO_PORTD_BASE, Key1IntHandler);
    // Key2 -- PF4 
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
    GPIOIntEnable(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOIntRegister(GPIO_PORTF_BASE, Key2IntHandler);
    // Key3 -- PA3
    GPIOIntTypeSet(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_FALLING_EDGE);
    GPIOIntEnable(GPIO_PORTA_BASE,GPIO_PIN_3);
    GPIOIntRegister(GPIO_PORTA_BASE, Key3and4IntHandler);
    // Key4 -- PA2
    GPIOIntTypeSet(GPIO_PORTA_BASE,GPIO_PIN_2,GPIO_FALLING_EDGE);
    GPIOIntEnable(GPIO_PORTA_BASE,GPIO_PIN_2);


    //-----------LED状态初始化-------------

    //PA4输出高电平,绿色LED灭
    GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_4,0xFF);
    //PD6输出高电平,红色LED灭
    GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_6,0xFF);
    //PF0输出高电平,蓝色LED灭
    GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,0xFF);

    led2 = 0;
    led3 = 0;
    led4 = 0;

    while(1)
    {
        //依次对按键值的各个位进行判断

        if(key_value & KEY_VALUE_KEY1)
        {
            //键值清零
            key_value &= ~(KEY_VALUE_KEY1);

            //判断当前的LED状态,取反
            if(0==led2)
            {
                //PF0输出低电平,蓝色LED亮
                GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,0x00);
                //修改状态标志,led的状态为 亮
                led2 = 1;
            }
            else
            {
                //PF0输出高电平,蓝色LED灭
                GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_0,0xFF);
                //修改状态标志,led的状态为 灭
                led2 = 0;
            }
        }

        if(key_value & KEY_VALUE_KEY2)
        {
            //键值清零
            key_value &= ~(KEY_VALUE_KEY2);

            //判断当前的LED状态,取反
            if(0==led3)
            {
                //PA4输出低电平,绿色LED亮
                GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_4,0x00);
                //修改状态标志,led的状态为 亮
                led3 = 1;
            }
            else
            {
                //PA4输出高电平,绿色LED灭
                GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_4,0xFF);
                //修改状态标志,led的状态为 灭
                led3 = 0;
            }

        }

        if(key_value & KEY_VALUE_KEY3)
        {
            //键值清零
            key_value &= ~(KEY_VALUE_KEY3);

            //判断当前的LED状态,取反
            if(0==led4)
            {
                //PD6输出低电平,红色LED亮
                GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_6,0x00);
                //修改状态标志,led的状态为 亮
                led4 = 1;
            }
            else
            {
                //PD6输出高电平,红色LED灭
                GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_6,0xFF);
                //修改状态标志,led的状态为 灭
                led4 = 0;
            }
        }

    }

}

 

你可能感兴趣的:(TivaC微控制器)