一.项目介绍
本项目是基于Funpack活动完成的,使用的硬件平台是BeagleBone® Black开发板,这是一款面向开发人员和业余爱好者的低成本、高扩展、并有社区支持的开发平台。处理器选用了TI AM3358芯片,基于ARM Cortex-A8架构处理器。还配备了丰富的扩展资源,包括HDMI接口、以太网、SD 卡槽、并预留了足够多的管脚用于AD转换、LCD显示屏、PWM输出、I2C、串口等等。板卡可运行完整的 Linux 系统,且支持多种编程语言。
本项目实现的功能是使用PRU控制一个LED实现呼吸灯,并且使用一个按键按下后可以切换闪烁的速度。
二.设计思路
要实现通过按键可以切换LED闪烁速度需要使用PRU的两个通道,一个用于生成PWM信号控制LED,另一个用于检测按键状态。所以我使用了P9.27作为PRU的输入,检测按键状态;使用了P9.30作为PRU的输出,生成PWM信号控制LED。如果检测到按钮被按下,更新按钮状态,并增加延时循环的次数,使LED闪烁速度减慢。如果延时循环的次数超过上限,则重置为初始值。
三.硬件介绍
BeagleBone Black 是一款面向开发人员和业余爱好者的低成本、高扩展、社区支持的开发平台,板卡处理器选用的是 TI 公司 AM3358 芯片, 处理器集成了高达 1GHz 的 ARM Cortex™ A8 内核,具有强大的处理能力并提供了丰富的外设接口。BeagleBone® Black面向开源社区用户、开源硬件爱好者和任何对Arm Cortex-A8低成本处理器感兴趣的人而设计,配备精简,旨在为不需要搭建完整开发平台并想体验Arm处理器功能的用户提供入门的捷径。它配备了最低限度的外设,使用户能够体验处理器的强大功能,还提供了许多接口,用户还可以开发自己的电路板或添加自己的电路。
特性
- 处理器 TI Sitara 处理器:AM3358BZCZ100
- 1GHz ARM® Cortex-A8 处理器
- SGX 3D 图形引擎
- NEON 浮点加速器
- 2×32 位 200MHz 可编程实时单元 (PRU)
- 内存
- SDRAM:512MB DDR3L 800MHZ
- 板载闪存:4GB,8 位嵌入式 MMC (eMMC)
- 电源管理:使用 TPS65217C PMIC 和单独的 LDO 为系统供电
- 调试支持: 可选板载 20 引脚 CTI JTAG、串行接头
- 电源
- miniUSB接口或直流插孔
- 通过扩展头提供 5VDC 外部电源
- 接口
- 高速 USB 2.0 客户端端口: 通过 miniUSB 访问 USB0,客户端模式
- 高速 USB 2.0 主机端口: 访问 USB1,A 型插座,500mA LS/FS/HS
- 串行端口: UART0 通过 6 针 3.3V TTL 接头访问。接头已填充
- 10/100M 以太网接口(RJ45)
- 用户输入/输出
- 复位按钮
- 启动按钮
- 电源按钮
- LED 电源指示灯
- 4 个用户可配置的 LED
- 视频/音频接口
- HDMI D 型接口
- LCD 接口
- HDMI 接口立体声音频
- 2x 46 针针座扩展接口
- LCD、UART、eMMC
- ADC、I2C、SPI、PWM
微控制器:Sitara AM3358BZCZ100
AM335x 微处理器以 ARM Cortex-A8 处理器为基础,通过图像、图形处理、外设以及 EtherCAT 和 PROFIBUS 等工业接口选件得到增强。 这些设备支持高级操作系统(HLOS)。 处理器 SDK Linux® 和 TI-RTOS 可从 TI 免费获得。 AM335x 微处理器包含功能框图所示的子系统: 微处理器单元 (MPU) 子系统基于 ARM Cortex-A8 处理器,PowerVR SGX™ 图形加速器子系统提供 3D 图形加速,支持显示和游戏效果。
PRU-ICSS 与 ARM 内核分离,允许独立运行和时钟,从而提高了效率和灵活性。PRU-ICSS 支持额外的外设接口和实时协议,如 EtherCAT、PROFINET、EtherNet/IP、PROFIBUS、Ethernet Powerlink、Sercos 等。此外,PRU-ICSS 的可编程特性及其对引脚、事件和所有片上系统 (SoC) 资源的访问,为实现快速、实时响应、专用数据处理操作、定制外设接口以及卸载 SoC 其他处理器内核的任务提供了灵活性。
板卡关键器件电路板布局:
BeagleBone Black的处理器、存储器等芯片型号如下:
- 板载处理器:Sitara AM3358BZCZ100
- 双数据速率RAM存储器:美光512MB DDR3L
- TPS65217C PMIC 为电路板上的各种元件提供电源轨
- SMSC 以太网 PHY 是网络的物理接口
- 板载 MMC 芯片 Micron eMMC ,最多可存储 4GB 数据
- HDMI framer可通过适配器控制HDMI或DVI-D显示
板卡连接器、LED 和按键的布局:
- 5V直流电源输入
- 电源按钮提醒处理器启动断电序列,并用于关闭电路板的电源
- 110/100以太网与LAN连接
- Serial Debug 串行调试端口
- USB 接口可与 PC 的miniUSB 连接,并为开发板供电
- 如果板上的电源已关闭,则BOOT开关可用于强制从microSD卡引导,断开电源并重新为板上加电
- 有四个蓝色 LED 可供用户使用
- Reset按钮允许用户重置处理器
- microSD 插槽是可安装 microSD卡
- micro HDMI 显示器接口
- USB Host可以连接不同USB接口,例如Wi-Fi、BT、键盘等
板卡框图
四.功能介绍
这个程序的功能可以使用PRU控制一个LED实现呼吸灯,并且使用一个按键按下后切换闪烁的速度。
运行程序:首先要更改为要运行的代码的目录,比如我的目录是opt/source/pru-cookbook-code/06io,那么就使用cd命令切换到这个目录:
bone$ cd opt/source/pru-cookbook-code/06io
然后在终端控制窗口输入source setup.sh配置文件
source setup.sh
之后再输入make就可以运行了。具体参考pru-cookbook 运行程序
这个是运行起来后的窗口,输入代码
cat /sys/class/remoteproc/remoteproc1/state
可以查看pru是否正在运行。
这个是使用PRU控制一个LED实现呼吸灯的实物图。
五.主要代码
在setup.sh文件中需要对使用的引脚进行配置:配置P9_30引脚为PRU输出,配置P9_27引脚为PRU输入
if [ $machine = "Black" ]; then
echo " Found"
config-pin P9_30 pruout
config-pin -q P9_30
config-pin P9_27 pruin
config-pin -q P9_27
然后在.C文件里面编写下面的代码,代码的主要功能是:
1、配置PRU:通过设置系统控制寄存器,禁止PRU进入待机模式。
2、初始化变量:
delay_cycles
:控制LED闪烁速度的延时循环次数。
previous_ButtonState
:存储上一次按键P9_27的状态。
3、主循环:程序在一个无限循环中运行,不断检测按键状态并控制LED。
4、按键检测:
如果按键未被按下且检测到按键被按下(P9_27为高电平),则增加delay_cycles
的值,使LED闪烁速度减慢。
如果按键已经被按下且检测到按键未被按下,则重置previous_ButtonState
。
5、LED控制:
使用__R30
寄存器的P9_30位来切换LED的状态,实现闪烁效果。
6、延时实现:
通过一个简单的循环计数来实现延时,控制LED的闪烁间隔。
7、速度切换:
每次按键按下时,delay_cycles
翻倍,超过上限则重置为初始值,从而实现不同的闪烁速度。
#include <stdint.h> // 包含标准整数类型定义
#include <pru_cfg.h> // 包含PRU配置相关的头文件
#include "resource_table_empty.h" // 包含资源表的头文件
#include "prugpio.h" // 包含PRU GPIO操作的头文件
// 定义两个易失性寄存器变量,用于访问PRU的寄存器
volatile register unsigned int __R30;
volatile register unsigned int __R31;
void main(void)
{
// 配置系统控制寄存器,禁止PRU进入待机模式
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
// 定义延时循环的次数,用于控制LED闪烁的速度
uint32_t delay_cycles = 5000000;
// 定义一个变量来存储上一次按钮的状态
uint32_t previous_ButtonState = 0;
// 主循环
while (1)
{
// 如果当前按钮状态未被按下(即previous_ButtonState为0)
if (!previous_ButtonState)
{
// 如果检测到按钮被按下(P9.27为高电平)
if (__R31 & P9_27)
{
// 更新按钮状态
previous_ButtonState = 1;
// 增加延时循环的次数,使LED闪烁速度减慢
delay_cycles = delay_cycles * 2;
// 如果延时循环的次数超过上限,则重置为初始值
if (delay_cycles > 50000000)
{
delay_cycles = 5000000;
}
}
}
else
{
// 如果按钮未被按下,则更新按钮状态
if (!(__R31 & P9_27))
{
previous_ButtonState = 0;
}
}
// 切换P9.30引脚的状态,控制LED的开关
__R30 ^= P9_30;
// 定义一个计数器变量
uint32_t counter = 0;
// 延时循环,通过循环计数来实现延时效果
while (counter < delay_cycles)
{
counter++;
}
}
}
六.注意事项
如果你尝试在BeagleBone Black的接口上配置一些引脚时,收到错误:
bone$ *config-pin P9_30 pruout*
ERROR: open() for /sys/devices/platform/ocp/ocp:P9_30_pinmux/state failed, No such file or directory
这是因为在BeagleBone Black的镜像上,HDMI显示驱动程序默认启用,并使用许多引脚。可以通过编辑boot/uEnv.txt来禁用它。
bone$ sudo vi /boot/uEnv.txt
取消注释与要禁用的设备对应的行,并释放其 pin。
###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
之后就可以正常使用这些pin了。参考pru-cookbook 访问更多IO
七.心得体会
在本次的Funpack活动中,我有机会深入探索了BeagleBone开发板的PRU功能,并且成功实现了一个LED呼吸灯项目。通过这次实践,我更加深刻地理解了如何将硬件引脚与软件程序相结合,以及如何通过编程来控制硬件设备。PRU作为一个独立的实时处理单元,让我体会到了实时控制硬件的能力。通过编写PRU程序,我学会了如何精确控制硬件引脚的电平变化。在编写程序和调试过程中,我遇到了不少问题,比如引脚配置错误、环境配置错误等。通过解决这些问题,我的问题分析和解决能力得到了提升。总结来说,这次Funpack活动不仅增强了我的技术能力,也提高了我解决实际问题的能力。这是一个宝贵的学习经历。非常感谢硬禾学堂和DigiKey举办的这个活动,让我收获很多。