Funpack3-5:BeagleBone® Black 任务1:使用PRU点灯!
该项目使用了BeagleBone® Black,实现了使用PRU点灯的设计,它的主要功能为:使用C语言实现PRU控制一个LED实现呼吸灯,并且使用一个按键按下后切换闪烁的速度。。
标签
嵌入式系统
Funpack活动
开发板
PRU
Jahg
更新2025-01-15
28

本项目使用BeagleBone® Black板卡,简称BBB板,实现点灯操作,是Funpack3-5的BeagleBone® Black板卡的任务一。

本项目的主要难点在于需要使用PRU实现呼吸灯的操作,以及接收外部按键输入,切换呼吸灯的闪烁频率。


完成项目的第一步是熟悉板卡。BeagleBone® Black板卡是一个老板卡,应该有10+年,所以资料还是很齐全的,而且网上教程很多,同时板子自带的系统也很完备。

拿到板卡后,意外发现插上usb接口后,会在本地生成一个IP地址,能够直接通过IP地址访问系统,同时还可以直接使用cloud9的IDE进行程序编辑和编译下载操作。

熟悉系统后,发现系统内已经自带PRU的demo工程,可以直接编译成功,这就节省了大家编译环境和完成hello world的时间。

基于此,为了完成任务1:点灯!使用PRU控制一个LED实现呼吸灯,并且使用一个按键按下后切换闪烁的速度。需要进行需求的拆解。


任务拆解如下:

1)调用PRU进行GPIO的输出控制;

2)调用PRU进行GPIO的输入捕捉;

3)对输出进行逻辑控制,实现呼吸灯效果;

4)实现对呼吸灯效果的频率控制;

5)结合GPIO的输入捕捉和输出控制,完成任务描述的所有内容。


对于需求1):使用cloud9的demo工程:blinkInternalLED.pru0.c,确认点亮LED灯效果;


对于需求2):使用clude9的demo工程:blinkR30.pru0.c,进行修改,主要修改点为:重新配置输入捕捉的端口为P9_14,实现LED灯亮灭的功能。


对于需求3):使用cloud9的demo工程:blinkInternalLED.pru0.c,进行修改,主要修改点为:使用for循环控制点亮LED灯的delay周期和熄灭LED灯的delay周期。主要修改代码如下:

            gpio1[GPIO_CLEARDATAOUT] = USR3;    // Turn USR2 LED off
           
            for(i = 0; i < u8index; i++)
            {
                __delay_cycles(500000000/500000);    // Wait 1/200000 second
            }
           
                gpio1[GPIO_SETDATAOUT]   = USR3;    // On
           
            for(i = 200; i > u8index; i--)
            {
                __delay_cycles(500000000/500000);    // Wait 1/200000 second
            }


对于需求4):基于需求3)工程,进行修改,主要修改点为:增加外部for循环,实现对呼吸灯步进频率的控制;

//呼吸灯频率控制部分
        for(j = 0; j < 100; j++)// 100 cycle
        {
       
            gpio1[GPIO_CLEARDATAOUT] = USR3;    // Turn USR2 LED off
           
            for(i = 0; i < u8index; i++)
            {
                __delay_cycles(500000000/500000);    // Wait 1/200000 second
            }
           
            gpio1[GPIO_SETDATAOUT]   = USR3;    // On
           
            for(i = 200; i > u8index; i--)
            {
                __delay_cycles(500000000/500000);    // Wait 1/200000 second
            }
        }
       
        u8index = u8index + u16FreqCtrl;//PWM speed control
        if(u8index > 200)
        u8index = 1;


对于需求5):结合需求4)和需求2)的工程,捕捉P9_14端口的输入,进行防抖处理,并对控制步进频率的变量进行切换;

        if(~gpio1[SWITCHIN]&P9_14) //if P19_14 low,sw is press
        {
            u8PressCounter ++;
       
            if(u8PressCounter > ENUM_PRESS_FILTER) //Filter
            {
                u8PressCounter = 0;
               
                if(u8CurrentSWSts == ENUM_SW_STS_ONE)//switch status
                {
                    u16FreqCtrl = ENUM_FREQ_CTRL_HIGH;
                    u8CurrentSWSts = ENUM_SW_STS_TWO;
                }
                else if(u8CurrentSWSts == ENUM_SW_STS_TWO)
                {
                    u16FreqCtrl = ENUM_FREQ_CTRL_LOW;
                    u8CurrentSWSts = ENUM_SW_STS_ONE;
                }
            }
        }


