嵌入式系统课设:单按键控制LED灯

合工大嵌入式系统课程设计

设计要求:
  根据单个按键输入情况控制LED灯的不同显示效果。K1连续按下偶数次时,四个LED灯(LED1~LED4)按1秒(定时器中断实现)的间隔同时闪烁对应的次数,然后保持LED1和LED2常亮,LED3和LED4熄灭;K1连续按下奇数次时,四个灯按0.5秒(定时器中断实现)的间隔同时闪烁对应的次数,然后保持LED1和LED2熄灭,LED3和LED4常亮。K2按下时,四个灯按1秒(定时器中断实现)的间隔逐一点亮(同一个时刻只有个灯亮),并循环显示。K3按下时,四个灯按0.5秒(定时器中断实现)的间隔逐一点亮(同一个时刻只有一个灯亮),并循环显示。K4按下时,所有灯熄灭,系统进入初始状态。
  说明:程序需要区分连续按键与间隔时间按键。连续按键的间隔时间自行确定,合理即可示。

主要代码如下:
main.c

main.c:
#include "stdio.h"
#define GPKCON0 (*(volatile unsigned long *)0x7F008800)
#define GPKDAT (*(volatile unsigned long *)0x7F008808)

#define GPNCON (*(volatile unsigned long *)0x7F008830)
#define GPNDAT (*(volatile unsigned long *)0x7F008834)

#define GPFCON (*(volatile unsigned int *)0x7F0080A0)
#define GPFDAT (*(volatile unsigned int *)0x7F0080A4)

int COUNT;
void timer_init(unsigned long utimer, unsigned long uprescaler, unsigned long udivider, unsigned long utcntb, unsigned long utcmpb, int mode_x, int countk1_x);
void delay_short(volatile unsigned int n) {
    while (n--) {
    }
}
void delay(volatile unsigned int n) {
    while (n--) {
        delay_short(0x7ff);
    }

}
void buzzer_init(void)
{
    // set GPF14 as output
    GPFCON |= 1 << 28;
    GPFCON &= ~(1 << 29);
}

int main()
{

    int dat = 0;

    // 配置GPK4-7为输出功能
    GPKCON0 = 0x11110000;

    // 所有LED熄灭
    GPKDAT = 0x000000f0;

    // 配置GPN为输入功能
    GPNCON = 0;

    // 初始化buzzer
    buzzer_init();

    // 轮询的方式查询按键事件
    while (1)
    {
        dat = GPNDAT;
        if (dat & (1 << 0));
        else {
            // KEY1被按下
            // 设置定时器


            int countk1 = 0;
            int num = 1500000;

            while (num > 0)
            {

                //GPNDAT,低四位有效,哪位按下哪位为0
                if (!(GPNDAT & (1 << 0)))  //意思就是 若k1按下了 那么就进入if
                {
                    delay(10);
                    countk1++;             //按下一次 计数一次
                    num = 1500000;       //把倒计时还原
                    while (!(GPNDAT & (1 << 0))) { ; }
                }

                num--;


            }//while(num > 0)
            COUNT = countk1;
            if (countk1 % 2 == 1)
                timer_init(0, 65, 4, 31250, 0, 0, countk1);
            else if (countk1 % 2 == 0)
                timer_init(0, 65, 4, 62500, 0, 0, countk1);


            //if(GPNDAT & (1<<0))
            //{
            //	dat = 0xfd;
            //} 


        }
        if (dat & (1 << 1));
        else {
            // KEY2被按下
            // 设置定时器
            while (!(GPNDAT & (1 << 0))) { ; }
            int big = 0x6000000;
            while (big > 0)
                big--;
            timer_init(0, 65, 4, 62500, 0, 1, 0);

        }
        if (dat & (1 << 2));
        else
            // KEY3被按下
            // 设置定时器
        {
            while (!(GPNDAT & (1 << 0))) { ; }
            timer_init(0, 65, 4, 31250, 0, 2, 0);
        }

        if (dat & (1 << 3));
        else
            // KEY4被按下
            // 设置定时器
        {
            while (!(GPNDAT & (1 << 0))) { ; }
            int big = 0x6000000;
            while (big > 0)
                big--;
            timer_init(0, 65, 4, 31250, 0, 3, 0);

        }
    }
}

timer.c:

#include "stdio.h"
#define GPKCON0             (*((volatile unsigned long *)0x7F008800))
#define GPKDATA                 (*((volatile unsigned long *)0x7F008808))
#define GPKDAT              (*((volatile unsigned long *)0x7F008808))
#define EINT0CON0           (*((volatile unsigned long *)0x7F008900))
#define EINT0MASK           (*((volatile unsigned long *)0x7F008920))
#define EINT0PEND           (*((volatile unsigned long *)0x7F008924))
#define PRIORITY            (*((volatile unsigned long *)0x7F008280))
#define SERVICE             (*((volatile unsigned long *)0x7F008284))
#define SERVICEPEND         (*((volatile unsigned long *)0x7F008288))
#define VIC0IRQSTATUS       (*((volatile unsigned long *)0x71200000))
#define VIC0FIQSTATUS       (*((volatile unsigned long *)0x71200004))
#define VIC0RAWINTR         (*((volatile unsigned long *)0x71200008))
#define VIC0INTSELECT       (*((volatile unsigned long *)0x7120000c))
#define VIC0INTENABLE       (*((volatile unsigned long *)0x71200010))
#define VIC0INTENCLEAR      (*((volatile unsigned long *)0x71200014))
#define VIC0PROTECTION      (*((volatile unsigned long *)0x71200020))
#define VIC0SWPRIORITYMASK  (*((volatile unsigned long *)0x71200024))
#define VIC0PRIORITYDAISY   (*((volatile unsigned long *)0x71200028))
#define VIC0ADDRESS         (*((volatile unsigned long *)0x71200f00))

