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 必不可少,做到哪都到哪,才能有所領悟~不看手冊,那是不行地。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM