TM4C123G学习笔记2——GPIO

目录

GPIO 输出——点亮 RGB LED

GPIO 输入——获取按键状态

GPIO 中断——按键中断


GPIO 输出——点亮 RGB LED

#include "stdint.h"
#include "stdbool.h"
#include "inc\tm4c123gh6pm.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"


#define G_LED GPIO_PIN_1
#define B_LED GPIO_PIN_2
#define R_LED GPIO_PIN_3


//1.系统时钟分频值
//
//SYSCTL_SYSDIV_1  // 振荡器不分频(不可用于PLL)
//SYSCTL_SYSDIV_2  // 振荡器 2分频(不可用于PLL)
//SYSCTL_SYSDIV_3  // 振荡器 3分频(不可用于PLL)
//SYSCTL_SYSDIV_4  // 振荡器 4分频,或对PLL的分频结果为50MHz
//SYSCTL_SYSDIV_5  // 振荡器 5分频,或对PLL的分频结果为40MHz
//SYSCTL_SYSDIV_64 // 振荡器64分频,或对PLL的分频结果为3.125MHz Sandstorm家族最大分频数只能取到16,也就是811系列只能分频到16
//2.使用OSC还是PLL
//
//SYSCTL_USE_PLL   // 采用锁相环PLL作为系统时钟源
//SYSCTL_USE_OSC   // 采用OSC(主振荡器或内部振荡器)作为系统时钟源
//
//3.OSC时钟源选择
//
//SYSCTL_OSC_MAIN  // 主振荡器作为OSC
//SYSCTL_OSC_INT   // 内部12MHz振荡器作为OSC
//SYSCTL_OSC_INT4  // 内部12MHz振荡器4分频后作为OSC
//SYSCTL_OSC_INT30 // 内部30KHz振荡器作为OSC
//SYSCTL_OSC_EXT32 // 外接32.768KHz有源振荡器作为OSC
//
//4.外接晶体频率
//
//SYSCTL_XTAL_1MHZ    // 外接晶体1MHz
//SYSCTL_XTAL_1_84MHZ // 外接晶体1.8432MHz
//SYSCTL_XTAL_2MHZ    // 外接晶体2MHz
//SYSCTL_XTAL_2_45MHZ // 外接晶体2.4576MHz
//SYSCTL_XTAL_3_57MHZ // 外接晶体3.579545MHz
//SYSCTL_XTAL_3_68MHZ // 外接晶体3.6864MHz
//SYSCTL_XTAL_4MHZ    // 外接晶体4MHz
//SYSCTL_XTAL_4_09MHZ // 外接晶体4.096MHz
//SYSCTL_XTAL_4_91MHZ // 外接晶体4.9152MHz
//SYSCTL_XTAL_5MHZ    // 外接晶体5MHz
//SYSCTL_XTAL_5_12MHZ // 外接晶体5.12MHz
//SYSCTL_XTAL_6MHZ    // 外接晶体6MHz
//SYSCTL_XTAL_6_14MHZ // 外接晶体6.144MHz
//SYSCTL_XTAL_7_37MHZ // 外接晶体7.3728MHz
//SYSCTL_XTAL_8MHZ    // 外接晶体8MHz
//SYSCTL_XTAL_8_19MHZ // 外接晶体8.192MHz
//SYSCTL_XTAL_10MHZ   // 外接晶体10MHz
//SYSCTL_XTAL_12MHZ   // 外接晶体12MHz
//SYSCTL_XTAL_12_2MHZ // 外接晶体12.288MHz
//SYSCTL_XTAL_13_5MHZ // 外接晶体13.56MHz
//SYSCTL_XTAL_14_3MHZ // 外接晶体14.31818MHz
//SYSCTL_XTAL_16MHZ   // 外接晶体16MHz
//SYSCTL_XTAL_16_3MHZ // 外接晶体 16.384MHz 5.振荡源禁止
//SYSCTL_INT_OSC_DIS  // 禁止内部振荡器
//SYSCTL_MAIN_OSC_DIS // 禁止主振荡器 振荡源禁止
//SYSCTL_INT_OSC_DIS  // 禁止内部振荡器
//SYSCTL_MAIN_OSC_DIS // 禁止主振荡器

void main(void)
{
    //设置系统时钟为50M,从pll晶振产生
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

    //使能GPIOF
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //设置端口为输出
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, R_LED | G_LED | B_LED);

    while(1)
    {
        GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, R_LED);
        SysCtlDelay(200000);
        SysCtlDelay(200000);
        SysCtlDelay(200000);
        GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, G_LED);
        SysCtlDelay(200000);
        SysCtlDelay(200000);
        SysCtlDelay(200000);
        GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, B_LED);
        SysCtlDelay(200000);
        SysCtlDelay(200000);
        SysCtlDelay(200000);
    }
}