#define     PWMTIMER_BASE           (0x7F006000)
#define     TCFG0       ( *((volatile unsigned long *)(PWMTIMER_BASE+0x00)) )
#define     TCFG1       ( *((volatile unsigned long *)(PWMTIMER_BASE+0x04)) )
#define     TCON        ( *((volatile unsigned long *)(PWMTIMER_BASE+0x08)) )
#define     TCNTB0      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x0C)) )
#define     TCMPB0      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x10)) )
#define     TCNTO0      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x14)) )
#define     TCNTB1      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x18)) )
#define     TCMPB1      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x1C)) )
#define     TCNTO1      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x20)) )
#define     TCNTB2      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x24)) )
#define     TCMPB2      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x28)) )
#define     TCNTO2      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x2C)) )
#define     TCNTB3      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x30)) )
#define     TCMPB3      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x34)) )
#define     TCNTO3      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x38)) )
#define     TCNTB4      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x3C)) )
#define     TCNTO4      ( *((volatile unsigned long *)(PWMTIMER_BASE+0x40)) )
#define     TINT_CSTAT  ( *((volatile unsigned long *)(PWMTIMER_BASE+0x44)) )

#define GPFCON (*(volatile unsigned int *)0x7F0080A0)
#define GPFDAT (*(volatile unsigned int *)0x7F0080A4)
typedef void (isr)(void);
extern void asm_timer_irq();
extern int COUNT;
int mode;
int count;
int countk1;
void irq_init(void)
{
    /* 在中断控制器里使能timer0中断 */
    VIC0INTENABLE |= (1 << 23);

    VIC0INTSELECT = 0;

    isr** isr_array = (isr**)(0x7120015C);

    isr_array[0] = (isr*)asm_timer_irq;

    /*将GPK4-GPK7配置为输出口*/
    GPKCON0 = 0x11110000;

    //熄灭四个LED灯
    GPKDATA = 0xff;

    // set GPF14 as output
    GPFCON |= 1 << 28;
    GPFCON &= ~(1 << 29);
}
// timer0中断的中断处理函数
void do_irq()
{
    // K1对应的操作
    if (mode == 0)
    {

        if (countk1 <= 0)
        {
            if (COUNT % 2 == 0)
                GPKDATA = 0xc0;
            else
                GPKDATA = 0x30;
            //GPKDATA=0xff;
        }
        else
        {
            int label = count % 2;
            switch (label)
            {
            case 0:
                // 四个LED灯全部熄灭
                GPKDATA = 0xff;
                break;
            case 1:
                // 四个LED灯全部亮起
                GPKDATA = 0x0;
                countk1 = countk1 - 1;
                break;
            default:break;
            }
            count++;
        }




    }
    // K2对应的操作
    if (mode == 1)
    {
        int label = count % 4;
        switch (label)
        {
        case 0:
            // LED1 亮起,LED2、LED3、LED4熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 4);
            break;
        case 1:
            // LED2 亮起,LED1、LED3、LED4熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 5);
            break;
        case 2:
            // LED3 亮起,LED1、LED2、LED4熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 6);
            break;
        case 3:
            // LED4 亮起,LED1、LED2、LED3熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 7);
            break;
        default:break;
        }
        // count加一
        count++;
    }
    // K3对应的操作
    if (mode == 2)
    {
        int label = count % 4;
        switch (label)
        {
        case 0:
            // LED1 亮起,LED2、LED3、LED4熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 4);
            break;
        case 1:
            // LED2 亮起,LED1、LED3、LED4熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 5);
            break;
        case 2:
            // LED3 亮起,LED1、LED2、LED4熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 6);
            break;
        case 3:
            // LED4 亮起,LED1、LED2、LED3熄灭
            GPKDATA = 0xff;
            GPKDAT &= ~(1 << 7);
            break;
        default:break;
        }
        // count加一
        count++;
    }
    // K4对应的操作
    if (mode == 3)
    {
        GPKDATA = 0xff;
    }

    unsigned long uTmp;
    //清timer0的中断状态寄存器
    uTmp = TINT_CSTAT;
    TINT_CSTAT = uTmp;
    VIC0ADDRESS = 0x0;
}

// 初始化timer
void timer_init(unsigned long utimer, unsigned long uprescaler, unsigned long udivider, unsigned long utcntb, unsigned long utcmpb, int mode_x, int countk1_x)
{
    unsigned long temp0;
    // 设置mode值,用于判断执行哪一种操作
    mode = mode_x;
    countk1 = countk1_x;
    // 定时器的输入时钟 = PCLK / ( {prescaler value + 1} ) / {divider value} = PCLK/(65+1)/16=62500hz

    //设置预分频系数为66
    temp0 = TCFG0;
    temp0 = (temp0 & (~(0xff00ff))) | (uprescaler << 0);
    TCFG0 = temp0;

    // 16分频
    temp0 = TCFG1;
    temp0 = (temp0 & (~(0xf << 4 * utimer)) & (~(1 << 20))) | (udivider << 4 * utimer);
    TCFG1 = temp0;

    // 1s = 62500hz
    TCNTB0 = utcntb;
    TCMPB0 = utcmpb;

    // 手动更新
    TCON |= 1 << 1;

    // 清手动更新位
    TCON &= ~(1 << 1);

    // 自动加载和启动timer0
    TCON |= (1 << 0) | (1 << 3);

    // 使能timer0中断
    temp0 = TINT_CSTAT;
    temp0 = (temp0 & (~(1 << utimer))) | (1 << (utimer));
    TINT_CSTAT = temp0;
}



结果:

物联沃分享整理
物联沃-IOTWORD物联网 » 嵌入式系统课设:单按键控制LED灯

发表评论