300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 【嵌入式系统课设】单个按键控制LED灯

【嵌入式系统课设】单个按键控制LED灯

时间:2023-05-14 00:00:55

相关推荐

【嵌入式系统课设】单个按键控制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 outputGPFCON |= 1 << 28;GPFCON &= ~(1 << 29);}int main(){int dat = 0;// 配置GPK4-7为输出功能GPKCON0 = 0x11110000;// 所有LED熄灭GPKDAT = 0x000000f0;// 配置GPN为输入功能GPNCON = 0;// 初始化buzzerbuzzer_init();// 轮询的方式查询按键事件while (1){dat = GPNDAT;if (dat & (1 << 0));else {// KEY1被按下// 设置定时器int countk1 = 0;int num = 1500000;while (num > 0){//GPNDAT,低四位有效,哪位按下哪位为0if (!(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))#definePWMTIMER_BASE (0x7F006000)#defineTCFG0 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x00)) )#defineTCFG1 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x04)) )#defineTCON ( *((volatile unsigned long *)(PWMTIMER_BASE+0x08)) )#defineTCNTB0( *((volatile unsigned long *)(PWMTIMER_BASE+0x0C)) )#defineTCMPB0( *((volatile unsigned long *)(PWMTIMER_BASE+0x10)) )#defineTCNTO0( *((volatile unsigned long *)(PWMTIMER_BASE+0x14)) )#defineTCNTB1( *((volatile unsigned long *)(PWMTIMER_BASE+0x18)) )#defineTCMPB1( *((volatile unsigned long *)(PWMTIMER_BASE+0x1C)) )#defineTCNTO1( *((volatile unsigned long *)(PWMTIMER_BASE+0x20)) )#defineTCNTB2( *((volatile unsigned long *)(PWMTIMER_BASE+0x24)) )#defineTCMPB2( *((volatile unsigned long *)(PWMTIMER_BASE+0x28)) )#defineTCNTO2( *((volatile unsigned long *)(PWMTIMER_BASE+0x2C)) )#defineTCNTB3( *((volatile unsigned long *)(PWMTIMER_BASE+0x30)) )#defineTCMPB3( *((volatile unsigned long *)(PWMTIMER_BASE+0x34)) )#defineTCNTO3( *((volatile unsigned long *)(PWMTIMER_BASE+0x38)) )#defineTCNTB4( *((volatile unsigned long *)(PWMTIMER_BASE+0x3C)) )#defineTCNTO4( *((volatile unsigned long *)(PWMTIMER_BASE+0x40)) )#defineTINT_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 outputGPFCON |= 1 << 28;GPFCON &= ~(1 << 29);}// timer0中断的中断处理函数void do_irq(){// K1对应的操作if (mode == 0){if (countk1 <= 0){if (COUNT % 2 == 0)GPKDATA = 0xc0;elseGPKDATA = 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;}// 初始化timervoid 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//设置预分频系数为66temp0 = TCFG0;temp0 = (temp0 & (~(0xff00ff))) | (uprescaler << 0);TCFG0 = temp0;// 16分频temp0 = TCFG1;temp0 = (temp0 & (~(0xf << 4 * utimer)) & (~(1 << 20))) | (udivider << 4 * utimer);TCFG1 = temp0;// 1s = 62500hzTCNTB0 = utcntb;TCMPB0 = utcmpb;// 手动更新TCON |= 1 << 1;// 清手动更新位TCON &= ~(1 << 1);// 自动加载和启动timer0TCON |= (1 << 0) | (1 << 3);// 使能timer0中断temp0 = TINT_CSTAT;temp0 = (temp0 & (~(1 << utimer))) | (1 << (utimer));TINT_CSTAT = temp0;}

结果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。