GPIO 输入——获取按键状态

#include "stdint.h"
#include "stdbool.h"
#include "inc\tm4c123gh6pm.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_gpio.h"


#define G_LED GPIO_PIN_1
#define B_LED GPIO_PIN_2
#define R_LED GPIO_PIN_3

#define KEY1 GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7)
#define KEY2 GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6)
#define KEY3 GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7)


void RGB_Config(void);
void KEY_Config(void);
uint8_t KEY_Scan(uint8_t mode);


uint16_t value = 0;


int main(void)
{
    uint8_t key_value = 0;
    uint8_t t = 0, k = 0;

    //设置系统时钟为50M,从pll晶振产生
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

    RGB_Config();
    KEY_Config();

    while(1)
    {
        key_value = KEY_Scan(0);
        if(key_value == 3)
        {
            t ++;
        }
        if(t%3 == 1)
        {
            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, R_LED);
        }
        if(t%3 == 2)
        {
            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, G_LED);
        }
        if(t%3 == 0)
        {
            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, B_LED);
        }
        if(t == 9)
            t = 1;


//        t = GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7);//检测
//
//        if((t&GPIO_PIN_7) != GPIO_PIN_7)//如果按下
//        {
//            SysCtlDelay(20*(SysCtlClockGet()/3000));//消抖
//            t = GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7);//再次检测
//            if((t&GPIO_PIN_7) != GPIO_PIN_7) //再次判断
//            {
//                k ++;
//                while(!GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7));
//            }
//        }
//
//        if(k%3 == 1)
//        {
//            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, R_LED);
//        }
//        if(k%3 == 2)
//        {
//            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, G_LED);
//        }
//        if(k%3 == 0)
//        {
//            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, B_LED);
//        }
//        if(k == 9)
//            k = 1;
    }
}



/*****************************************************************************
 * @brief   LCD模块按键
 *          PC7 对应的为按键S1
 *          PD6 对应的为按键S2
 *          PD7 对应的为按键S3
 * @param   null
 * @return  null
*****************************************************************************/
void KEY_Config(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    HWREG(GPIO_PORTD_BASE+GPIO_O_LOCK)  |= GPIO_LOCK_KEY; // TM4单片机的PD7和PF0引脚默认是不可屏蔽中断(NMI),所以不可以直接使用,使用之前需要进行解锁操作
    HWREG(GPIO_PORTD_BASE+GPIO_O_CR)    |= (1<<7);
    HWREG(GPIO_PORTD_BASE+GPIO_O_DEN)   &= (~(1<<7));
    HWREG(GPIO_PORTD_BASE+GPIO_O_PDR)   &= (~(1<<7));
    HWREG(GPIO_PORTD_BASE+GPIO_O_PUR)   &= (~(1<<7));
    HWREG(GPIO_PORTD_BASE+GPIO_O_AFSEL) &= (~(1<<7));

    GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_7);
    GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_6|GPIO_PIN_7);
    GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_6|GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);//将输入io口上拉,为高电平,其电平变为低电平即认为其按下
//    GPIO_PIN_TYPE_STD_WPU   为弱上拉
//    GPIO_PIN_TYPE_STD_WPD   为弱下拉
//    GPIO_PIN_TYPE_STD       为推挽引脚
//    GPIO_PIN_TYPE_OD        为开漏
//    GPIO_PIN_TYPE_ANALOG    为模拟输入
//    GPIO_PIN_TYPE_WAKE_HIGH 为高电平唤醒
//    GPIO_PIN_TYPE_WAKE_LOW  为低电平唤醒
}


void RGB_Config(void)
{
    //使能GPIOF
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    //设置端口为输出
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, R_LED | G_LED | B_LED);
}


uint8_t KEY_Scan(uint8_t mode)
{
    static uint8_t key_up;//按键按松开标志
    key_up=1;   // 此处不能直接以 static uint8_t key_up = 1; 这种方式赋值

    if(mode)key_up=1;       //支持连按
    if(key_up&&(KEY1==0||KEY2==0||KEY3==0))
    {
        SysCtlDelay(50*(SysCtlClockGet()/3000));//消抖
        key_up=0;
        if(KEY1==0)     return 1;
        else if(KEY2==0)return 2;
        else if(KEY3==0)return 3;
    }else if(KEY1==1&&KEY2==1&&KEY3==1)key_up=1;
    return 0;// 无按键按下
}

GPIO 中断——按键中断

#include "stdint.h"
#include "stdbool.h"
#include "inc\tm4c123gh6pm.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_gpio.h"


#define G_LED GPIO_PIN_1
#define B_LED GPIO_PIN_2
#define R_LED GPIO_PIN_3

