1、系统更新
使用USB连接连接上电脑之后,可以在电脑 设备和驱动器 位置看到一个新的盘符,进入到里面打开文件 START.HTM,按里面步骤把板卡系统更新为最新版本.
2、连接板卡并打开Visual Studio Code
更新系统之后,根据 Basics — BeagleBoard Documentation 里面指令
sudo systemctl start bb-code-server.service
打开板卡VSCode服务.之后即可正常访问VSCode
备注:命令需要打开ssh登录之后配置,连接上ssh之后会提示用户名和登录密码.
3, 通过网线使板卡连接互联网
参考链接 Beyond the Basics — BeagleBoard Documentation
4、获取 PRU示例代码
参考链接 Getting Example Code,并根据链接内容,查看是否能正常运行
5、功能实现
1)、硬件连接
硬件连接示意图如下
其中LED串联一个电阻连接至P9_30引脚,KEY通过一个下拉电阻连接至P9_27引脚
2)、程序框图
程序框图如下所示,基本为线性工作方式,每个循环去判断按键状态,并更新呼吸灯频率
3)、测试连接
编写input_setup.sh文件,配置PRU输入输出引脚(呼吸灯和按键)
#!/bin/bash
#
export TARGET=input.pru0
echo TARGET=$TARGET
# Configure the PRU pins based on which Beagle is running
echo " Black Found"
config-pin P9_30 pruout
config-pin -q P9_30
config-pin P9_27 pruin
config-pin -q P9_27
执行指令 source input_setup.sh,显示如下信息则配置正确
Current mode for P9_30 is: pruout
Current mode for P9_30 is: pruout
Current mode for P9_27 is: pruin
Current mode for P9_27 is: pruin
以上代码将P9_30配置为PRU输出引脚用以连接LED灯,P9_27配置为PRU输入引脚连接按键
通过如下代码input_pru0.c将KEY和LED连接,使用指令 make TARGET=input_pru0检测硬件是否正常
#include <stdint.h>
#include <pru_cfg.h>
#include "resource_table_empty.h"
volatile register uint32_t __R30;
volatile register uint32_t __R31;
void main(void)
{
uint32_t led;
uint32_t sw;
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
led = (1<<2); // P9_30
sw = (1<<5); // P9_11
while (1) {
if((__R31&sw) == sw) {
__R30 |= led; // Turn on LED
} else
__R30 &= ~led; // Turn off LED
}
}
4)、实现呼吸灯
一般呼吸灯的实现采用逐渐调整PWM占空比实现,但在BeagleBone 的PRU简单教材中没有发现关于PWM外设的教材,所以直接通过定时调整高低电平的方式实现呼吸灯
定义引脚宏定义
#define P9_30 (1<<2)
#define P9_27 (1<<5)
#define LED P9_30
#define KEY P9_27
a、创建一个延时函数,用作PWM延时
void delay_us(uint32_t us){
uint32_t i;
for(i=0; i<us; i++){
__delay_cycles(1000/5);
}
}
b、创建一个函数,实现一个PWM周期输出
/**
*pin:pwm的输出引脚
* freq: PWM的运行频率
*duuty:PWM占空比
*/
void showPwm(uint32_t pin, float freq, float duty)
{
//由于上面软件定时最小间隔为1us,这里定义1秒为多少us
uint32_t oneSecWaitTimes = (uint32_t)1000000; //1秒有1000 000微妙
//根据设定的PWM频率计算PWM时间周期,单位 us
uint32_t oneCycleTimes = (uint32_t)(oneSecWaitTimes / freq);
//根据占空比计算PWM高电平时间,单位us
uint32_t heightLevelTimes = (uint32_t)(oneCycleTimes * duty);
//一个PWM内低电平时长,单位us
uint32_t lowLevelTimes ;
//计算低电平时长 单位us
if(heightLevelTimes >= oneCycleTimes){
lowLevelTimes = 0;
}else if(heightLevelTimes <= 0){
lowLevelTimes = oneCycleTimes;
}else{
lowLevelTimes = oneCycleTimes - heightLevelTimes;
}
__R30 |= pin; // Turn on LED
delay_us(heightLevelTimes);
__R30 &= ~ pin; // Turn off LED
delay_us(lowLevelTimes);
}
c、创建一个按键读取函数,获取按键的输入状态
/**
*读取按键的状态,由于函数调用间隔跟pwm输出频率有关,所以此处需要输入pwm频率
*这里只检测按键是否按下,不考虑长按,双击等事件
*pin:key按键输入引脚
* freq: PWM的运行频率
*/
uint8_t key_scan(uint32_t pin, float freq)
{
static float pinPressedTimes = 0;
static float pinRelssedTimes = 0;
static uint8_t pressedFlag = 0;
//计算key_scan函数调用的间隔
float intervalTime = 1/freq;
if((__R31&pin) == pin) { //按键按下
pinRelssedTimes = 0;
pinPressedTimes += intervalTime;
//按键按下超过0.1S,置位按下标志
if((pinPressedTimes > 0.1) && (pressedFlag == 0)){
pressedFlag = 1;
}
}else{ //按键松开
pinPressedTimes = 0;
pinRelssedTimes += intervalTime;
//按键松开0.1S且按键按下标志为1,返回按键按下标志,这种方式只有在按键松开时才会返回按键按下事件
if((pressedFlag == 1) && (pinRelssedTimes > 0.1)){
pressedFlag = 0;
return 1;
}
}
return 0;
}
d、编写运行逻辑
void main(void)
{
float pwmFreq = 100.0; //PWM频率
float breathFreq = 0.5; //呼吸灯频率
float incDuty = 2*breathFreq / pwmFreq; //PWM占空比变化值
float pwmDuty = 0; //PWM初始占空比
uint8_t direction = 0; //呼吸灯方向
uint8_t keyState = 0; //按键状态
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
while (1) {
keyState = key_scan(KEY, pwmFreq); //获取按键状态
if(keyState == 1){ //按键按下
//处理按键信息
breathFreq *= 2; //呼吸灯呼吸频率*2
if(breathFreq > 10){
breathFreq = 0.2;
}
incDuty = 2*breathFreq / pwmFreq; //刷新占空比增量
}
if(direction == 0){ //逐渐变亮
pwmDuty += incDuty;
if(pwmDuty > 1){ //占空比达到最大,改变方向
pwmDuty = 1;
direction = 1;
}
}else{ //逐渐变暗
pwmDuty -= incDuty;
if(pwmDuty < 0){ //占空比达到最小,改变方向
pwmDuty = 0;
direction = 0;
}
}
showPwm(LED, pwmFreq,pwmDuty); //pwm输出
}
}
心得体会
由于之前基本都没有接触过linux,在最开始没有了解PRU时做了很多心理准备,中间拖了很长时间,后面发现如果只是简单实现功能,不需要linux也可以实现,减少了很多压力,很多事情还是需要上手才知道具体难度。