• Blackfin DSP(二):寄存器操作与GPIO


      BlackfinDSP的寄存器是通过指针操作的,与51、ARM等MCU一样,通过“或”操作来置1,通过“与”操作清零。

      在DSP上最简单的外设非IO口莫属,但是由于其功能强大,远非一般IO口可比,因此区别的称之为“GPIO”(general purpose IO),也称为PF(programmable flagas)口,本文通过GPIO控制LED来演示寄存器的操作方式。

    //===============      开发环境         ======================

      上位机: win7 旗舰版

          DSP环境: CCES1.0.2  (用Blackfin DSP第一节:新建工程一文中的Visual DSP++完全一样)

          开发板   : ADSP-BF561 EZKIT(用561的原因是,手头的533EZKIT的GPIO连接到了FLASH上,想驱动LED,必须先对FLASH进行操作,比较麻烦,以后会尽量采           用533,虽然用561,但是操作方式是一致的,只不过寄存器的定义不同)   

    //================    原理图             =====================

      由图可见,LED1~LED8分别连接在PF40~PF47口,当PFx输出为高电平时,可点亮相应的LED。

    //================    寄存器定义             =====================

    1.方向寄存器(参考Hardware reference)

    首先,必须将PFx的方向设置为输出;

    2.设置输出电平

    输出高电平是通过FLAG_SET寄存器来进行设置的,在相应的位写1,即可设置为高电平。定义如下:

    输出低电平是通过FLAG_CLEAR寄存器实现,写1清除相应的端口电平值。(图就不贴了)

    //===================   寄存器的操作 ======================

    blackfin系列的寄存器定义都是在安装目录下的cdefbf5xx.h中定义的,为此,在程序的开始部分要包含相应的头文件。比如cdefbf561.h包含了所有561寄存器的定义:

    ……
    #define pFIO2_FLAG_D     ((volatile unsigned short *)FIO2_FLAG_D)
    #define pFIO2_FLAG_C     ((volatile unsigned short *)FIO2_FLAG_C)
    #define pFIO2_FLAG_S     ((volatile unsigned short *)FIO2_FLAG_S)
    #define pFIO2_FLAG_T     ((volatile unsigned short *)FIO2_FLAG_T)
    ……
    #define FIO2_FLAG_D                 0xFFC01700 /* Flag Data register (mask used to directly */
    #define FIO2_FLAG_C                 0xFFC01704 /* Flag Clear register */
    #define FIO2_FLAG_S                 0xFFC01708 /* Flag Set register */
    #define FIO2_FLAG_T                 0xFFC0170C /* Flag Toggle register (mask used to */

    这是一个地址指针,因此可以直接当作指针来操作,比如置1操作如下:

    *pFIO2_DIR    |= 0xFF00;   /*将pFIO2_DIR的高8位置为1*/

    //=================== 代码示例=======================

    以下代码中包含了GPIO的输出、输入、反转 这三个功能的设置方法,对于其它功能,可以查看硬件手册。

    #include <cdefbf561.h>   /* C POINTERS TO SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561 */
    #include <adi_types.h>   /* type defines                                                    */
    #include <ccblkfn.h>     /*  include the async() function prototype                          */
    
    void TurnOnLed(uint8_t nLed);
    void msDelay(uint32_t msec) ;
    void TurnOffAllLed(void);
    void ToggleLed(uint8_t nLed);
    void delay(int i);
    
    void main(void)
    {
        TurnOnLed(1);    //  打开LED1 (PF40)
        TurnOnLed(2);    //  打开LED2 (PF41)
        msDelay(100);
        TurnOffAllLed(); // 关闭所有LED
    
        TurnOnLed(1);    //  打开LED1 (PF40)
        TurnOnLed(2);    //  打开LED2 (PF41)
        msDelay(100);
        TurnOffAllLed(); // 关闭所有LED
    
        while(1)   //blink
        {
            ToggleLed(1);   //翻转LED
            msDelay(100);
        }
    }
    /*  GPIO as output  */
    void TurnOnLed(uint8_t nLed)
    {
            *pFIO2_DIR   |= 0xFF00;       /*set PF40~PF47 as output */
            ssync();
            *pFIO2_FLAG_S = ( 1 << (nLed+7) ); /*set the corresponding bit in FLAG_SET register as high*/
            ssync();
    
    }
    /* GPIO as input */
    void TurnOffAllLed(void)
    {
           *pFIO2_DIR    |= 0xFF00;   /*set PF40~PF47 as output */
           ssync();
           *pFIO2_FLAG_C  = 0xFF00;   /*set Flag_clear register to clear the PFx    */
           ssync();
    }
    /* Toggle GPIO */
    void ToggleLed(uint8_t nLed)
    {
        *pFIO2_DIR    |= 0xFF00;
        ssync();
        *pFIO2_FLAG_T  = (1 << (nLed+7) );  // write 1 to toggle
        ssync();
    }
    /*********************************************************************
    
    
        Function:       ezDelay
    
        Description:    Delays for approximately 1 msec when running at 600 MHz
    
    
    *********************************************************************/
    
    void msDelay(uint32_t msec)
    {
    
        volatile uint32_t i,j;
    
        // value of 0x3000000 is about 1 sec so 0xc49b is about 1msec
    
        for (j = 0; j < msec; j++) {
            for (i = 0; i < 0xc49b; i++) ;
        }
    
    }

    P.S:要想用好DSP,首先最重要的就是把寄存器的定义读懂,那Hardware  reference 必不可少,做到哪都到哪,才能有所领悟~不看手册,那是不行地。。。

  • 相关阅读:
    delphi 属性 参数 新注释
    delphi query阻塞执行 长时间执行sql的解决办法
    FDLocalSQL
    C# Webservice
    vmware的centos 6虚拟机如何共享文件夹?
    tomcat如何配置启动时自动部署webapps下的war包
    tomcat如何配置context的docBase
    windows本地启动tomcat闪退
    jfinal 字节流存储文件以及解、压缩工具类
    java try catch 异常后还会继续执行吗
  • 原文地址:https://www.cnblogs.com/BitArt/p/3171255.html
Copyright © 2020-2023  润新知