作业|学习资料

Keil新建工程及系统复位

凝神长老 · 11月18日 · 2018年 · · · · · · · 1638次已读

本文写于 2018年11月18日,距今已超过 1 年,距 2020年03月27日 的最后一次修改也已超过 3 个月,部分内容可能已经过时,您可以按需阅读。如果图片无法显示或者下载链接失效,请给我反馈,谢谢!


工程06_01 :

简单描述按压 reset 按键后的实验现象

按压 reset 键后,复位,重新回到红灯长亮、长灭,随后继续进入周期性闪烁。

代码中,首先写出红灯点亮、Delay、熄灭、Delay的代码,然后在一个无限循环中给出周期性闪烁的代码。

本题的关键在于设置工程,这一点在PPT中已经讲清楚了。

需要注意的是,添加lib或者s的时候,可能需要选择文件类型才能正确显示。

以及,这里也需要勾选:

而不仅仅是:

观察得到现象,红灯长亮、长灭、随后周期性短暂闪烁。

任意时刻按下复位,重新回到红灯长亮、长灭、随后周期性短暂闪烁

工程06_02:

描述红色LED1闪烁变化情况;若能改进该方法,请描述。

首先会绿灯亮2次,然后进入红灯快速闪烁。

如果没有按键,那么,红灯会以非常快的速度周期性地闪烁。

随着每按下一个按键,斐波那契数列会飞快地增长,红灯亮起和熄灭的时间间隔变长,即红灯周期性闪烁的周期变长。

如果继续按下按键,延迟的时间超过2秒,看门狗没有了“喂狗”操作,会复位,此时恢复到绿灯闪烁2次、然后红灯飞快闪烁的情况。

代码有改进的余地。

首先要分析问题的根源。

问题是出在了

if (GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN1) == GPIO_INPUT_PIN_LOW)

于是,程序只有运行到这里的短暂瞬间才会判断按键是不是被按下。

那么假设现在的Delay非常非常长,如果程序正在执行Delay的空循环,就不会做到这句if,也就不会响应按键。

所以,不能通过按键的电平判断。

怎么办呢?

中断!

如果我们定义了一个中断信号,当按键P1.1被按下的时候,能够触发中断,然后去执行斐波那契数列相加,之后再回到正常的业务逻辑就好了。

假设我们已经定义了这样一个中断,那么中断的处理过程就非常简单:

count = f0 + f1;
f0 = f1;
f1 = count;

关键在于,中断怎么定义,首先我们要定义中断的信号源为按钮P1.1,然后要允许中断。

// Configuring P1.1 as an input and enabling interrupts 
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
MAP_Interrupt_enableInterrupt(INT_PORT1);

然后要做一些有关于地址重映射的操作。

/* Enabling SRAM Bank Retention */
MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
/* Enabling MASTER interrupts */
MAP_Interrupt_enableMaster();
MAP_WDT_A_startTimer();

最后,在中断处理程序中写入:

/* GPIO ISR */
void PORT1_IRQHandler(void)
{
    uint32_t status;

    status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

    if(status & GPIO_PIN1)
    {
        //GPIO_setAsOutputPin(GPIO_PORT_P2,GPIO_PIN2);
        //GPIO_toggleOutputOnPin(GPIO_PORT_P2,GPIO_PIN2);
        count = f0 + f1;
        f0 = f1;
        f1 = count;
        MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
    }
}

完整代码见下文。

那么,完成修改以后,就不再需要这段话了。

if (GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN1) == GPIO_INPUT_PIN_LOW)
        {
            ;//请将count数值按照斐波那契数列增大
            count = f0 + f1;
            f0 = f1;
            f1 = count;
            // 改进以后则不再需要这里判断
        }

取而代之的是中断处理程序。

为了确认程序确实是进入了中断处理程序,我们可以在中断处理程序点个灯看看。

我选择了蓝灯,每进入一次中断处理程序,蓝灯翻转。

由此,每按下一个按键,不仅红灯闪烁的间隔会加长,而且能观察到蓝灯随着按键按下会点亮或熄灭。

   if(status & GPIO_PIN1)
    {
        // 为了便于观察确实进去了中断处理程序,可以开一个灯看看,我开了一个蓝灯
        //GPIO_setAsOutputPin(GPIO_PORT_P2,GPIO_PIN2);
        //GPIO_toggleOutputOnPin(GPIO_PORT_P2,GPIO_PIN2);

工程06_03:

描述实验现象

在不执行Decode函数的时候,或者说,Decode函数永远返回0,那么,程序就不会执行,那么,首先会红灯长时间闪烁,然后进入快速闪烁。

如果执行了Decode,那么按照题目描述,最终会计算到123,也就是,会触发复位,由此,红灯会始终长时间闪烁,然后复位,长时间闪烁……不会进入快闪烁。

该程序的重点在于求出123。

只要按照要求模拟,即,每次取出一位数,判断是奇数还是偶数,然后对应的计数器加1。

取出每一位数可以用 x % 10 来解决,直到 num 为0。

当计数完成,按照偶-奇-总的顺序排列,即:

num = even * 100 + odd * 10 + total;

怎么判断是不是到了123?

只要再对数字做一次上面的操作,操作前后数字不变,说明就是123。

while (prev != num);

核心代码:

0 0 投票
文章评分
订阅评论动态
提醒
guest
17 评论
最新
最旧 得票最多
行内反馈
查看所有评论
藤原千花书记
藤原千花书记 Chrome 74.0.3729.169 Windows 7
2019年12月22日 21:25

大佬

ILoveChina
ILoveChina Chrome 78.0.3904.108 Windows 10
2019年11月27日 10:48

da lao nb

tal
tal Firefox 70.0 Windows 10
2019年11月18日 15:26

tql

垃圾蒟蒻
垃圾蒟蒻 Chrome 75.0.3770.100 Windows 10
2019年11月16日 23:04

太强了

aix
aix Chrome 78.0.3904.97 Windows 10
2019年11月10日 09:33

tql

1
1 Chrome 78.0.3904.70 Windows 10
2019年11月10日 08:44

666

zzjs
zzjs Edge 18.18362 Windows 10
2019年11月9日 15:13

6

1
1 Edge 18.18362 Windows 10
2019年10月31日 09:12

1

jack
jack Chrome 77.0.3865.90 Windows 10
2019年10月30日 16:28

tql

jack
jack QQ浏览器 9.8 Android 9 | HUAWEI HMA-AL00
2019年10月30日 16:19

tql

L
L Chrome 69.0.3497.92 Windows 10
2018年12月28日 23:35

谢谢!

昵称可以随便取诶
昵称可以随便取诶 Chrome 70.0.3538.102 Windows 10
2018年11月25日 13:20

测试一下昵称是不是可以随便取的

www
www Chrome 70.0.3538.102 Windows 10
2018年11月24日 10:55

tql

小菜鸡
小菜鸡 Chrome 65.0.3325.181 Windows 10
2018年11月18日 19:03

num = even * 100 + odd * 10 + total; 这里要是odd和total不是1位数呢

luxuantao
luxuantao Chrome 70.0.3538.102 Windows 10
2018年11月18日 17:56

一定要评论过分了