基于以上软件需求,结合外部电路,完成本次任务。


硬件连接图如下:


电路图.jpg



电路连接实物图.jpg

任务效果如下描述:

首先呼吸灯慢闪,按下按键后,USR3灯切换为呼吸快闪,再次按下按键后,USR3灯切换为呼吸慢闪;按下一次按键,呼吸灯的频率切换一次。


软件流程图如下:


主体代码如下:

////////////////////////////////////////
//  JahgFunPackFinal.pru0.c
//  Blinks USR3 USR LED using the PRU with PWM contral,use P9_14 to switch the Blinks Freq
//  Wiring: None
//  Setup:  Turn off the USR LEDs triggers
//  See:    prugpio.h to see to which ports the USR LEDs are attached
//  PRU:    Any
//  Author: Jahg  20241215  Ver1.0
////////////////////////////////////////
#include <stdint.h>
#include <pru_cfg.h>
#include "resource_table_empty.h"
#include "prugpio.h"


//Just remember that __R30 is for outputs and __R31 is for inputs.
volatile register unsigned int __R30;
volatile register unsigned int __R31;


#define SWITCHIN 0x138/4


#define ENUM_PRESS_FILTER 0x1


#define ENUM_SW_STS_ONE 0x1
#define ENUM_SW_STS_TWO 0x2


#define ENUM_FREQ_CTRL_HIGH 0x30
#define ENUM_FREQ_CTRL_LOW 0x8



void main(void) {
    // Points to the two GPIO ports that are used
    uint32_t *gpio1 = (uint32_t *)GPIO1;


    /* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
    CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
   
    uint8_t u8index = 255;
    uint16_t u16FreqCtrl = 5;
    uint8_t i = 0;
    uint16_t j = 0;
   
    uint8_t u8CurrentSWSts = 0x1;
    uint8_t u8PressCounter = 0x0;



    while(1) {
       
        if(~gpio1[SWITCHIN]&P9_14) //if P19_14 low,sw is press
        {
            u8PressCounter ++;
       
            if(u8PressCounter > ENUM_PRESS_FILTER) //Filter
            {
                u8PressCounter = 0;
               
                if(u8CurrentSWSts == ENUM_SW_STS_ONE)//switch status
                {
                    u16FreqCtrl = ENUM_FREQ_CTRL_HIGH;
                    u8CurrentSWSts = ENUM_SW_STS_TWO;
                }
                else if(u8CurrentSWSts == ENUM_SW_STS_TWO)
                {
                    u16FreqCtrl = ENUM_FREQ_CTRL_LOW;
                    u8CurrentSWSts = ENUM_SW_STS_ONE;
                }
            }
        }


       
        //呼吸灯频率控制部分
        for(j = 0; j < 100; j++)// 100 cycle
        {
       
            gpio1[GPIO_CLEARDATAOUT] = USR3;    // Turn USR2 LED off


           
           
            for(i = 0; i < u8index; i++)
            {
                __delay_cycles(500000000/500000);    // Wait 1/200000 second
            }
           
                gpio1[GPIO_SETDATAOUT]   = USR3;    // On


           
            for(i = 200; i > u8index; i--)
            {
                __delay_cycles(500000000/500000);    // Wait 1/200000 second
            }
       
        }
       
        u8index = u8index + u16FreqCtrl;//PWM speed control
        if(u8index > 200)
        u8index = 1;
       
    }
    __halt();
}


// Turns off triggers
#pragma DATA_SECTION(init_pins, ".init_pins")
#pragma RETAIN(init_pins)
const char init_pins[] =  
    "/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
    "/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
    "\0\0";


总结:

通过本次任务,熟悉了BBB板卡的设计,查阅了很多资料,了解了BBB板卡的设计目标是为了软硬件爱好者和开发人员的使用,所以开源了很多硬件及软件的资料。虽然使用的Ti芯片很老,但是由于里面集成了PRU,可玩性还是很高的。通过PRU控制的PWM波形,通过示波器观察,波形十分稳定,实现的1ms的PWM波形非常漂亮。BBB的硬件设计也很棒,板卡简洁小巧,丝印标识清晰,做工扎实,对应的硬件资料也十分丰富。同时,板卡的上手非常简单,由于自带了EMMC,收到板卡后立即可以使用,使用USB线接入电脑,通过本地IP地址就可访问,非常方便。比起树莓派来说,虽然性能不及,但是易用性,硬件资料的丰富性都是远远强于树莓派的。

附件下载
JahgFunPackFinal.pru0.c
程序代码
团队介绍
个人作品
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号