lm3s811 学习笔记(四)【gpio】

来源:互联网 发布:只有微信无法连接网络 编辑:程序博客网 时间:2024/06/05 02:38

今天主要是熟悉下gpio的一些应用。最简单的就是LED灯的控制。

下面的例子就拿L5来说明吧。

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//enable gpio b

GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0);//set PB0 output

还有一种模式设置的方法GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_DIR_MODE_OUT) ;//这个方案可以设置多个引脚,参数2为位引脚的或

控制LED灯地亮灭,就是往引脚写入值

ledstatus = GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0&(~ledstatus));

上面的程序是读取L5对应管脚的值,然后使灯地状态进行翻转。

这里说下GPIOPinWrite()该函数的用法。

GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_1, GPIO_PIN_1);

GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_1, ~GPIO_PIN_1);

例程上常用上面的方法。主要也就是你要让哪个管脚置一,参数3的值中管脚对应的位必须置一。

如下各条指令都能点亮响应端口(假设已经都定义成输出了)。

 

     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0,1);

     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1,2);
     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2,4);
     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3,8);
     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_4,0x10);
     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_5,0x20);
     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_6,0x40);
     GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_7,0x80);

下面我主要讲述下键控LED的流程,其实就是利用按键中断控制灯的亮灭。

首先是配置KEY。

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);//Enable GPIO C
GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_4);//Enable GPIO C pin 4
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_4);//set the pin mode is input

GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_LOW_LEVEL);//set interrupt type is low Falling edge
IntEnable(INT_GPIOC);//enable GPIO C interrupt

下面是按键中断的处理函数

void userkey_handler(void)
{
    unsigned char ucVal;
    unsigned long ulStatus;

    ulStatus = GPIOPinIntStatus(GPIO_PORTC_BASE, true);//  get gpio c interrupt status
    GPIOPinIntClear(GPIO_PORTC_BASE, ulStatus); //  clear interrupt status

    if (ulStatus & GPIO_PIN_4)                 //  如果KEY的中断状态有效
    {
        ucVal = GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0);      //  翻转LED
        GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, ~ucVal);

        SysCtlDelay(10 * (SysCtlClockGet() / 3000));             //  延时约10ms,消除按键抖动

        while (GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_4) == 0x00);     //  等待KEY抬起

        SysCtlDelay(10 * (SysCtlClockGet() / 3000));             //  延时约10ms,消除松键抖动
    }
}

既然用到了SysCtlDelay()函数。在这里也顺道分析下。

#if defined(ewarm) || defined(DOXYGEN)//iar环境下
void
SysCtlDelay(unsigned long ulCount)
{
    __asm("    subs    r0, #1\n"
          "    bne.n   SysCtlDelay\n"
          "    bx      lr");
}
#endif
#if defined(codered) || defined(gcc) || defined(sourcerygxx)//codered、gcc、sourcerygcc环境下
void __attribute__((naked))
SysCtlDelay(unsigned long ulCount)
{
    __asm("    subs    r0, #1\n"
          "    bne     SysCtlDelay\n"
          "    bx      lr");
}
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION)//keil MDK环境下
__asm void
SysCtlDelay(unsigned long ulCount)
{
    subs    r0, #1;
    bne     SysCtlDelay;
    bx      lr;
}
#endif
#if defined(ccs)//ccs
volatile unsigned long g_ulInlineCCSWorkaround;
void
SysCtlDelay(unsigned long ulCount)
{
    __asm("delay?: subs    r0, #1\n"
          "    bne.n   delay?\n"
          "    bx lr\n");


    //
    // This is needed to keep TI compiler from optimizing away this code.
    //
    g_ulInlineCCSWorkaround += ulCount;
}
#endif

SysCtlDelay()执行了3个汇编语句,运行时间3个始终周期。函数说明上: The loop takes 3 cycles/loop.

1、在主晶振6MHZ的情况下

SysCtlDelay(2);   delaytime = 2 * 3 * (1/6000000) = 1us

SysCtlDelay(10 * (TheSysClock / 3000));  delaytime = 10 * (6000000/3000)* 3  * (1/6000000) = 10ms

2、在主晶振8MHZ的情况下

SysCtlDelay(2);  delaytime = 2 * 3 * (1/8000000) = 0.75us

SysCtlDelay(10 * (TheSysClock / 3000));  delaytime = 10 * (8000000/3000)* 3  * (1/8000000) = 10ms

由此 可以看出无论是多大的晶振,都是除以3000。SysCtlDelay(10 * (TheSysClock / 3000));这种写法也方便移植

原创粉丝点击