使用库函数编程点亮开发板上的8只LED灯(使用位带和SysTick)。控制规律如下:
(1) 奇数的4只灯与偶数的4只灯交替点亮,间隔时间为1秒。(实验台编号为奇数的同学完成)
在完成第2的基础上,修改8只LED灯的控制规律,要求如下:
1只灯从左到右循环点亮,间隔时间为2秒。
参考GPT和自己的思路:
对于第一个问题,可以使用位带和SysTick定时器来控制8只LED灯的点亮。具体步骤如下:
初始化SysTick定时器,设置间隔时间为1秒。
定义一个数组,存储8只LED灯的状态,0表示灭,1表示亮。
定义两个变量,odd和even,分别表示奇数灯和偶数灯的当前状态,初始值都为0。
在SysTick中断中,每次触发时,先判断当前状态是奇数灯还是偶数灯,然后将对应的四只灯的状态取反。
更新奇数灯和偶数灯的状态。
将数组中的8个元素依次输出到LED灯上,即可实现奇数的4只灯与偶数的4只灯交替点亮,间隔时间为1秒。
对于第二个问题,需要在第一个问题的基础上再做一些修改。具体步骤如下:
修改SysTick定时器的间隔时间为2秒。
定义一个变量i,初始值为0,表示当前点亮的是第i只灯。
在SysTick中断中,每次触发时,将第i只灯的状态取反,并将i加1。如果i已经到达8,则将其重置为0,从第一只灯开始循环点亮。
将数组中的8个元素依次输出到LED灯上,即可实现1只灯从左到右循环点亮,间隔时间为2秒。
需要注意的是,在修改灯的状态时,可以使用位运算中的位带操作,可以更快速地实现状态的改变。同时,需要设置适当的时钟频率和计数器分频系数,以确保SysTick定时器的间隔时间精准。
参考GPT和自己的思路:
为实现奇数的4只灯与偶数的4只灯交替点亮,间隔时间为1秒,可以使用位带和SysTick进行编程控制。具体的代码实现可以参考以下示例代码:
// 定义8个LED的位带地址
#define LED0 (*((volatile unsigned long *)0x40010800))
#define LED1 (*((volatile unsigned long *)0x40010804))
#define LED2 (*((volatile unsigned long *)0x40010808))
#define LED3 (*((volatile unsigned long *)0x4001080C))
#define LED4 (*((volatile unsigned long *)0x40010810))
#define LED5 (*((volatile unsigned long *)0x40010814))
#define LED6 (*((volatile unsigned long *)0x40010818))
#define LED7 (*((volatile unsigned long *)0x4001081C))
// SysTick定时器初始化函数
void SysTick_Init(void) {
NVIC_ST_CTRL_R = 0; // 关闭SysTick定时器
NVIC_ST_RELOAD_R = 7999999; // 设定重装载值,对应1秒
NVIC_ST_CURRENT_R = 0; // 清空当前计数值
NVIC_SYS_PRI3_R |= 0x40000000; // 设置SysTick优先级为2,即最高优先级
NVIC_ST_CTRL_R |= 0x07; // 打开SysTick定时器,选择默认时钟源
}
// 奇偶数灯交替点亮函数
void LED_Control(void) {
static unsigned long cnt = 0;
cnt++;
if (cnt % 2) {
LED0 = 1;
LED2 = 1;
LED4 = 1;
LED6 = 1;
LED1 = 0;
LED3 = 0;
LED5 = 0;
LED7 = 0;
} else {
LED0 = 0;
LED2 = 0;
LED4 = 0;
LED6 = 0;
LED1 = 1;
LED3 = 1;
LED5 = 1;
LED7 = 1;
}
}
int main(void) {
// 初始化SysTick定时器
SysTick_Init();
// 循环执行LED灯控制函数
while (1) {
LED_Control();
while (!(NVIC_ST_CTRL_R & 0x10000)) {}
}
}
为实现1只灯从左到右循环点亮,间隔时间为2秒,可以在上述代码的基础上,加上一个计数器,实现按照指定的时间间隔点亮LED灯,具体的代码实现可以参考以下示例代码:
// 从左到右循环点亮,间隔时间为2秒
void LED_Control2(void) {
static unsigned long cnt1 = 0;
static unsigned long cnt2 = 0;
cnt1++;
if (cnt1 >= 2) {
cnt1 = 0;
cnt2++;
switch (cnt2) {
case 1:
LED0 = 1;
break;
case 2:
LED1 = 1;
break;
case 3:
LED2 = 1;
break;
case 4:
LED3 = 1;
break;
case 5:
LED4 = 1;
break;
case 6:
LED5 = 1;
break;
case 7:
LED6 = 1;
break;
case 8:
LED7 = 1;
break;
default:
LED0 = 0;
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
cnt2 = 0;
break;
}
}
}
其中,计数器cnt1用于控制每秒点亮的次数,计数器cnt2用于控制点亮的LED灯编号。在每2秒钟内,依次点亮LED0~LED7,点亮完毕后计数器cnt2复位为0,重新开始循环。