内容介绍
内容介绍
Funpack3-5 BeagleBone® Black 变频呼吸灯
项目描述
本项目基于 BeagleBone® Black 实现了一个变频呼吸灯,所有功能全部基于 BeagleBone® Black 裸板,无需其他外设
BeagleBone® Black 是一款面向开发人员和业余爱好者的低成本、高扩展、并有社区支持的开发平台。处理器选用了TI AM3358芯片,基于ARM Cortex-A8架构处理器。还配备了丰富的扩展资源,包括HDMI接口、以太网、SD 卡槽、并预留了足够多的管脚用于AD转换、LCD显示屏、PWM输出、I2C、串口等等。板卡可运行完整的 Linux 系统,且支持多种编程语言。
基本目标如下:
- 使用 PRU 控制一个 LED
- 需要实现呼吸灯效果
- 使用一个按键控制闪烁速度
硬件及软件
硬件原理图
本项目所需功能在 BeagleBone® Black 裸板上全集成了,因此硬件部分直接基于裸板即可:
基于上述原理图我们可以知道如下信息:
- 输入为 S2 ,对应的 IO 为 LCD_DATA2,即
P8_43
- 根据官方文档可知该 io 连接在 PRU1 上
- 输入为是个 led 中的任意一个即可,分别为:
- USR0:对应
GPIO1_21
- USR1:对应
GPIO1_22
- USR2:对应
GPIO1_23
- USR3:对应
GPIO1_24
- USR0:对应
软件 IO 适配
软件上我们需要配合硬件来操作,因此我们需要在 PRU 上编写代码前先关注下怎么配置 io
输入
对于输入 S2,由于上述硬件限制,因此我们只能够将程序放到 PRU1 上
又因为 S2 的输入刚好在 LCD 是 IO 上,BeagleBone® Black 中默认将这个 IO 作为了显示输出,如果我们需要在 PRU 中操作的话需要在 Linux 侧关闭原本输出功能
关闭 S2 的输出很简单,编辑板上 /boot/uEnv.txt
文件即可,将其中 disable_uboot_overlay_video=1
取消注释即可:
###Disable auto loading of virtual capes (emmc/video/wireless/adc)
#disable_uboot_overlay_emmc=1
# 就下面这句,取消注释即可
disable_uboot_overlay_video=1
#disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1
#disable_uboot_overlay_adc=1
此为,由于该 io 默认不是通过 PRU 控制,我们还需要在每次启动 PRU 程序前通过板载的 config-pin
将该 io 配置成 PRU 输入即可:
config-pin P8_43 pruin
config-pin -q P8_43
输出
对于输出的 LED 灯,默认这几个 LED 都被 Linux kernel 使用了:
cat /sys/class/leds/beaglebone\:green\:usr0/trigger
cat /sys/class/leds/beaglebone\:green\:usr1/trigger
cat /sys/class/leds/beaglebone\:green\:usr2/trigger
cat /sys/class/leds/beaglebone\:green\:usr3/trigger
因此我们需要在启动 PRU 程序前将其关闭。这里有两种方式关闭:
- 直接在启动 PRU 程序前通过自定义脚本往对应的节点里边关闭 Linux 的输出即可
- 借助官方提供的编译脚本来间接实现上述步骤
在这里我们可以直接采用第二种方式来实现,基本步骤就是在对应的 PRU 源码中插入如下语句即可:
#pragma DATA_SECTION(init_pins, ".init_pins")
#pragma RETAIN(init_pins)
const char init_pins[] =
"/sys/class/leds/beaglebone:green:usr0/trigger\0none\0" \
"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
"/sys/class/leds/beaglebone:green:usr3/trigger\0none\0" \
"\0\0";
- 编译脚本会自动提取上述信息并自动设置对应 Linux kernel 的 io
各功能对应的主要代码片段及说明
之后就是软件部分了,这部分的核心逻辑如下:
按键部分
uint8_t isEdgeTriggered() {
static uint8_t lastButtonState = 1;
if (((__R31 & USER_KEY2) != USER_KEY2) && lastButtonState == 1) {
delay_ms(100);
if (((__R31 & USER_KEY2) != USER_KEY2)) {
lastButtonState = 0;
return lastButtonState;
}
}
else if (((__R31 & USER_KEY2) == USER_KEY2) && lastButtonState == 0) {
lastButtonState = 1;
return lastButtonState;
}
return 2;
}
- 这部分主要的逻辑是通过 PRU 的
R31
寄存器从对应的 IO 口读取值 - 然后通过配合延时逻辑实现软件消抖,防止误触
- 最后通过一个静态变量实现边缘检测,在不同边沿返回不同的值,如果没有边沿则返回 2,方便其他逻辑
呼吸灯部分
void breathEffect(unsigned int delayTime) {
unsigned int i;
for (i = 0; i < STEP; i++) {
led(3, 1);
delay_us(i * delayTime / STEP);
led(3, 0);
delay_us((STEP - i) * delayTime / STEP);
}
for (i = STEP; i > 0; i--) {
led(3, 1);
delay_us(i * delayTime / STEP);
led(3, 0);
delay_us((STEP - i) * delayTime / STEP);
}
}
- 这部分逻辑通过传入的延时时间来控制对应的频率
- 同时也能够通过宏
STEP
来控制不同的步进,使得变频更加顺滑
总体逻辑
基本流程图如下:
对应的源码实现如下:
void main(void) {
unsigned int delayTime = SPEED_SLOW;
led_init();
led(0, 1);
led(1, 0);
led(2, 0);
while (1) {
if (isEdgeTriggered() == 1) {
if (delayTime == SPEED_FAST) {
delayTime = SPEED_SLOW;
led(0, 1);
led(1, 0);
led(2, 0);
} else if (delayTime == SPEED_SLOW) {
delayTime = SPEED_MEDIUM;
led(0, 0);
led(1, 1);
led(2, 0);
} else {
delayTime = SPEED_FAST;
led(0, 0);
led(1, 0);
led(2, 1);
}
}
breathEffect(delayTime);
}
}
- 这部分为总体逻辑部分,我们会在开始初始化 led0 ~ led2,用于显示当前的挡位信息
- 之后会通过按键检测切换不同的挡位,并亮起对应的 led
- 最后通过上述呼吸灯程序来点亮 led3
功能展示及说明
本项目最终效果如下:
- 通过下方 S2 开关切换挡位
- 上方右边三个 led 为挡位显示
- 上方最左边的 led 为对应控制的呼吸灯
对本活动的心得体会
本项目以 BeagleBone® Black 为核心,开发了一款变频呼吸灯,通过硬件与软件的结合,充分展示了嵌入式开发的魅力。在以下方面让我收获颇多:
- 技术层面
- 硬件资源的高效利用:通过合理配置 PRU(可编程实时单元)和 GPIO 管脚,最大程度发挥了硬件的潜力
- Linux 系统与 PRU 的结合:利用 PRU 实现高效的实时控制,充分体现了 Linux 系统的灵活性和实时性之间的平衡
- 软件逻辑的模块化设计:将按键检测、呼吸灯效果及主逻辑分别独立成模块,便于调试和扩展
- 实时控制能力的发挥:PRU 的高效性在呼吸灯的控制中得到了充分验证,通过精细的延时和步进调整,实现了顺滑的变频效果,表现出优秀的实时控制性能
- 实践能力提升
- 硬件与软件的协同开发能力:在硬件资源有限的情况下,需要结合硬件设计和软件调试,通过逐步排查和配置,实现对复杂功能的精准控制
- 动手调试能力的加强:从禁用 Linux 默认功能,到使用 config-pin 命令配置 IO,以及调试 LED 输出模式,整个过程强化了对嵌入式开发流程的理解和实践
- 嵌入式系统的深入理解:项目开发过程中,涉及到对 PRU 寄存器的直接操作和 Linux 系统层的配置,深刻体会到嵌入式系统底层设计的复杂性和精妙之处
总之,本项目从硬件、软件到调试,充分展示了嵌入式开发的魅力和挑战,为未来进一步探索嵌入式技术打下了良好的基础
附件下载
src.zip
团队介绍
暂无团队
评论
0 / 100
查看更多
猜你喜欢
Funpack3-5 基于BeagleBone® Black的LED呼吸灯该项目使用了BeagleBone® Black,实现了PRU上的LED呼吸灯的设计,它的主要功能为:按键可控呼吸灯速度。
raincorn
36
Funpack3-5 BeagleBone Black使用pru实现呼吸灯该项目使用了BeagleBone板以及c语言,实现了通过pru来点亮呼吸灯的设计,它的主要功能为:点灯!使用PRU控制一个LED实现呼吸灯,并且使用一个按键按下后切换闪烁的速度。
争奈争奈
78
Funpack3-5 BeagleBone Black PRU实现呼吸灯该项目使用了simppru语言,实现了beagleboneblack呼吸灯的设计,它的主要功能为:按键按下切换呼吸灯呼吸速率。
double_ninth
76