当前位置:网站首页>【嵌入式系统课设】单个按键控制LED灯
【嵌入式系统课设】单个按键控制LED灯
2022-07-01 22:12:00 【march of Time】
合工大嵌入式系统课程设计
设计要求:
根据单个按键输入情况控制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;
}
结果:
边栏推荐
- Unable to climb hill sort, directly insert sort
- 转--利用C语言中的setjmp和longjmp,来实现异常捕获和协程
- The fixed assets management subsystem reports are divided into what categories and which accounts are included
- 激发新动能 多地发力数字经济
- 工作中非常重要的测试策略,你大概没注意过吧
- 今日睡眠质量记录71分
- [JUC learning road day 8] condition
- Talk about what parameters ZABBIX monitors
- Kubernetes create service access pod
- SAP 智能机器人流程自动化(iRPA)解决方案分享
猜你喜欢
Appium自动化测试基础 — APPium安装(一)
Kubernetes create service access pod
I graduated from college in 14 years and changed to software testing in 3 months. My monthly salary was 13.5k. At the age of 32, I finally found the right direction
元宇宙可能成为互联网发展的新方向
The fixed assets management subsystem reports are divided into what categories and which accounts are included
Share some feelings of a programmer who has experienced layoffs twice a year
SAP UI5 应用开发教程之一百零四 - SAP UI5 表格控件的支持复选(Multi-Select)以及如何用代码一次选中多个表格行项目
工作中非常重要的测试策略,你大概没注意过吧
思科考试--路由的概念和配置考试
今日睡眠质量记录71分
随机推荐
I graduated from college in 14 years and changed to software testing in 3 months. My monthly salary was 13.5k. At the age of 32, I finally found the right direction
rxjs Observable of 操作符的单步调试分析
Deep learning -- data operation
Mixconv code
人体姿态估计的热图变成坐标点的两种方案
MySQL5.7 设置密码策略(等保三级密码改造)
好友新书发布,祝贺(送福利)
nn. Parameter] pytoch feature fusion adaptive weight setting (learnable weight use)
Cisco exam -- redundant network
Fiori applications are shared through the enhancement of adaptation project
Mysql5.7 set password policy (etc. three-level password transformation)
internal field separator
Share some feelings of a programmer who has experienced layoffs twice a year
Turn -- go deep into Lua scripting language, so that you can thoroughly understand the debugging principle
Origin2018 installation tutorial "recommended collection"
Flink SQL command line connection yarn
The median salary of TSMC's global employees is about 460000, and the CEO is about 8.99 million; Apple raised the price of iPhone in Japan; VIM 9.0 release | geek headlines
Reprint CSDN article operation
Fiori 应用通过 Adaptation Project 的增强方式分享
tcpdump命令使用详解