#define KEY1 GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7)
#define KEY2 GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6)
#define KEY3 GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7)


void RGB_Config(void);
void KEY_Config(void);
void KEY_EXTI_Config(void);
uint8_t KEY_Scan(uint8_t mode);

void Init_GPIO_KEY_Handler(void); // 声明中断服务函数,TM4C的中断服务函数名可以自己定义的,但是需要注册


uint16_t value = 0;


int main(void)
{
    uint8_t key_value = 0;
    uint8_t t = 0, k = 0;

    //设置系统时钟为50M,从pll晶振产生
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

    RGB_Config();
    KEY_Config();
    KEY_EXTI_Config();


    while(1)
    {

    }
}



/*****************************************************************************
 * @brief   LCD模块按键
 *          PC7 对应的为按键S1
 *          PD6 对应的为按键S2
 *          PD7 对应的为按键S3
 * @param   null
 * @return  null
*****************************************************************************/
void KEY_Config(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    HWREG(GPIO_PORTD_BASE+GPIO_O_LOCK)  |= GPIO_LOCK_KEY; // TM4单片机的PD7和PF0引脚默认是不可屏蔽中断(NMI),所以不可以直接使用,使用之前需要进行解锁操作
    HWREG(GPIO_PORTD_BASE+GPIO_O_CR)    |= (1<<7);
    HWREG(GPIO_PORTD_BASE+GPIO_O_DEN)   &= (~(1<<7));
    HWREG(GPIO_PORTD_BASE+GPIO_O_PDR)   &= (~(1<<7));
    HWREG(GPIO_PORTD_BASE+GPIO_O_PUR)   &= (~(1<<7));
    HWREG(GPIO_PORTD_BASE+GPIO_O_AFSEL) &= (~(1<<7));

    GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_7);
    GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_6|GPIO_PIN_7);
    GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_6|GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);//将输入io口上拉,为高电平,其电平变为低电平即认为其按下

}


void RGB_Config(void)
{
    //使能GPIOF
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    //设置端口为输出
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, R_LED | G_LED | B_LED);
}


void KEY_EXTI_Config(void)
{
    GPIOIntRegister(GPIO_PORTD_BASE, Init_GPIO_KEY_Handler);        // 注册GPIOD的中断服务函数
    GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_6, GPIO_FALLING_EDGE); // 设置PD6为下降沿触发
    GPIOIntEnable(GPIO_PORTD_BASE, GPIO_INT_PIN_6);                 // 使能PD6中断

    IntEnable(INT_GPIOD);         // 使能GPIOD中断
    IntPrioritySet(INT_GPIOD, 0); // 设置中断优先级,TM4C123G的中断优先级有8个
    GPIOIntClear(GPIO_PORTD_BASE, GPIO_INT_PIN_6); // 清除PD6中断标志位
}


/*****************************************************************************
 * @brief   LCD模块按键响应中断
 *          PC7 对应的为按键S1
 *          PD6 对应的为按键S2
 *          PD7 对应的为按键S3
 * @param   null
 * @return  null
*****************************************************************************/
void Init_GPIO_KEY_Handler(void) //中断处理子函数
{
    unsigned long ulStatus;
    ulStatus = GPIOIntStatus(GPIO_PORTD_BASE, true);  // 读取中断状态
    GPIOIntClear(GPIO_PORTD_BASE, ulStatus);          // 清除中断状态
    if (ulStatus & GPIO_PIN_6)                        // 如果KEY的中断状态有效
    {
        SysCtlDelay(10 * (SysCtlClockGet() / 3000));  // 延时约10ms,消除按键抖动
        while (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6) == 0x00); // 等待KEY抬起
        SysCtlDelay(10 * (SysCtlClockGet()  / 3000)); // 延时约10ms,消除松键抖动

        value ++ ;
        if(value%3 == 1)
        {
            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, R_LED);
        }
        if(value%3 == 2)
        {
            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, G_LED);
        }
        if(value%3 == 0)
        {
            GPIOPinWrite(GPIO_PORTF_BASE, R_LED | G_LED | B_LED, B_LED);
        }
        if(value == 9)
            value = 1;
    }
//    else if (ulStatus & GPIO_PIN_7) // 如果KEY的中断状态有效
//    {
//        SysCtlDelay(10 * (SysCtlClockGet() / 3000));              // 延时约10ms,消除按键抖动
//        while (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7) == 0x00); // 等待KEY抬起
//        SysCtlDelay(10 * (SysCtlClockGet()  / 3000));             // 延时约10ms,消除松键抖动
//
//
//    }
}

 

 

上一篇:centos7:无法分配内存 (errno=12)


下一篇:Linux如何解决root用户Operation not permitted