工程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);
核心代码:
666
6
1
tql
tql
谢谢!
测试一下昵称是不是可以随便取的
tql
num = even * 100 + odd * 10 + total; 这里要是odd和total不是1位数呢
@小菜鸡10000 以内的随机数,怎么可能不是 1 位数…… 当然你说的很对,应该考虑这 3 个数依次拼接起来才是正确的。
一定要评论过分了
@luxuantao好吧,那就 Public Visible 好了。